Python动画制作:用tkinter模拟掷骰子

骰子是很多游戏必不可少的道具,虽然用代码模拟生成骰子的点数比较简单,但在图形化的游戏里,如果能够模拟出掷骰子的效果,必然会为游戏增色不少。正好最近问哥在琢磨的几个小游戏都需要用到掷骰子,于是单独写篇文章把掷骰子这个小功能的实现方法单独拿出来。


效果

代码实现起来也比较简单,因为问哥是用python的内置模块tkinter实现的GUI,所以代码也是使用tkinter编写。


代码实现

from tkinter import *
import random

root = Tk()
root.geometry('200x250')
root.title('掷骰子')

dice_rotate = [PhotoImage(file=r'images\donghua.gif', format=f'gif -index {i}') for i in range(13)]
dice = [PhotoImage(file=f'images/{i}.png') for i in range(1,7)]

i = 0
def rotate():
    global i
    if i<13:
        cv.itemconfig(image1,image=dice_rotate[i])
        i += 1
        root.after(50,rotate)
    else:
        cv.itemconfig(image1,image=dice[random.randint(0,5)])
        i = 0

cv = Canvas(root, bg='white')
img = PhotoImage(file=r'images\1.png')
image1 = cv.create_image(100,100,image=img)
btn = Button(root, text='掷骰子',command=rotate)
cv.create_window(100,200,window=btn)
cv.pack()
root.mainloop()

解析

实现的难点主要在于如何在tkinter上播放GIF动画。

我们都知道GIF其实是一帧一帧的静态图片组合在一起,然后按照一定的播放速度展现,就变成了人肉眼看到的动画。但是使用tkinter的PhotoImage方法导入的图片,只能是某一帧的静态图片。于是我们要使用index属性调用GIF里的每一帧图片,然后再按一定的速度重复调用程序。

首先,找到我们要播放的GIF图片,比如本例中的掷骰子的GIF,通过编辑软件,可以看到它其实是由13张静态图片组成,图片的索引从0开始,从0到12.

所以我们可以先用推导式创建一个列表,用来保存每一帧的静态图片:

dice_rotate = [PhotoImage(file=r'images\donghua.gif', format=f'gif -index {i}') for i in range(13)]

如何在tkinter上创建画布Canvas和按钮Button这里就不多说了,可以参考问哥之前的文章。

既然我们想要实现按下按钮骰子自动旋转,就必须创建一个回调函数,然后绑在Button上。在这个回调函数rotate()里,我们要按顺序把13张GIF的静态图片播放完,然后随机展示骰子1到6的图片,表示骰子停下后的点数。

我们使用计数器和root.after()函数来实现GIF的顺序播放。root.after(50, rotate)函数里的两个参数,第一个表示50毫秒,第二个表示rotate函数。这句代码的意思就是设定50毫秒后再执行一次rotate函数(不是递归)。于是我们再定义一个全局变量 i 作为计数器,从0开始。每次运行rotate的时候,检查i是不是小于13,因为我们只有0到12这13张静态图片。然后在展现图片的同时,计数器累加。rotate执行13遍,也就是把GIF所有图片展示完成后,i >=12,就不再运行after函数,而是展现一张静态的骰子图片,用来表示掷骰子的结果,最后把计数器归零。

i = 0
def rotate():
    global i # 全局变量计数器
    if i<12:
        cv.itemconfig(image1,image=dice_rotate[i]) # 循环“播放”GIF的图片
        i += 1
        root.after(50,rotate) # 50毫秒后再执行一次rotate函数
    else:
        cv.itemconfig(image1,image=dice[random.randint(0,5)]) # 掷骰子的结果
        i = 0 # 计数器归零

当然,最后需要展示一张骰子的静图,表示掷骰子的结果,1到6的骰子静图在一开始就定义另在一个图片列表里了。

dice = [PhotoImage(file=f'images/{i}.png') for i in range(1,7)]

所以程序的最后只需要使用一个随机数生成0到5的数字,代表图片在列表中的序列。

如此,便可以实现在tkinter上掷骰子的效果了。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

请叫我问哥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值