Python写个小游戏:蛇棋(下)



前言

惭愧啊,三个月没更新下篇,问哥想起了西岳奇童。。。按你胃,最近确实忙得不可开交,忙着忙着,就忘记了在CSDN上继续游戏梦想了。另一方面,好像这个游戏比较冷门,所以阅读量也比较低,而热门的游戏也有比较成熟的代码,问哥又不想去复制粘贴。不管怎么样,烂尾总是不对,对不起大家!

其实这个游戏在上篇已经介绍的差不多了,唯一的“悬念”是如何实现棋子的动作。其实细究起来,倒也不算悬念。所谓的动作,就是连续的画面展示,在之前介绍的骰子、计时器里都有介绍过。而棋子的运动也较为类似。

上篇 —— 游戏界面搭建与基本逻辑
下篇 —— 移动棋子的动画实现与算法


蛇棋

1. 玩法简介

游戏截图:
在这里插入图片描述

2. 实现棋子移动

在上篇里,我们引入了棋子的自定义“类”(Piece),这样把棋子定义为有“方法”的类的实例,就像有生命一样。

class Piece:
    def __init__(self,name,cv,co,bg):
        self.name = name
        self.cv = cv
        self.id = cv.create_image(co,image = bg)
        self.pos = 0
        
def choose_piece(img):
    global players
    P1 = Piece("Player", cv, (30,650),player_img[img])
    P2 = Piece("電腦", cv, (50,655),player_img[1-img])
    players=[P1,P2]

那么包括移动在内的棋子的方法,自然也应该定义在棋子这个类里。在我看来,棋子这个类应该包括至少两个方法:移动和判断。而前者就可以继续分为两个方法:横向跳跃和纵向跨域。判断就是指棋子移动到新的地点后,根据该地点的状况(梯子还是蛇头)来决定是否执行进一步的移动(升级或是后退)。

下面把完整的类定义内容贴出来:

class Piece:
    def __init__(self,name,cv,co,bg):
        self.name = name
        self.cv = cv
        self.id = cv.create_image(co,image = bg)
        self.pos = 0
    def jump(self,n,acc=-10,reverse=1):
        if self.pos==100:reverse = -1
        self.d = -reverse if (self.pos//10)%2 or self.pos==100 else reverse
        if 0<self.pos<100 and self.pos%10==0:
            self.d *= -1
            self.shift(self.pos+1)
            if n>1:
                self.cv.after(50,lambda :self.jump(n-1))
            else: self.judge()
        else:
            self.cv.move(self.id,5.8*self.d,acc)
            if acc <10:
                self.cv.after(50,lambda :self.jump(n,acc+2,reverse))
            else:
                self.pos = self.pos+1 if reverse>0 else self.pos-1
                if n>1:
                    self.cv.after(50,lambda :self.jump(n-1,-10,reverse))
                else: 
                    self.judge()       
    def shift(self,tar):
        self.d = -1 if (self.pos//10)%2 else 1
        dist_level = (tar-1)//10-(self.pos-1)//10
        if dist_level == 0:
            # self.jump(abs(tar-self.pos),-10,-1)
            dist_x = ((tar-1)%10-(self.pos-1)%10)*63.8
            for i in range(int(abs(dist_x))):
                self.cv.move(self.id,1,0)
                time.sleep(0.005)
                self.cv.update()
            self.pos = tar
        else:
            if dist_level%2:
                dist_x = (11-(tar-1)%10-(self.pos-1)%10-2)*63.8
            else:
                dist_x = ((tar-1)%10-(self.pos-1)%10)*63.8
            dist_y = dist_level*63
            angle = dist_x/abs(dist_y)
            d=1 if dist_y<0 else -1
            for i in range(abs(dist_y)):
                self.cv.move(self.id,angle*self.d,d)
                time.sleep(0.005)
                self.cv.update()
            self.pos = tar
    def judge(self):
        if self.pos in LADDER.keys():
            info_update(f'{self.name} 运气真好,遇到梯子!')
            info_update(f'{self.name} 前进到 {LADDER[self.pos]} ^O^')
            tar = LADDER[self.pos]
            self.shift(tar)
            if self.pos==100: 
                win_next(self.name)
                return
        elif self.pos in SNAKE.keys():
            info_update(f'{self.name} 遭遇蛇吻!')
            info_update(f'{self.name} 退回到 {SNAKE[self.pos]} T_T')
            tar = SNAKE[self.pos]
            self.shift(tar)
        elif self.pos==100:
            win_next(self.name)
            return
        else:
            info_update(f"{self.name} 移动到 {self.pos}")
        players.reverse()
        if players[0].name=='電腦':
            info_update("電腦 开始掷骰子")
            roll(0)
        else:
            info_update("等待玩家掷骰子")
            btn['state']=NORMAL

而同样的,我们希望棋子在转动骰子后,根据骰子的点数自动开始移动,就需要把骰子运动的函数与棋子的移动方法链接起来:

def move(step):
    info_update(f"{players[0].name} 掷出了 {step} 点")
    players[0].jump(step)

def roll(i):
    btn['state']=DISABLED
    if i<13:
        cv.itemconfig(image1,image=dice_rotate[i])
        root.after(50,lambda :roll(i+1))
    else:
        res = random.randint(0,5)
        cv.itemconfig(image1,image=dice[res])
        move(res+1)

这样一样,我们只要点击“掷骰子”的按钮,转出数字,棋子就会自动开始移动了。

匆忙贴出了代码,大家如果感兴趣,可以自行尝试,下次问哥不再轻易尝试这么冷门的游戏了。😄

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

请叫我问哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值