找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 113|回复: 0

[教程] 五子棋迷你游戏代码讲解/教程【LLFs-OSRMGP内容扩展-2】

[复制链接]
发表于 2024-11-25 11:01:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 烈林凤 于 2024-11-26 14:17 编辑

## 该项目来源于LLFs-OSRMGP(https://github.com/llfseik/LLFs-OSRMGP),遵循MIT协议。
## 严禁进行售卖!若需嵌入付费项目请与我联系!

这是本仓库的第二次内容扩展,感谢各位的支持!
仓库内的所有教程都会尽量保证详细准确,请尽量将代码、注释和教程放在一起使用!
本篇复用了好多上一篇扫雷游戏的代码,因此只详细讲解其中的不同之处,希望各位谅解!
renpy程序糕手们可能会觉得很多地方有些繁琐,那可以只看代码和注释的部分进行学习,谢谢配合!
若教程中有什么错误的地方,欢迎留言指出!
各种文档、仓库或其他网站的链接我都放在文字中了,点击蓝色文字即可跳转。
感谢@ZYKsslm 提供的圆形绘制代码!

先展示完整代码——
[RenPy] 纯文本查看 复制代码
## 该项目来源于LLFs-OSRMGP([url=https://github.com/llfseik/LLFs-OSRMGP]https://github.com/llfseik/LLFs-OSRMGP[/url]),遵循MIT协议。
## 严禁售卖该项目代码!你可以随意将其用修改并于任何非商业用途,但请注明出处!

label gobang_label:
    $ quick_menu = False
    call screen gobang_screen()

## 绘制无棋子时的格子
image gobang_normal_box:
    xysize(int(box_xysize),int(box_xysize))
    "#000000"

init 1 python:
    import random

    ## 格子大小
    box_xysize = 50
    ## 行数、列数、所有格子的坐标、棋盘的坐标、白棋的坐标、黑棋的坐标
    box_rows = 10
    box_cols = 10
    all_box_list = []
    gobang_whilte_box_list = []
    gobang_black_box_list = []
    ## 先手
    first_turn = "white"
    ## 输赢、游玩次数、胜场、分数
    win_or_lose = ""
    count = 0
    win_count = 0
    score = 0
    game_over = None

    ## 绘制圆形棋子
    class Chess(renpy.Displayable):
        def __init__(self,x,y,color,radius,**kwargs):
            super(Chess, self).__init__(**kwargs)
            self.x = x
            self.y = y
            self.color = color
            self.radius = radius

        ## 绘制圆形棋子
        def render(self,width,height,st,at):
            render = renpy.Render(width,height)
            canvas = render.canvas()
            canvas.circle(self.color,(self.x,self.y),self.radius)
            return render
    
    ## 绘制棋子
    renpy.image("gobang_white", Fixed(Chess(box_xysize/2,box_xysize/2,"#FFFFFF",box_xysize/2-1), xysize=(box_xysize,box_xysize)))
    renpy.image("gobang_black", Fixed(Chess(box_xysize/2,box_xysize/2,"#000000",box_xysize/2-1), xysize=(box_xysize,box_xysize)))

    ## 初始化游戏
    def gobang_init_game():
        global box_rows, box_cols, all_box_list, gobang_tag_list, gobang_gobang_whilte_box_list, first_turn, win_or_lose, count, win_count, score, game_over

        ## 清空棋盘
        gobang_whilte_box_list.clear()
        gobang_black_box_list.clear()
        all_box_list.clear()

        ## 重置游戏状态
        box_rows = 15
        box_cols = 15

        
        ## 生成所有格子的坐标
        all_box_list = []
        for i in range(0,box_rows):
            for j in range(0,box_cols):
                all_box_list.append((i,j))
        
        ## 开始游戏
        game_over = False
        win_or_lose = ""
    
    ## 落子并判断胜负(游戏的核心算法)
    def gobang_falling(chess_color=None,box_pos=None):
        global win_or_lose,game_over
        x_num = 0
        y_num = 0
        x_left_num = 0
        x_right_num = 0
        box_x = box_pos[0]
        box_y = box_pos[1]
        ## 如果棋子是白色则调用白棋列表,否则调用黑棋列表。
        if chess_color == "white":
            list_color = gobang_whilte_box_list
        elif chess_color == "black":
            list_color = gobang_black_box_list
            
        list_color.append(box_pos)
        ## 这一部分还有优化空间,但目前就这样吧,优化算法什么的就交给后人)
        ## 搜索当前棋子上下左右以及四个斜向方向的4格棋子状态,如果是对应颜色的棋子,则将变量+1
        for i in range(1,5):
            if (box_x+i,box_y) in list_color:
                x_num += 1
            if (box_x-i,box_y) in list_color:
                x_num += 1
            if (box_x,box_y+i) in list_color:
                y_num += 1
            if (box_x,box_y-i) in list_color:
                y_num += 1
            if (box_x+i,box_y+i) in list_color:
                x_left_num += 1
            if (box_x-i,box_y-i) in list_color:
                x_left_num += 1
            if (box_x+i,box_y-i) in list_color:
                x_right_num += 1
            if (box_x-i,box_y+i) in list_color:
                x_right_num += 1
        ## 如果四个方向的棋子有一条加起来等于5个,则获胜(排除自身的这颗棋子,避免重复判断)
        if x_num >= 4 or y_num >= 4 or x_left_num >= 4 or x_right_num >= 4:
            win_or_lose = chess_color
            game_over = True

screen gobang_screen():

    ## 初始化游戏
    on "show" action [Function(gobang_init_game,),SetVariable("game_over",False)]

    ## 当前下的棋子颜色
    default now_turn = first_turn

    ## 绘制棋盘
    fixed:
        xycenter (0.5,0.5)
        ## 棋盘底图
        add "#b6a4ff" xysize (int(box_cols*box_xysize*1.1+box_xysize*0.1),int(box_rows*box_xysize*1.1+box_xysize*0.1)) xycenter (0.5,0.5)

        if game_over == None or game_over == False:
            grid box_cols box_rows:
                xycenter (0.5,0.5)
                xsize int(box_rows*box_xysize*1.1)
                ysize int(box_cols*box_xysize*1.1)
                spacing int(box_xysize*0.1)

                for i in all_box_list:
                    ## 判断格子的状态
                    if i in gobang_whilte_box_list:
                        add "gobang_white" xysize(int(box_xysize),int(box_xysize))
                    elif i in gobang_black_box_list:
                        add "gobang_black" xysize(int(box_xysize),int(box_xysize))
                    else:
                        ## 因为没有hover效果,所以说不使用imagebutton以节省性能
                        button:
                            image "gobang_normal_box":
                                xycenter (0.5,0.5)
                                xysize(int(box_xysize),int(box_xysize))
                            xysize(int(box_xysize),int(box_xysize))
                            ## 调用落子函数并将当前棋子的颜色改变
                            action [Function(gobang_falling,now_turn,i),
                                    SetScreenVariable("now_turn","black" if now_turn == "white" else "white")]
        else:
            fixed:
                xycenter (0.5,0.5)
                xsize int(box_rows*box_xysize*1.1)
                ysize int(box_cols*box_xysize*1.1)
                add "#000000"
                vbox:
                    xycenter (0.5,0.5)
                    text "胜者:[win_or_lose]" xycenter (0.5,0.5) size box_xysize*0.6
                    textbutton "再来一局":
                        xycenter (0.5,0.5)
                        text_size box_xysize*0.6
                        action  [Function(gobang_init_game),SetVariable("game_over",False)]


这一段代码一共可以分为2大部分:
  • init python:最核心的算法部分
  • screen gobang_screen_screen:玩家游玩所看到和需要交互的界面


剩下的label不是必须使用的,因此各位可以根据需求进行替换。
我会更多地讲解init python部分,因为这是游戏玩法的核心,学会了最核心的算法,无论做什么样的格子类游戏都能够手到擒来!
而且screen的部分,通过代码注释,已经基本明了,因此不会有过多的解释,只需要根据自己的需要去增减配置即可。
接下来我们按顺序逐个分析代码——

init python
可以在这个地方调用调用python中的random库,便于之后随机两种棋子的先后手,但在这里并没有使用,因此默认是白棋先手。

class Chess(renpy.Displayable)与renpy.image:
为了绘制圆形棋子,因此我使用了zyk提供的圆形绘制代码来尝试进行绘制,这部分使用了cdd(创作者定义的可视组件),其本质上是使用了pygame渲染组件的方法,但因为这部分是renpy内置的,并没有调用pygame库,因此不算使用了pygame库(大概?),这一部分我也没怎么搞懂,就不写详细说明了,各位可以前往自行研究。

def gobang_init_game:
游戏初始运行必要的函数,会初始化所有参数(这一步是必须的,轻则游戏重开时数据未清除,重则直接报错),因为没有留有改变棋盘大小的接口,所以没有进行数据检测,各位可以自行添加。
使用global将函数内的部分变量转为全局变量,否则函数内对变量的更改无法改变全局变量
通过两次for遍历,往all_box_list列表中中添加元组,两次遍历分别是每排的格子数和每列的格子数,
分别对应着“x”和“y”,最后加入的元组形式为(x,y)(例如[(1,1)]),遍历出的元组数量总量即为格子数量总量,之后只需将all_box_list遍历进grid即可。

def gobang_falling:
包含了最重要的游戏算法,是游戏主要玩法的核心函数,每次点击格子后都会调用这个函数。
该函数有两个入参,分别为所下棋子颜色和本格格子的坐标。
设定6个局部变量,分别为:左斜线方向相同棋子的数量、右斜线方向相同棋子的数量、竖排方向相同棋子的数量、横排方向相同棋子的数量、当前棋子x坐标、当前棋子y坐标。
首先,将自身坐标加进对应颜色的坐标列表中,
然后,遍历当前棋子的周围8个方向的坐标,并判断是否在对应颜色的坐标列表中,如果是则将变量+1,
最后,如果四个方向的棋子有一条加起来等于5个(排除自身的这颗棋子,避免重复判断),则获胜。

好了,以上将init python,也就是最核心的游戏算法部分讲完了,
接下来就是负责向玩家展示和交互的screen部分了——



on "show"
当界面被展示时,立刻使用Function行为SetVariable行为,调用init_game并将game_over改为True表示游戏开始。

default:
使用界面局部变量,判断当前下的是哪种颜色的棋子,并默认是先前设置的先手棋子(白棋)

grid
这是游戏中最主要的界面,强烈建议不要随意更改。
首先,当game_over不为True时,将会展示这个,grid将以box_cols和box_rows来规划网格。

然后,使用for遍历all_box_list将所有方格放入其中,将已经打开的方格变为图片,减少性能损耗。

接着,如果不是已经打开的方格,则作为按钮供玩家点击,
这次将上一篇的imagebutton改为了button,因为imagebutton默认是存在hover的,而取消hover能节省好多性能,保证游戏游玩时不会因此而卡顿

最后,调用gobang_falling函数,导入当前棋子的颜色和坐标为参数,
并通过判断当前下棋的对象,如果上一个是白棋则改为黑棋,反之亦然。

至此,关于五子棋迷你游戏代码讲解/教程都已经全部讲完了,希望这篇教程能更好地让各位配置和学习!
之后我会发布更多renpy相关的开源迷你小游戏教程,并添加进LLFs-OSRMGP中,欢迎各位关注仓库和加星!

各位下期再见!

QQ20241125-110004.png

评分

参与人数 1活力 +300 干货 +3 收起 理由
被诅咒的章鱼 + 300 + 3 感谢分享!

查看全部评分

本帖被以下淘专辑推荐:

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|RenPy中文空间 ( 苏ICP备17067825号|苏公网安备 32092302000068号 )

GMT+8, 2024-12-4 01:49 , Processed in 0.118978 second(s), 34 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表