程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python動畫制作:用tkinter模擬擲骰子

編輯:Python

骰子是很多游戲必不可少的道具,雖然用代碼模擬生成骰子的點數比較簡單,但在圖形化的游戲裡,如果能夠模擬出擲骰子的效果,必然會為游戲增色不少。正好最近問哥在琢磨的幾個小游戲都需要用到擲骰子,於是單獨寫篇文章把擲骰子這個小功能的實現方法單獨拿出來。


效果

代碼實現起來也比較簡單,因為問哥是用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上擲骰子的效果了。


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved