1. 程式人生 > 實用技巧 >初識python:tkinter 實現 彈球小遊戲

初識python:tkinter 實現 彈球小遊戲

通過tkinter採用非面相物件式實現彈球小遊戲

#!/user/bin env python
# author:Simple-Sir
# time:2020/8/3 17:12
import tkinter,time,random

x = 1
y = 1
score = 0  # 分數
level = 1  # 關卡

# 建立顏色列表
color_li = ['#feeeed','#f391a9','#fab27b','#454926','#181d4b','#a3cf62','#45b97c','#008792','#2585a6']

# 建立視窗
tk = tkinter.Tk()  # 宣告一個TK,初始化一個“視窗”(畫一個視窗)
tk.title('彈球遊戲') # 視窗名稱 tk.resizable(width=False,height=False) # 視窗是否可變(長、寬),也可用0,1表示 tk.wm_attributes('-topmost',1) # 視窗永遠在前 # 建立畫布 canvas = tkinter.Canvas(tk,width=600,height=500,bd=0) # 建立一個“畫布” # 建立畫布元件 filename = tkinter.PhotoImage(file="bg.png") # 獲取一張圖片 canvas.create_image(300, 250,image=filename) #
將圖片新增到畫布,作為背景 id_ball = canvas.create_oval(10, 10, 30, 30, fill=random.choice(color_li),width=0) # 定義一個球 id_paddle = canvas.create_rectangle(0,400,150,420,fill=random.choice(color_li),width=0) # 定義木板 canvas.move(id_paddle,225,0) canvas.create_text(400, 20, text='關卡:',fill='white',font=('宋體', '20')) canvas.create_text(
500, 20, text='得分:',fill='white',font=('宋體', '20')) id_level = canvas.create_text(450, 20, text=1,fill='white',font=('宋體', '20')) id_score = canvas.create_text(550, 20, text=0,fill='white',font=('宋體', '20')) id_start_game = canvas.create_text(300,200,text='Start Game.',font=('宋體', '30'),fill=random.choice(color_li)) canvas.pack() # 將畫布新增到視窗中 tk.update() # 重新整理視窗 wh = canvas.winfo_height() # 獲取視窗高度(update重新整理之後才能獲取) ww = canvas.winfo_width() # 獲取視窗寬度(update重新整理之後才能獲取) def turn_left(event): canvas.move(id_paddle, -10, 0) def turn_right(event): canvas.move(id_paddle, 10, 0) def start_game(event): canvas.move(id_start_game,0,10) canvas.bind_all('<KeyPress-Left>', turn_left) canvas.bind_all('<KeyPress-Right>', turn_right) canvas.bind_all('<Button-1>', start_game) # 保持起始介面 while 1: tk.update() # 重新整理視窗 p_start_game = canvas.coords(id_start_game) print(p_start_game) if p_start_game[1] == 210: canvas.delete(id_start_game) break # 讓球跑起來 while 1: tk.update() # 重新整理視窗 time.sleep(0.01/level) # 通過level控制速度(也考慮過用球的顏色控制速度) p_ball = canvas.coords(id_ball) # 獲取球當前位置座標 p_paddle = canvas.coords(id_paddle) # 獲取木板的座標 print('當前座標:',p_ball) # 列印當前座標 if p_ball[0] <= 0: # 當球落到右邊框時:左上角x座標判斷 x = 1 elif p_ball[2] >= ww: # 當球落到右邊框時,右下角x座標判斷 x = -1 if p_ball[1] <= 0: # 當球落到上邊框時,左上角y座標判斷 y = 1 elif p_ball[3] >= wh: # 當球落到下邊框時,右下角y座標判斷 y = -1 print(p_ball[2],p_paddle[0],p_paddle[2],p_ball[3]) if p_ball[2]>=p_paddle[0] and p_ball[2]<=p_paddle[2] and p_ball[3] == p_paddle[1]: # 球與模板接觸:球的右下角x座標在木板右上角x座標內,且球的右下角x座標在木板左下角x座標內,球的右下角y座標等於木板的左上角y座標 y = -1 # 讓球向上移動 score += 10 # 得分加10分 canvas.itemconfig(id_ball, fill=random.choice(color_li)) # 修改球的顏色,隨機顏色 canvas.itemconfig(id_paddle, fill=random.choice(color_li)) # 修改木板的顏色,隨機顏色 canvas.itemconfig(id_score, text=score) # 修改分數 if score > 0 and score % 50 == 0: # 每50分升一級 level += 1 # 升級 canvas.itemconfig(id_level, text=level) # 修改等級 canvas.move(id_ball, x, y) # 移動 if p_ball[3] == wh: # 當球與下邊框接觸時,遊戲失敗。 canvas.create_text(300, 250, text='Game Over !', font=('宋體', '30'), fill='red') # 新增遊戲結束介面 break # 遊戲結束,繼續保持介面 tk.mainloop()
彈球小遊戲

最終執行效果:

知識點

1、匯入模組

import tkinter

2、生明一個tkinter例項(建立一個“視窗”)

tk = tkinter.Tk() # 宣告一個tkinter,初始化一個“視窗”(畫一個視窗)

3、設定視窗屬性

tk.title('彈球遊戲') # 視窗名稱
tk.resizable(width=False,height=False) # 視窗是否可變(長、寬),也可用0,1表示
tk.wm_attributes('-topmost',1) # 視窗永遠在前
wm_attributes可選屬性欄位:

-topmost 是否是一個永遠最前的視窗
-alpha 視窗的透明度
-fullscreen 視窗是否滿屏顯示
-disabled 視窗是否是一個不可用的狀態(不能有任何操作)

4、元件例項

首先弄清楚座標概念:

以畫布的左上角為原點(0,0)
以畫一個圓為例,需要通過“矩形”的左上角、右下角兩個座標確定這個“矩形”的位置、大小,然後,在矩形中畫這個圓

tkinter.Canvas 建立畫布

#!/user/bin env python
# author:Simple-Sir
# time:2020/8/3 17:12
import tkinter

# 建立視窗
tk = tkinter.Tk()  # 宣告一個TK,初始化一個“視窗”(畫一個視窗)
tk.title('彈球遊戲')  # 視窗名稱
tk.resizable(width=False,height=False)  # 視窗是否可變(長、寬),也可用0,1表示
tk.wm_attributes('-topmost',1)  # 視窗永遠在前

canvas = tkinter.Canvas(tk,width=300,height=200,bd=0)  # 建立一個“畫布”
# width 寬
# height 高
# bd 邊框寬度(畫素)
# bg 背景顏色
# highlightthickness 顏色高亮

canvas.pack()  # 將畫布新增到視窗中
tk.update()  # 重新整理視窗


# 進入訊息迴圈
tk.mainloop()  # 所有GUI程式都必須有一個主迴圈
建立“畫布”

執行結果:

畫布屬性:

move 移動
delete 刪除
winfo_height 獲取視窗高度(update重新整理之後才能獲取)
winfo_width() 獲取視窗寬度(update重新整理之後才能獲取)
coords 獲取目標當前座標
itemconfig 修改元件屬性

畫布元件:

畫布元件屬性:

fill 填充顏色,預設不填充
stipple 點陣圖平鋪填充
outline 邊框顏色
width 邊框寬度,預設1
dash 邊框使用虛線。單獨整數:虛線線段長度 (n1,n2,n3):線段的長度n1,間隔長度n2,虛線長度n3
arrowshape 指定箭頭形狀。該選項是一個形如 "20 20 10" 的字串,字串中的三個整數依次指定填充長度、箭頭長度、箭頭寬度。
joinstyle 直線連線點的風格: miter、round、bevel
state 指定該畫布物件的狀態 NORMAL(正常,預設),DISABLED(不可用,不響應事件)和 HIDDEN(隱藏)

canvas.create_arc建立扇形:

#!/user/bin env python
# author:Simple-Sir
# time:2020/8/3 17:12
import tkinter

# 建立視窗
tk = tkinter.Tk()  # 宣告一個TK,初始化一個“視窗”(畫一個視窗)
tk.title('彈球遊戲')  # 視窗名稱
tk.resizable(width=False,height=False)  # 視窗是否可變(長、寬),也可用0,1表示
tk.wm_attributes('-topmost',1)  # 視窗永遠在前

# 建立畫布
canvas = tkinter.Canvas(tk,width=300,height=200,bd=0)  # 建立一個“畫布”
# width 寬
# height 高
# bd 邊框寬度(畫素)
# bg 背景顏色
# highlightthickness 顏色高亮


canvas.create_arc(0,0,100,100,start=0,extent=60,fill='red') # 指定座標(左上、右下),開始度數,要畫的度數,填充顏色
# style  PIESLICE - 扇形、CHORD - 弓形、ARC - 只畫一個弧)
# start  扇形的起始角度,以3點鐘位置為0度,逆時針方向增加度數。
# extent 扇形要繪製的度數

canvas.pack()  # 將畫布新增到視窗中
tk.update()  # 重新整理視窗


# 進入訊息迴圈
tk.mainloop()  # 所有GUI程式都必須有一個主迴圈
建立扇形

執行結果:

canvas.create_oval 建立圓:

#!/user/bin env python
# author:Simple-Sir
# time:2020/8/3 17:12
import tkinter

# 建立視窗
tk = tkinter.Tk()  # 宣告一個TK,初始化一個“視窗”(畫一個視窗)
tk.title('彈球遊戲')  # 視窗名稱
tk.resizable(width=False,height=False)  # 視窗是否可變(長、寬),也可用0,1表示
tk.wm_attributes('-topmost',1)  # 視窗永遠在前

# 建立畫布
canvas = tkinter.Canvas(tk,width=300,height=200,bd=0)  # 建立一個“畫布”
# width 寬
# height 高
# bd 邊框寬度(畫素)
# bg 背景顏色
# highlightthickness 顏色高亮

# 建立圓
canvas.create_oval(10,10,100,100,fill='red')

canvas.pack()  # 將畫布新增到視窗中
tk.update()  # 重新整理視窗


# 進入訊息迴圈
tk.mainloop()  # 所有GUI程式都必須有一個主迴圈
建立圓

執行結果:

canvascreate_image建立影象

#!/user/bin env python
# author:Simple-Sir
# time:2020/8/3 17:12
import tkinter

# 建立視窗
tk = tkinter.Tk()  # 宣告一個TK,初始化一個“視窗”(畫一個視窗)
tk.title('彈球遊戲')  # 視窗名稱
tk.resizable(width=False,height=False)  # 視窗是否可變(長、寬),也可用0,1表示
tk.wm_attributes('-topmost',1)  # 視窗永遠在前

# 建立畫布
canvas = tkinter.Canvas(tk,width=300,height=200,bd=0)  # 建立一個“畫布”
# width 寬
# height 高
# bd 邊框寬度(畫素)
# bg 背景顏色
# highlightthickness 顏色高亮

# 建立影象
filename = tkinter.PhotoImage(file="cat.png")
canvas.create_image(10, 20, anchor='nw', image=filename)  # 西距離邊框10,北距離邊框20

canvas.pack()  # 將畫布新增到視窗中
tk.update()  # 重新整理視窗


# 進入訊息迴圈
tk.mainloop()  # 所有GUI程式都必須有一個主迴圈
建立影象

執行結果:

canvas.create_line建立線條

#!/user/bin env python
# author:Simple-Sir
# time:2020/8/3 17:12
import tkinter

# 建立視窗
tk = tkinter.Tk()  # 宣告一個TK,初始化一個“視窗”(畫一個視窗)
tk.title('彈球遊戲')  # 視窗名稱
tk.resizable(width=False,height=False)  # 視窗是否可變(長、寬),也可用0,1表示
tk.wm_attributes('-topmost',1)  # 視窗永遠在前

# 建立畫布
canvas = tkinter.Canvas(tk,width=300,height=200,bd=0)  # 建立一個“畫布”
# width 寬
# height 高
# bd 邊框寬度(畫素)
# bg 背景顏色
# highlightthickness 顏色高亮

# line 線條
canvas.create_line(0,0,100,100,50,60,200,300,arrow='last',joinstyle='bevel')  # 多個座標會連續畫
# arrow 兩端是否有箭頭(none:兩端無箭頭、first:開始端有箭頭、last:結束端有箭頭、both:兩端都有箭頭。

canvas.pack()  # 將畫布新增到視窗中
tk.update()  # 重新整理視窗


# 進入訊息迴圈
tk.mainloop()  # 所有GUI程式都必須有一個主迴圈
建立線條

執行結果:

#!/user/bin env python
# author:Simple-Sir
# time:2020/8/3 17:12
import tkinter

# 建立視窗
tk = tkinter.Tk()  # 宣告一個TK,初始化一個“視窗”(畫一個視窗)
tk.title('彈球遊戲')  # 視窗名稱
tk.resizable(width=False,height=False)  # 視窗是否可變(長、寬),也可用0,1表示
tk.wm_attributes('-topmost',1)  # 視窗永遠在前

# 建立畫布
canvas = tkinter.Canvas(tk,width=300,height=200,bd=0)  # 建立一個“畫布”
# width 寬
# height 高
# bd 邊框寬度(畫素)
# bg 背景顏色
# highlightthickness 顏色高亮

# rectangle 矩形
canvas.create_rectangle(0,10,100,150,fill='blue',outline='red',stipple='error',width=10,dash=(10,50,100))
# stipple 點陣圖平鋪填充
# outline 邊框顏色
# width 邊框寬度,預設1
# dash 邊框使用虛線。單獨整數:虛線線段長度 (n1,n2,n3):虛線線段長度n1,間隔長度n2,虛線長度n3

canvas.pack()  # 將畫布新增到視窗中
tk.update()  # 重新整理視窗


# 進入訊息迴圈
tk.mainloop()  # 所有GUI程式都必須有一個主迴圈
建立矩形

執行結果:

建立多邊形:

#!/user/bin env python
# author:Simple-Sir
# time:2020/8/3 17:12
import tkinter

# 建立視窗
tk = tkinter.Tk()  # 宣告一個TK,初始化一個“視窗”(畫一個視窗)
tk.title('彈球遊戲')  # 視窗名稱
tk.resizable(width=False,height=False)  # 視窗是否可變(長、寬),也可用0,1表示
tk.wm_attributes('-topmost',1)  # 視窗永遠在前

# 建立畫布
canvas = tkinter.Canvas(tk,width=300,height=200,bd=0)  # 建立一個“畫布”
# width 寬
# height 高
# bd 邊框寬度(畫素)
# bg 背景顏色
# highlightthickness 顏色高亮

# polygon 多邊形
canvas.create_polygon(0,0,100,200,100,250,50,300,fill='red',outline='red',stipple='error',width=10,dash=(10,50,100))

canvas.pack()  # 將畫布新增到視窗中
tk.update()  # 重新整理視窗


# 進入訊息迴圈
tk.mainloop()  # 所有GUI程式都必須有一個主迴圈
建立多邊形

執行結果:

建立文字:

#!/user/bin env python
# author:Simple-Sir
# time:2020/8/3 17:12
import tkinter

# 建立視窗
tk = tkinter.Tk()  # 宣告一個TK,初始化一個“視窗”(畫一個視窗)
tk.title('彈球遊戲')  # 視窗名稱
tk.resizable(width=False,height=False)  # 視窗是否可變(長、寬),也可用0,1表示
tk.wm_attributes('-topmost',1)  # 視窗永遠在前

# 建立畫布
canvas = tkinter.Canvas(tk,width=300,height=200,bd=0)  # 建立一個“畫布”
# width 寬
# height 高
# bd 邊框寬度(畫素)
# bg 背景顏色
# highlightthickness 顏色高亮


canvas.create_text(100,100,text='使用text繪製文字',font='宋體',fill='red',anchor='n',justify='left',)
# justify 文字的對齊方式:center、left、right

canvas.pack()  # 將畫布新增到視窗中
tk.update()  # 重新整理視窗


# 進入訊息迴圈
tk.mainloop()  # 所有GUI程式都必須有一個主迴圈
建立文字

執行結果:

事件

三種繫結方式:
canvas.bind() # 繫結到某一個元件上
canvas.bind_all() # 繫結到所有元件上
canvas.bind_class() # 繫結到某一類元件上

鍵盤事件:
<Left>
<Right>
<Up>
<Down>
<BackSpace>
<Delete>
<Tab>
<Return>
<Shift_L>
<Shift_R>
<Control_L>
<Control_R>
<Alt_L>
<Alt_R>
<Home>
<Key> 或者 <KeyPress> 任意鍵盤按鍵

滑鼠事件
<Button-1> 滑鼠點選(1-左鍵,2-中鍵,3-右鍵)
<Double-Button-1> 滑鼠雙擊(1-左鍵,2-中鍵,3-右鍵)
<B1-Motion> 滑鼠拖動(1-左鍵,2-中鍵,3-右鍵)
<ButtonRelease-1> 滑鼠按下之後釋放(1-左鍵,2-中鍵,3-右鍵)
<Enter> 滑鼠進入控制元件範圍
<Leave> 滑鼠離開控制元件範圍