python基于tkinter制作图形界面的2048游戏
作者:projectgurukul 时间:2022-02-03 03:40:47
目录
2048游戏输出
项目先决条件
创建main.py
解释:
1.Board:
2.game:
总结
2048游戏输出
项目先决条件
前提条件如下:
1. Python
2. Tkinter
创建main.py
代码:
from tkinter import *
from tkinter import messagebox
import random
class Board:
bg_color={
'2': '#eee4da',
'4': '#ede0c8',
'8': '#edc850',
'16': '#edc53f',
'32': '#f67c5f',
'64': '#f65e3b',
'128': '#edcf72',
'256': '#edcc61',
'512': '#f2b179',
'1024': '#f59563',
'2048': '#edc22e',
}
color={
'2': '#776e65',
'4': '#f9f6f2',
'8': '#f9f6f2',
'16': '#f9f6f2',
'32': '#f9f6f2',
'64': '#f9f6f2',
'128': '#f9f6f2',
'256': '#f9f6f2',
'512': '#776e65',
'1024': '#f9f6f2',
'2048': '#f9f6f2',
}
def __init__(self):
self.window=Tk()
self.window.title('ProjectGurukul 2048 Game')
self.gameArea=Frame(self.window,bg= 'azure3')
self.board=[]
self.gridCell=[[0]*4 for i in range(4)]
self.compress=False
self.merge=False
self.moved=False
self.score=0
for i in range(4):
rows=[]
for j in range(4):
l=Label(self.gameArea,text='',bg='azure4',
font=('arial',22,'bold'),width=4,height=2)
l.grid(row=i,column=j,padx=7,pady=7)
rows.append(l)
self.board.append(rows)
self.gameArea.grid()
def reverse(self):
for ind in range(4):
i=0
j=3
while(i<j):
self.gridCell[ind][i],self.gridCell[ind][j]=self.gridCell[ind][j],self.gridCell[ind][i]
i+=1
j-=1
def transpose(self):
self.gridCell=[list(t)for t in zip(*self.gridCell)]
def compressGrid(self):
self.compress=False
temp=[[0] *4 for i in range(4)]
for i in range(4):
cnt=0
for j in range(4):
if self.gridCell[i][j]!=0:
temp[i][cnt]=self.gridCell[i][j]
if cnt!=j:
self.compress=True
cnt+=1
self.gridCell=temp
def mergeGrid(self):
self.merge=False
for i in range(4):
for j in range(4 - 1):
if self.gridCell[i][j] == self.gridCell[i][j + 1] and self.gridCell[i][j] != 0:
self.gridCell[i][j] *= 2
self.gridCell[i][j + 1] = 0
self.score += self.gridCell[i][j]
self.merge = True
def random_cell(self):
cells=[]
for i in range(4):
for j in range(4):
if self.gridCell[i][j] == 0:
cells.append((i, j))
curr=random.choice(cells)
i=curr[0]
j=curr[1]
self.gridCell[i][j]=2
def can_merge(self):
for i in range(4):
for j in range(3):
if self.gridCell[i][j] == self.gridCell[i][j+1]:
return True
for i in range(3):
for j in range(4):
if self.gridCell[i+1][j] == self.gridCell[i][j]:
return True
return False
def paintGrid(self):
for i in range(4):
for j in range(4):
if self.gridCell[i][j]==0:
self.board[i][j].config(text='',bg='azure4')
else:
self.board[i][j].config(text=str(self.gridCell[i][j]),
bg=self.bg_color.get(str(self.gridCell[i][j])),
fg=self.color.get(str(self.gridCell[i][j])))
class Game:
def __init__(self,gamepanel):
self.gamepanel=gamepanel
self.end=False
self.won=False
def start(self):
self.gamepanel.random_cell()
self.gamepanel.random_cell()
self.gamepanel.paintGrid()
self.gamepanel.window.bind('<Key>', self.link_keys)
self.gamepanel.window.mainloop()
def link_keys(self,event):
if self.end or self.won:
return
self.gamepanel.compress = False
self.gamepanel.merge = False
self.gamepanel.moved = False
presed_key=event.keysym
if presed_key=='Up':
self.gamepanel.transpose()
self.gamepanel.compressGrid()
self.gamepanel.mergeGrid()
self.gamepanel.moved = self.gamepanel.compress or self.gamepanel.merge
self.gamepanel.compressGrid()
self.gamepanel.transpose()
elif presed_key=='Down':
self.gamepanel.transpose()
self.gamepanel.reverse()
self.gamepanel.compressGrid()
self.gamepanel.mergeGrid()
self.gamepanel.moved = self.gamepanel.compress or self.gamepanel.merge
self.gamepanel.compressGrid()
self.gamepanel.reverse()
self.gamepanel.transpose()
elif presed_key=='Left':
self.gamepanel.compressGrid()
self.gamepanel.mergeGrid()
self.gamepanel.moved = self.gamepanel.compress or self.gamepanel.merge
self.gamepanel.compressGrid()
elif presed_key=='Right':
self.gamepanel.reverse()
self.gamepanel.compressGrid()
self.gamepanel.mergeGrid()
self.gamepanel.moved = self.gamepanel.compress or self.gamepanel.merge
self.gamepanel.compressGrid()
self.gamepanel.reverse()
else:
pass
self.gamepanel.paintGrid()
print(self.gamepanel.score)
flag=0
for i in range(4):
for j in range(4):
if(self.gamepanel.gridCell[i][j]==2048):
flag=1
break
if(flag==1): #found 2048
self.won=True
messagebox.showinfo('2048', message='You Wonnn!!')
print("won")
return
for i in range(4):
for j in range(4):
if self.gamepanel.gridCell[i][j]==0:
flag=1
break
if not (flag or self.gamepanel.can_merge()):
self.end=True
messagebox.showinfo('2048','Game Over!!!')
print("Over")
if self.gamepanel.moved:
self.gamepanel.random_cell()
self.gamepanel.paintGrid()
gamepanel =Board()
game2048 = Game( gamepanel)
game2048.start()
解释:
我们在代码中定义了两个类:
1.Board:
变量:
Bg_color:这是一个字典,用于存储每个单元格的背景色。
Color:这是一个字典,用于存储每个单元的前景色。
Window:它是tkinter的主要窗口。
gameArea:这是一个tkinter框架小部件。
gridCell:这是一个4×4整数矩阵,存储所有单元格的实际整数值。
Board:这是tkinter标签小部件的4×4网格,它在tkinter窗口上显示单元格的值。它还用于根据其gridCell值配置该单元格的背景和前景。
Score:它存储玩家的当前分数。
其余只是标志变量。
功能:
__init __(self):这是构造函数。它使用适当的默认值初始化所有变量,例如gridCell的默认值为“ 0”,移动,合并的默认值为False,等等。
Reverse:反转gridCell矩阵。
Transpose:它使用zip函数并进行gridCell矩阵的转置。
CompressGrid:它将所有非空单元格向左移动,因此可以轻松完成合并。
mergeGrid:如果两个相邻单元格具有相同的gridCell值,则将它们的gridCell值相加。
Random_cell:首先将所有空单元格存储在列表中,然后从创建的列表中选择一个随机单元格并使其gridCell值2
Can_merge:返回一个布尔值,表示我们可以合并任意两个单元格。当且仅当两个单元格具有相同的gridCell值时,我们才可以合并它们。
paintGrid:将前景和背景色分配给4×4网格中与其gridCell值相对应的每个单元。
2.game:
此类没有很多变量,只有一些布尔变量指示游戏状态。
功能:
__init __(self):这是构造函数。它使用适当的默认值初始化所有变量。
开始:调用random_cell两次,将'2'赋给两个随机单元格的gridCell值,然后绘制网格,然后,调用link_keys链接上,下,左和右键。
Link_keys:首先,它检查游戏是赢还是输,如果是,则不执行任何操作执行return语句。否则,它将继续执行。
方法:
对于左滑动,我们将先压缩然后合并gridCell矩阵,然后如果compress或merge为true(指示矩阵的值受前两个函数影响),那么我们需要再次压缩网格。
对于上移,我们将进行移调,然后向左轻扫,然后再次进行移调以返回原始顺序。
向下移动与向上移动相同,但是我们需要反转矩阵。
同样,向右与向左+向后移动相同。
每次操作后,我们需要检查游戏状态,如果所有单元都被占用,我们甚至不能合并任何两个单元,即没有动作可以改变矩阵的状态,则游戏结束了。
如果任何一个单元格值都达到2048,则玩家将获胜,并且屏幕上会闪烁一个消息框,宣布获胜者。
总结
我们已经成功地用python开发了流行的2048游戏。开发游戏而不是玩别人的游戏非常有趣,现在我们将玩自己开发的游戏。
来源:https://projectgurukul.org/python-2048-game/