您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關python實現俄羅斯方塊的方法的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
python實現俄羅斯方塊的具體代碼,具體內容如下
# teris.py # A module for game teris. # By programmer FYJ from tkinter import * from time import sleep from random import * from tkinter import messagebox class Teris: def __init__(self): #方塊顏色列表 self.color = ['red','orange','yellow','purple','blue','green','pink'] # Set a core squre and any shape can be drawn by the relative location. #字典 存儲形狀對應7種形狀 元組存儲坐標 self.shapeDict = {1:[(0,0),(0,-1),(0,-2),(0,1)], # shape I 2:[(0,0),(0,-1),(1,-1),(1,0)], # shape O 3:[(0,0),(-1,0),(0,-1),(1,0)], # shape T T型 4:[(0,0),(0,-1),(1,0),(2,0)], # shape J 右長倒L蓋子 5:[(0,0),(0,-1),(-1,0),(-2,0)], # shape L 6:[(0,0),(0,-1),(-1,-1),(1,0)], # shape Z 7:[(0,0),(-1,0),(0,-1),(1,-1)]} # shape S #旋轉坐標控制 self.rotateDict = {(0,0):(0,0),(0,1):(-1,0),(0,2):(-2,0),(0,-1):(1,0), (0,-2):(2,0),(1,0):(0,1),(2,0):(0,2),(-1,0):(0,-1), (-2,0):(0,-2),(1,1):(-1,1),(-1,1):(-1,-1), (-1,-1):(1,-1),(1,-1):(1,1)} # 初始高度,寬度 核心塊位置 self.coreLocation = [4,-2] self.height,self.width = 20,10 self.size = 32 # Map can record the location of every square.i寬 j高 self.map = {} #全部置0 for i in range(self.width): for j in range(-4,self.height): self.map[(i,j)] = 0 #添加邊界 for i in range(-4,self.width+4): self.map[(i,self.height)] = 1 for j in range(-4,self.height+4): for i in range(-4,0): self.map[(i,j)] = 1 for j in range(-4,self.height+4): for i in range(self.width,self.width+4): self.map[(i,j)] = 1 # 初始化分數0 默認不加快 按下時加快 self.score = 0 self.isFaster = False # 創建GUI界面 self.root = Tk() self.root.title("Teris") self.root.geometry("500x645") self.area = Canvas(self.root,width=320,height=640,bg='white') self.area.grid(row=2) self.pauseBut = Button(self.root,text="Pause",height=2,width=13,font=(18),command=self.isPause) self.pauseBut.place(x=340,y=100) self.startBut = Button(self.root,text="Start",height=2,width=13,font=(18),command=self.play) self.startBut.place(x=340,y=20) self.restartBut = Button(self.root,text="Restart",height=2,width=13,font=(18),command=self.isRestart) self.restartBut.place(x=340,y=180) self.quitBut = Button(self.root,text="Quit",height=2,width=13,font=(18),command=self.isQuit) self.quitBut.place(x=340,y=260) self.scoreLabel1 = Label(self.root,text="Score:",font=(24)) self.scoreLabel1.place(x=340,y=600) self.scoreLabel2 = Label(self.root,text="0",fg='red',font=(24)) self.scoreLabel2.place(x=410,y=600) #按鍵交互 self.area.bind("<Up>",self.rotate) self.area.bind("<Left>",self.moveLeft) self.area.bind("<Right>",self.moveRight) self.area.bind("<Down>",self.moveFaster) self.area.bind("<Key-w>",self.rotate) self.area.bind("<Key-a>",self.moveLeft) self.area.bind("<Key-d>",self.moveRight) self.area.bind("<Key-s>",self.moveFaster) self.area.focus_set() #菜單 self.menu = Menu(self.root) self.root.config(menu=self.menu) self.startMenu = Menu(self.menu) self.menu.add_cascade(label='Start',menu=self.startMenu) self.startMenu.add_command(label='New Game',command=self.isRestart) self.startMenu.add_separator() self.startMenu.add_command(label='Continue',command=self.play) self.exitMenu = Menu(self.menu) self.menu.add_cascade(label='Exit',command=self.isQuit) self.helpMenu = Menu(self.root) self.menu.add_cascade(label='Help',menu=self.helpMenu) self.helpMenu.add_command(label='How to play',command=self.rule) self.helpMenu.add_separator() self.helpMenu.add_command(label='About...',command=self.about) #先將核心塊的所在位置在map中的元素設為1,通過self.shapeDict獲取其余方塊位置,將map中對應元素設為1。 def getLocation(self): map[(core[0],core[1])] = 1 for i in range(4): map[((core[0]+getNew[i][0]), (core[1]+getNew[i][1]))]=1 #判斷方塊下移一格后對應位置map中的元素是否為一,是,則不可移動,返回False;否,可以移動,返回True。 def canMove(self): for i in range(4): if map[(core[0]+getNew[i][0]),(core[1]+1+getNew[i][1])] == 1: return False return True # 先用randRange獲取1~7中的隨機整數,隨機到某一整數,那么訪問self.shapeDict,獲取這種形狀方塊的核心塊及其他方塊的相對位置。 # 訪問顏色字典,獲取此方塊的顏色。建立循環,當方塊可移動時(while self. canMove():),且暫停鍵未被摁下(if isPause:), # 核心塊縱坐標加一,根據核心塊及其他方塊對于核心塊的相對位置,畫出四個方塊。用self.getLocation()函數獲取方塊的位置。 def drawNew(self): global next global getNew global core next = randrange(1,8) #形狀 self.getNew = self.shapeDict[next] getNew = self.getNew core = [4,-2] time = 0.2 while self.canMove(): if isPause: core[1] += 1 self.drawSquare() if self.isFaster: sleep(time-0.15) else: sleep(time+0.22) self.isFaster = False else: self.drawSquare() sleep(time) self.getLocation() # 繪制當前方塊 def drawSquare(self): self.area.delete("new") for i in range(4): self.area.create_rectangle((core[0]+self.getNew[i][0])*self.size, (core[1]+self.getNew[i][1])*self.size, (core[0]+self.getNew[i][0]+1)*self.size, (core[1]+self.getNew[i][1]+1)*self.size, fill=self.color[next-1],tags="new") self.area.update() # 給底部每行中方塊都加上標簽:bottom + str(j), j代表該塊所在行數,每次遍歷map,建立對于range(self. height)的for循環,刪去每一行, # 若map什么地方的元素為1,畫出這一位置的方塊,不斷更新。這樣可以畫出底部方塊。 def drawBottom(self): for j in range(self.height): self.area.delete('bottom'+str(j)) for i in range(self.width): if map[(i,j)] == 1: self.area.create_rectangle(self.size*i,self.size*j,self.size*(i+1), self.size*(j+1),fill='grey',tags='bottom'+str(j)) self.area.update() # 判斷填滿遍歷map每一行的各個元素,若所有元素為1,則標簽中score值+10,將 # 此行所有元素改為0,行數map(i,j)=map(i-1,j)(即所有之上的行下移) # ,那么后續畫底部方塊時,可實現消行。 def isFill(self): for j in range(self.height): t = 0 for i in range(self.width): if map[(i,j)] == 1: t = t + 1 if t == self.width: self.getScore() self.deleteLine(j) # 加分 def getScore(self): scoreValue = eval(self.scoreLabel2['text']) scoreValue += 10 self.scoreLabel2.config(text=str(scoreValue)) # 消行 def deleteLine(self,j): for t in range(j,2,-1): for i in range(self.width): map[(i,t)] = map[(i,t-1)] for i in range(self.width): map[(i,0)] = 0 self.drawBottom() # 遍歷每一行,若從頂部到底部map每一行都有某一個元素或更多元素為1, # 那么說明方塊以頂到最上端,游戲結束。此處不可以簡單判定最上一行是否有元素為1就判定結束, # 若這樣會產生頂部有新的方塊產生,然后導致頂部有元素為1,誤判為游戲結束。 def isOver(self): t = 0 for j in range(self.height): for i in range(self.width): if self.map[(i,j)] == 1: t += 1 break if t >= self.height: return False else: return True # 先判斷方塊是否可以旋轉(針對其靠近邊界時)。先將其現在所在位置對應map中的元素改為0,判斷其旋 # 轉后位置對應map中的元素是否有一,若有,說明其旋轉后的位置已經被占,是不能旋轉的,返回值為False # 。否則為可旋轉,返回值True。若已判定可以旋轉,那么訪問self.rotateDict,得出旋轉以后所有小塊的位置 # 變換,將變換以后的位置對應map的元素設為1,旋轉便已完成。 def canRotate(self): for i in range(4): map[((core[0]+getNew[i][0]), (core[1]+getNew[i][1]))] = 0 for i in range(4): if map[((core[0]+self.rotateDict[getNew[i]][0]), (core[1]+self.rotateDict[getNew[i]][1]))] == 1: return False return True #旋轉 def rotate(self,event): if next != 2: if self.canRotate(): for i in range(4): getNew[i] = self.rotateDict[getNew[i]] self.drawSquare() if not self.canMove(): for i in range(4): map[((core[0]+getNew[i][0]),(core[1]+getNew[i][1]))] = 1 # 先判斷是否左移/右移,同樣,將方塊現在所處位置的map中元素設為0,看其移動后的位置上map的元素是否有1, # 若有,說明這一位置已被占據或已到邊界,不可移動,返回False。若可移動,返回True。按下左鍵,若可 # 以移動,核心塊的橫坐標減1,由于我們只討論其他小塊對于核心塊的相對位置,所以其他小塊的位置自動隨 # 核心塊的位置移動而移動。將移動過后的位置對應map中的元素設為1。 def canLeft(self): coreNow = core for i in range(4): map[((coreNow[0]+getNew[i][0]),(coreNow[1]+getNew[i][1]))] = 0 for i in range(4): if map[((coreNow[0]+getNew[i][0]-1),(coreNow[1]+getNew[i][1]))] == 1: return False return True #左移 def moveLeft(self,event): if self.canLeft(): core[0] -= 1 self.drawSquare() self.drawBottom() if not self.canMove(): for i in range(4): map[((core[0]+getNew[i][0]),(core[1]+getNew[i][1]))] = 1 # 判斷右移 def canRight(self): for i in range(4): map[((core[0]+getNew[i][0]),(core[1]+getNew[i][1]))] = 0 for i in range(4): if map[((core[0]+getNew[i][0]+1),(core[1]+getNew[i][1]))] == 1: return False return True # 右移 def moveRight(self,event): if self.canRight(): core[0] += 1 self.drawSquare() self.drawBottom() if not self.canMove(): for i in range(4): map[((core[0]+getNew[i][0]),(core[1]+getNew[i][1]))] = 1 # 初始化中有一self. isFaster 的變量被設為False,當其為False時, # 程序中的sleep(time)中time的值為0.35,而按下下鍵,self. isFaster變為True, # time變成0.05,通過調整sleep()中變量的大小可以調節方塊運動的速度。 # 此功能通過if語句實現。 def moveFaster(self,event): self.isFaster = True if not self.canMove(): for i in range(4): map[((core[0]+getNew[i][0]),(core[1]+getNew[i][1]))] = 1 # run the programe def run(self): self.isFill() self.drawNew() self.drawBottom() # play the game def play(self): self.startBut.config(state=DISABLED) global isPause isPause = True global map map = self.map while True: if self.isOver(): self.run() else: break self.over() # 重新開始游戲 def restart(self): self.core = [4,-2] self.map = {} for i in range(self.width): for j in range(-4,self.height): self.map[(i,j)] = 0 for i in range(-1,self.width): self.map[(i,self.height)] = 1 for j in range(-4,self.height+1): self.map[(-1,j)] = 1 self.map[(self.width,j)] = 1 self.score = 0 self.t = 0.07 for j in range(self.height): self.area.delete('bottom'+str(j)) self.play() # 結束后告訴用戶失敗 def over(self): feedback =messagebox.askquestion("You Lose!","You Lose!\nDo you want to restart?") if feedback == 'yes': self.restart() else: self.root.destroy() # 退出 def isQuit(self): askQuit =messagebox.askquestion("Quit","Are you sure to quit?") if askQuit == 'yes': self.root.destroy() exit() #判斷是否按下restart def isRestart(self): askRestart =messagebox.askquestion("Restart","Are you sure to restart?") if askRestart == 'yes': self.restart() else: return # 每次一按下暫停鍵,isPause = not isPause,當isPause = True時,由于之前提到過的if isPause:語句, # 方塊可以移動,游戲運行。當按下暫停鍵以后,isPause值為False,方塊將不可移動。同時,isPause值為False時 # ,暫停鍵變為開始鍵,即標簽由Pause 改為 Resume,當isPause值為True時,Resume改為Pause。這一功能由if語句實現。 def isPause(self): global isPause isPause=not isPause if not isPause: self.pauseBut["text"]="Resume" else: self.pauseBut["text"]="Pause" #幫助 def rule(self): ruleTop = Toplevel() ruleTop.title('Help') ruleTop.geometry('800x400') rule ="Start: Press the start button or choose the option 'Continue' to start the game.\n%-s%-s%-s%-s%-s%-s%-s%-s%-s%-s%-s%-s%-s%-s"%("Restart: Press the restart button or choose the option 'New Game' to resatrt the game.\n", "Enjoy the Teris game! Have fun!") ruleLabel = Label(ruleTop,text=rule,fg='blue',font=(18)) ruleLabel.place(x=50,y=50) # 顯示有關信息 def about(self): aboutTop = Toplevel() aboutTop.title('About') aboutTop.geometry('300x150') about = "Teris.py\n\ By Programmer Lee\n\ All Rights Reserved." aboutLabel = Label(aboutTop,font=('Curier',20),fg='darkblue',text=about) aboutLabel.pack() # Get into mainloop def mainloop(self): self.root.mainloop() # TerisPlay.py # Game Teris # By programmer FYJ from teris import * def main(): teris = Teris() teris.mainloop() main()
運行結構如圖所示:
感謝各位的閱讀!關于“python實現俄羅斯方塊的方法”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。