Python学习基础后,是不是不知道怎么加固练习?今天分享几个小游戏,让你在游戏中把知识给巩固了。
小时候大家一定都玩过俄罗斯方块,下面我们看看Python是怎么实现这个游戏的.
1、绑定功能
# 绑定功能 class App(Frame): def __init__(self,master): Frame.__init__(self) master.bind('<Up>',self.Up) master.bind('<Left>',self.Left) master.bind('<Right>',self.Right) master.bind('<Down>',self.Down) master.bind('<space>',self.Space) master.bind('<Control-Shift-Key-F12>',self.Play) master.bind('<Key-P>',self.Pause) master.bind('<Key-S>',self.StartByS) # rgb颜色值 self.backg="#%02x%02x%02x" % (120,150,30) #大背景 self.frontg="#%02x%02x%02x" % (40,120,150) #下一个形状颜色 self.nextg="#%02x%02x%02x" % (150,100,100) #小背景 self.flashg="#%02x%02x%02x" % (210,130,100) #炸的颜色 self.LineDisplay=Label(master,text='Lines: ',bg='black',fg='red') self.Line=Label(master,text='0',bg='black',fg='red') self.ScoreDisplay=Label(master,text='Score: ',bg='black',fg='red') self.Score=Label(master,text='0',bg='black',fg='red') self.SpendTimeDisplay=Label(master,text='Time: ',bg='black',fg='red') self.SpendTime=Label(master,text='0.0',bg='black',fg='red') self.LineDisplay.grid(row=HEIGHT-2,column=WIDTH,columnspan=2) self.Line.grid(row=HEIGHT-2,column=WIDTH+2,columnspan=3) self.ScoreDisplay.grid(row=HEIGHT-1,column=WIDTH,columnspan=2) self.Score.grid(row=HEIGHT-1,column=WIDTH+2,columnspan=3) self.SpendTimeDisplay.grid(row=HEIGHT-4,column=WIDTH,columnspan=2) self.SpendTime.grid(row=HEIGHT-4,column=WIDTH+2,columnspan=3) self.TotalTime=0.0 self.TotalLine=0 self.TotalScore=0 #游戏结束 self.isgameover=FALSE #暂停 self.isPause=FALSE #开始 self.isStart=FALSE self.NextList=[] #整个小背景 self.NextRowList=[] #一行小背景 self.px=0 self.py=0 #记录方块参考点 #渲染小背景 r=0;c=0 for k in range(4*4): LN=Label(master,text=' ',bg=str(self.nextg),fg='white',relief=FLAT,bd=3) LN.grid(row=r,column=WIDTH+c,sticky=N+E+S+W) self.NextRowList.append(LN) c=c+1 if c>=4: r=r+1;c=0 self.NextList.append(self.NextRowList) self.NextRowList=[] #渲染大背景 self.BlockList=[] self.BlockRowList=[] self.LabelList=[] self.LabelRowList=[] row=0;col=0 for i in range(HEIGHT*WIDTH): L=Label(master,text=' ',bg=str(self.backg),fg='white',relief=FLAT,bd=4) L.grid(row=row,column=col,sticky=N+E+S+W) L.row=row;L.col=col;L.isactive=PASSIVE self.BlockRowList.append(0); #大背景每个格子初始化为0值 self.LabelRowList.append(L) col=col+1 if col>=WIDTH: row=row+1;col=0 self.BlockList.append(self.BlockRowList) self.LabelList.append(self.LabelRowList) self.BlockRowList=[] self.LabelRowList=[] #file fw=open('text.txt','a') fw.close() hasHead=FALSE f=open('text.txt','r') if f.read(5)=='score': hasHead=TRUE f.close() self.file=open('text.txt','a') if hasHead==FALSE: self.file.write('score line time scorePtime linePtime scorePline date/n') self.file.flush() self.time=1000 self.OnTimer()
2、实现对俄罗斯方块的翻转
# 俄罗斯方块的翻转 def Up(self,event): BL=self.BlockList #格子的值 LL=self.LabelList #格子Label Moveable=TRUE #是否可旋转 #代码编写开始 nowStyle = style[self.xnow][(self.ynow)] newStyle = style[self.xnow][(self.ynow+1)%4] #算出下一俄罗斯方块 self.ynow = (self.ynow+1)%4 #此行代码非常重要,否则响应UP时,只能变第一次 print("nowStyle:"+str(nowStyle)+"=====>>newStyle:"+str(newStyle)) #根据现有形状中每个label的坐标计算出旋转后目标坐标(x,y) SourceList=[];DestList=[] for i in range(4): SourceList.append([ nowStyle[i][0]+self.px, nowStyle[i][1]+self.py]) x = newStyle[i][0]+self.px y = newStyle[i][1]+self.py DestList.append([x, y]) if x<0 or x>=HEIGHT or y<0 or y>=WIDTH : #or BL[x][y]==1 or LL[x][y].isactive==PASSIVE Moveable=FALSE if Moveable==TRUE: for i in range(len(SourceList)): self.Empty(SourceList[i][0],SourceList[i][1]) for i in range(len(DestList)): self.Fill(DestList[i][0],DestList[i][1]) def Left(self,event): BL=self.BlockList;LL=self.LabelList Moveable=TRUE for i in range(HEIGHT): for j in range(WIDTH): if LL[i][j].isactive==ACTIVE and j-1<0:Moveable=FALSE if LL[i][j].isactive==ACTIVE and j-1>=0 and BL[i][j-1]==1 and LL[i][j-1].isactive==PASSIVE:Moveable=FALSE if Moveable==TRUE: self.py-=1 for i in range(HEIGHT): for j in range(WIDTH): if j-1>=0 and LL[i][j].isactive==ACTIVE and BL[i][j-1]==0: self.Fill(i,j-1);self.Empty(i,j) def Right(self,event): BL=self.BlockList;LL=self.LabelList Moveable=TRUE for i in range(HEIGHT): for j in range(WIDTH): if LL[i][j].isactive==ACTIVE and j+1>=WIDTH:Moveable=FALSE if LL[i][j].isactive==ACTIVE and j+1<WIDTH and BL[i][j+1]==1 and LL[i][j+1].isactive==PASSIVE:Moveable=FALSE if Moveable==TRUE: self.py+=1 for i in range(HEIGHT-1,-1,-1): for j in range(WIDTH-1,-1,-1): if j+1<WIDTH and LL[i][j].isactive==ACTIVE and BL[i][j+1]==0: self.Fill(i,j+1);self.Empty(i,j) def Down(self,event): BL=self.BlockList;LL=self.LabelList Moveable=TRUE for i in range(HEIGHT): for j in range(WIDTH): if LL[i][j].isactive==ACTIVE and i+1>=HEIGHT:Moveable=FALSE if LL[i][j].isactive==ACTIVE and i+1<HEIGHT and BL[i+1][j]==1 and LL[i+1][j].isactive==PASSIVE:Moveable=FALSE if Moveable==TRUE and self.isStart : self.px+=1 for i in range(HEIGHT-1,-1,-1): for j in range(WIDTH-1,-1,-1): if i+1<HEIGHT and LL[i][j].isactive==ACTIVE and BL[i+1][j]==0: self.Fill(i+1,j);self.Empty(i,j); if Moveable==FALSE: for i in range(HEIGHT): for j in range(WIDTH): LL[i][j].isactive=PASSIVE self.JudgeLineFill() self.Start() if self.isgameover==TRUE:showinfo('T_T','The game is over!');self.Distroy();return FALSE for i in range(4): for j in range(4): self.NextEmpty(i,j) self.Rnd() return Moveable def Space(self,event): while 1: if self.Down(0)==FALSE:break
3、完整项目代码
#_*_ coding:utf-8 _*_ from tkinter import * import random import time import tkinter.messagebox #俄罗斯方块界面的高度 HEIGHT = 20 #俄罗斯方块界面的宽度 WIDTH = 10 ACTIVE = 1 PASSIVE = 0 TRUE = 1 FALSE = 0 style = [ [[(0,0),(0,1),(1,1),(2,1)],[(1,0),(1,1),(1,2),(0,2)],[(0,1),(1,1),(2,1),(2,2)],[(1,0),(2,0),(1,1),(1,2)]],#j [[(1,0),(1,1),(1,2),(2,1)],[(1,0),(0,1),(1,1),(2,1)],[(1,0),(1,1),(1,2),(0,1)],[(0,1),(1,1),(2,1),(1,2)]],#T [[(0,1),(1,1),(2,1),(2,0)],[(0,0),(1,0),(1,1),(1,2)],[(0,1),(1,1),(2,1),(0,2)],[(1,0),(1,1),(1,2),(2,2)]],#反L [[(0,0),(0,1),(1,1),(1,2)],[(2,1),(1,1),(1,2),(0,2)],[(0,0),(0,1),(1,1),(1,2)],[(2,1),(1,1),(1,2),(0,2)]],#Z [[(1,0),(1,1),(0,1),(0,2)],[(0,1),(1,1),(1,2),(2,2)],[(1,0),(1,1),(0,1),(0,2)],[(0,1),(1,1),(1,2),(2,2)]],#反Z [[(0,0),(0,1),(1,1),(1,0)],[(0,0),(0,1),(1,1),(1,0)],[(0,0),(0,1),(1,1),(1,0)],[(0,0),(0,1),(1,1),(1,0)]],#田 [[(1,0),(1,1),(1,2),(1,3)],[(0,1),(1,1),(2,1),(3,1)],[(1,0),(1,1),(1,2),(1,3)],[(0,1),(1,1),(2,1),(3,1)]]#长条 ] root=Tk(); root.title('俄罗斯方块') class App(Frame): def __init__(self,master): Frame.__init__(self) master.bind('<Up>',self.Up) master.bind('<Left>',self.Left) master.bind('<Right>',self.Right) master.bind('<Down>',self.Down) master.bind('<space>',self.Space) master.bind('<Control-Shift-Key-F12>',self.Play) master.bind('<Key-P>',self.Pause) master.bind('<Key-S>',self.StartByS) # rgb颜色值 self.backg="#%02x%02x%02x" % (120,150,30) #大背景 self.frontg="#%02x%02x%02x" % (40,120,150) #下一个形状颜色 self.nextg="#%02x%02x%02x" % (150,100,100) #小背景 self.flashg="#%02x%02x%02x" % (210,130,100) #炸的颜色 self.LineDisplay=Label(master,text='Lines: ',bg='black',fg='red') self.Line=Label(master,text='0',bg='black',fg='red') self.ScoreDisplay=Label(master,text='Score: ',bg='black',fg='red') self.Score=Label(master,text='0',bg='black',fg='red') self.SpendTimeDisplay=Label(master,text='Time: ',bg='black',fg='red') self.SpendTime=Label(master,text='0.0',bg='black',fg='red') self.LineDisplay.grid(row=HEIGHT-2,column=WIDTH,columnspan=2) self.Line.grid(row=HEIGHT-2,column=WIDTH+2,columnspan=3) self.ScoreDisplay.grid(row=HEIGHT-1,column=WIDTH,columnspan=2) self.Score.grid(row=HEIGHT-1,column=WIDTH+2,columnspan=3) self.SpendTimeDisplay.grid(row=HEIGHT-4,column=WIDTH,columnspan=2) self.SpendTime.grid(row=HEIGHT-4,column=WIDTH+2,columnspan=3) self.TotalTime=0.0 self.TotalLine=0 self.TotalScore=0 #游戏结束 self.isgameover=FALSE #暂停 self.isPause=FALSE #开始 self.isStart=FALSE self.NextList=[] #整个小背景 self.NextRowList=[] #一行小背景 self.px=0 self.py=0 #记录方块参考点 #渲染小背景 r=0;c=0 for k in range(4*4): LN=Label(master,text=' ',bg=str(self.nextg),fg='white',relief=FLAT,bd=3) LN.grid(row=r,column=WIDTH+c,sticky=N+E+S+W) self.NextRowList.append(LN) c=c+1 if c>=4: r=r+1;c=0 self.NextList.append(self.NextRowList) self.NextRowList=[] #渲染大背景 self.BlockList=[] self.BlockRowList=[] self.LabelList=[] self.LabelRowList=[] row=0;col=0 for i in range(HEIGHT*WIDTH): L=Label(master,text=' ',bg=str(self.backg),fg='white',relief=FLAT,bd=4) L.grid(row=row,column=col,sticky=N+E+S+W) L.row=row;L.col=col;L.isactive=PASSIVE self.BlockRowList.append(0); #大背景每个格子初始化为0值 self.LabelRowList.append(L) col=col+1 if col>=WIDTH: row=row+1;col=0 self.BlockList.append(self.BlockRowList) self.LabelList.append(self.LabelRowList) self.BlockRowList=[] self.LabelRowList=[] #file fw=open('text.txt','a') fw.close() hasHead=FALSE f=open('text.txt','r') if f.read(5)=='score': hasHead=TRUE f.close() self.file=open('text.txt','a') if hasHead==FALSE: self.file.write('score line time scorePtime linePtime scorePline date/n') self.file.flush() self.time=1000 self.OnTimer() def __del__(self): #self.file.close() pass def Pause(self,event): self.isPause=1-self.isPause def Up(self,event): BL=self.BlockList #格子的值 LL=self.LabelList #格子Label Moveable=TRUE #是否可旋转 #代码编写开始 nowStyle = style[self.xnow][(self.ynow)] newStyle = style[self.xnow][(self.ynow+1)%4] #算出下一俄罗斯方块 self.ynow = (self.ynow+1)%4 #此行代码非常重要,否则响应UP时,只能变第一次 print("nowStyle:"+str(nowStyle)+"=====>>newStyle:"+str(newStyle)) #根据现有形状中每个label的坐标计算出旋转后目标坐标(x,y) SourceList=[];DestList=[] for i in range(4): SourceList.append([ nowStyle[i][0]+self.px, nowStyle[i][1]+self.py]) x = newStyle[i][0]+self.px y = newStyle[i][1]+self.py DestList.append([x, y]) if x<0 or x>=HEIGHT or y<0 or y>=WIDTH : #or BL[x][y]==1 or LL[x][y].isactive==PASSIVE Moveable=FALSE if Moveable==TRUE: for i in range(len(SourceList)): self.Empty(SourceList[i][0],SourceList[i][1]) for i in range(len(DestList)): self.Fill(DestList[i][0],DestList[i][1]) def Left(self,event): BL=self.BlockList;LL=self.LabelList Moveable=TRUE for i in range(HEIGHT): for j in range(WIDTH): if LL[i][j].isactive==ACTIVE and j-1<0:Moveable=FALSE if LL[i][j].isactive==ACTIVE and j-1>=0 and BL[i][j-1]==1 and LL[i][j-1].isactive==PASSIVE:Moveable=FALSE if Moveable==TRUE: self.py-=1 for i in range(HEIGHT): for j in range(WIDTH): if j-1>=0 and LL[i][j].isactive==ACTIVE and BL[i][j-1]==0: self.Fill(i,j-1);self.Empty(i,j) def Right(self,event): BL=self.BlockList;LL=self.LabelList Moveable=TRUE for i in range(HEIGHT): for j in range(WIDTH): if LL[i][j].isactive==ACTIVE and j+1>=WIDTH:Moveable=FALSE if LL[i][j].isactive==ACTIVE and j+1<WIDTH and BL[i][j+1]==1 and LL[i][j+1].isactive==PASSIVE:Moveable=FALSE if Moveable==TRUE: self.py+=1 for i in range(HEIGHT-1,-1,-1): for j in range(WIDTH-1,-1,-1): if j+1<WIDTH and LL[i][j].isactive==ACTIVE and BL[i][j+1]==0: self.Fill(i,j+1);self.Empty(i,j) def Down(self,event): BL=self.BlockList;LL=self.LabelList Moveable=TRUE for i in range(HEIGHT): for j in range(WIDTH): if LL[i][j].isactive==ACTIVE and i+1>=HEIGHT:Moveable=FALSE if LL[i][j].isactive==ACTIVE and i+1<HEIGHT and BL[i+1][j]==1 and LL[i+1][j].isactive==PASSIVE:Moveable=FALSE if Moveable==TRUE and self.isStart : self.px+=1 for i in range(HEIGHT-1,-1,-1): for j in range(WIDTH-1,-1,-1): if i+1<HEIGHT and LL[i][j].isactive==ACTIVE and BL[i+1][j]==0: self.Fill(i+1,j);self.Empty(i,j); if Moveable==FALSE: for i in range(HEIGHT): for j in range(WIDTH): LL[i][j].isactive=PASSIVE self.JudgeLineFill() self.Start() if self.isgameover==TRUE:showinfo('T_T','The game is over!');self.Distroy();return FALSE for i in range(4): for j in range(4): self.NextEmpty(i,j) self.Rnd() return Moveable def Space(self,event): while 1: if self.Down(0)==FALSE:break def OnTimer(self): if self.isStart==TRUE and self.isPause==FALSE: self.TotalTime = self.TotalTime + float(self.time)/1000 self.SpendTime.config(text=str(self.TotalTime)) if self.isPause==FALSE: self.Down(0) if self.TotalScore>=1000:self.time=900 if self.TotalScore>=2000:self.time=750 if self.TotalScore>=3000:self.time=600 if self.TotalScore>=4000:self.time=400 self.after(self.time,self.OnTimer) #随着分数增大,俄罗斯方块下降速度加快 def JudgeLineFill(self): BL=self.BlockList;LL=self.LabelList count=0;LineList=[] for i in range(WIDTH):LineList.append(1) #display flash for i in range(HEIGHT): if BL[i]==LineList: count=count+1 for k in range(WIDTH): LL[i][k].config(bg=str(self.flashg)) LL[i][k].update() if count!=0:self.after(100) #delete block for i in range(HEIGHT): if BL[i]==LineList: #count=count+1 for j in range(i,0,-1): for k in range(WIDTH): BL[j][k]=BL[j-1][k] LL[j][k]['relief']=LL[j-1][k].cget('relief') LL[j][k]['bg']=LL[j-1][k].cget('bg') for l in range(WIDTH): BL[0][l]=0 LL[0][l].config(relief=FLAT,bg=str(self.backg)) self.TotalLine=self.TotalLine+count if count==1:self.TotalScore=self.TotalScore+1*WIDTH if count==2:self.TotalScore=self.TotalScore+3*WIDTH if count==3:self.TotalScore=self.TotalScore+6*WIDTH if count==4:self.TotalScore=self.TotalScore+10*WIDTH self.Line.config(text=str(self.TotalLine)) self.Score.config(text=str(self.TotalScore)) def Fill(self,i,j): if j<0:return if self.BlockList[i][j]==1:self.isgameover=TRUE self.BlockList[i][j]=1 self.LabelList[i][j].isactive=ACTIVE self.LabelList[i][j].config(relief=RAISED,bg=str(self.frontg)) def Empty(self,i,j): self.BlockList[i][j]=0 self.LabelList[i][j].isactive=PASSIVE self.LabelList[i][j].config(relief=FLAT,bg=str(self.backg)) def Play(self,event): showinfo('Made in China','^_^') def NextFill(self,i,j): self.NextList[i][j].config(relief=RAISED,bg=str(self.frontg)) def NextEmpty(self,i,j): self.NextList[i][j].config(relief=FLAT,bg=str(self.nextg)) def Distroy(self): #save if self.TotalScore!=0: #cehkongfu savestr='%-9u%-8u%-8.2f%-14.2f%-13.2f%-14.2f%s/n' % ( self.TotalScore,self.TotalLine,self.TotalTime ,self.TotalScore/self.TotalTime ,self.TotalLine/self.TotalTime ,float(self.TotalScore)/self.TotalLine ,time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())) self.file.seek(0,2) self.file.write(savestr) self.file.flush() for i in range(HEIGHT): for j in range(WIDTH): self.Empty(i,j) self.TotalLine=0;self.TotalScore=0;self.TotalTime=0.0 self.Line.config(text=str(self.TotalLine)) self.Score.config(text=str(self.TotalScore)) self.SpendTime.config(text=str(self.TotalTime)) self.isgameover=FALSE self.isStart=FALSE self.time=1000 for i in range(4): for j in range(4): self.NextEmpty(i,j) #游戏开始方块 def Start(self): nextStyle = style[self.x][self.y] #下一形状 self.xnow = self.x self.ynow = self.y #记录大背景中的方块 self.py = random.randint(0,6) print("给py赋任意值:"+str(self.py)) self.px = 0 for ii in range(4): self.Fill(int(nextStyle[ii][0]),int(nextStyle[ii][1])+self.py) self.isStart=TRUE #游戏开始 #预处理方块 def Rnd(self): self.x=random.randint(0,6) self.y=random.randint(0,3) nextStyle = style[self.x][self.y] #下一形状 for ii in range(4): self.NextFill(int(nextStyle[ii][0]),int(nextStyle[ii][1])) #游戏开始给出一次任意形状的方块 def RndFirst(self): self.x=random.randint(0,6) #选择第一个方块style self.y=random.randint(0,3) def Show(self): self.file.seek(0) strHeadLine=self.file.readline() dictLine={} strTotalLine='' for OneLine in self.file.readlines(): temp=int(OneLine[:5]) dictLine[temp]=OneLine list=sorted(dictLine.items(),key=lambda d:d[0]) ii=0 for onerecord in reversed(list): ii=ii+1 if ii<11: strTotalLine+=onerecord[1] showinfo('Ranking', strHeadLine+strTotalLine) def StartByS(self,event): self.RndFirst() self.Start() self.Rnd() def Start(): app.RndFirst() app.Start() app.Rnd() def End(): app.Distroy() def Set(): print("设置功能待完善...") def Show(): app.Show() #主菜单 mainmenu=Menu(root) root['menu']=mainmenu #二级菜单:game gamemenu=Menu(mainmenu) mainmenu.add_cascade(label='游戏',menu=gamemenu) gamemenu.add_command(label='开始',command=Start) gamemenu.add_command(label='结束',command=End) gamemenu.add_separator() gamemenu.add_command(label='退出',command=root.quit) #二级菜单:set setmenu=Menu(mainmenu) mainmenu.add_cascade(label='设置',menu=setmenu) setmenu.add_command(label='设置',command=Set) #二级菜单:show showmenu=Menu(mainmenu) mainmenu.add_cascade(label='展示',menu=showmenu) showmenu.add_command(label='展示',command=Show) #绑定功能 app=App(root) #程序入口 root.mainloop()
游戏效果:
二、经典的贪吃蛇游戏
这个游戏就非常经典了,试试Python的执行效果
源码:
import random import pygame import sys from pygame.locals import * Snakespeed = 9 Window_Width = 800 Window_Height = 500 Cell_Size = 20 # Width and height of the cells # Ensuring that the cells fit perfectly in the window. eg if cell size was # 10 and window width or window height were 15 only 1.5 cells would # fit. assert Window_Width % Cell_Size == 0, "Window width must be a multiple of cell size." # Ensuring that only whole integer number of cells fit perfectly in the window. assert Window_Height % Cell_Size == 0, "Window height must be a multiple of cell size." Cell_W = int(Window_Width / Cell_Size) # Cell Width Cell_H = int(Window_Height / Cell_Size) # Cell Height White = (255, 255, 255) Black = (0, 0, 0) Red = (255, 0, 0) # Defining element colors for the program. Green = (0, 255, 0) DARKGreen = (0, 155, 0) DARKGRAY = (40, 40, 40) YELLOW = (255, 255, 0) Red_DARK = (150, 0, 0) BLUE = (0, 0, 255) BLUE_DARK = (0, 0, 150) BGCOLOR = Black # Background color UP = 'up' DOWN = 'down' # Defining keyboard keys. LEFT = 'left' RIGHT = 'right' HEAD = 0 # Syntactic sugar: index of the snake's head def main(): global SnakespeedCLOCK, DISPLAYSURF, BASICFONT pygame.init() SnakespeedCLOCK = pygame.time.Clock() DISPLAYSURF = pygame.display.set_mode((Window_Width, Window_Height)) BASICFONT = pygame.font.Font('freesansbold.ttf', 18) pygame.display.set_caption('Snake') showStartScreen() while True: runGame() showGameOverScreen() def runGame(): # Set a random start point. startx = random.randint(5, Cell_W - 6) starty = random.randint(5, Cell_H - 6) wormCoords = [{'x': startx, 'y': starty}, {'x': startx - 1, 'y': starty}, {'x': startx - 2, 'y': starty}] direction = RIGHT # Start the apple in a random place. apple = getRandomLocation() while True: # main game loop for event in pygame.event.get(): # event handling loop if event.type == QUIT: terminate() elif event.type == KEYDOWN: if (event.key == K_LEFT) and direction != RIGHT: direction = LEFT elif (event.key == K_RIGHT) and direction != LEFT: direction = RIGHT elif (event.key == K_UP) and direction != DOWN: direction = UP elif (event.key == K_DOWN) and direction != UP: direction = DOWN elif event.key == K_ESCAPE: terminate() # check if the Snake has hit itself or the edge if wormCoords[HEAD]['x'] == -1 or wormCoords[HEAD]['x'] == Cell_W or wormCoords[HEAD]['y'] == -1 or wormCoords[HEAD]['y'] == Cell_H: return # game over for wormBody in wormCoords[1:]: if wormBody['x'] == wormCoords[HEAD]['x'] and wormBody['y'] == wormCoords[HEAD]['y']: return # game over # check if Snake has eaten an apply if wormCoords[HEAD]['x'] == apple['x'] and wormCoords[HEAD]['y'] == apple['y']: # don't remove worm's tail segment apple = getRandomLocation() # set a new apple somewhere else: del wormCoords[-1] # remove worm's tail segment # move the worm by adding a segment in the direction it is moving if direction == UP: newHead = {'x': wormCoords[HEAD]['x'], 'y': wormCoords[HEAD]['y'] - 1} elif direction == DOWN: newHead = {'x': wormCoords[HEAD]['x'], 'y': wormCoords[HEAD]['y'] + 1} elif direction == LEFT: newHead = {'x': wormCoords[HEAD][ 'x'] - 1, 'y': wormCoords[HEAD]['y']} elif direction == RIGHT: newHead = {'x': wormCoords[HEAD][ 'x'] + 1, 'y': wormCoords[HEAD]['y']} wormCoords.insert(0, newHead) DISPLAYSURF.fill(BGCOLOR) drawGrid() drawWorm(wormCoords) drawApple(apple) drawScore(len(wormCoords) - 3) pygame.display.update() SnakespeedCLOCK.tick(Snakespeed) def drawPressKeyMsg(): pressKeySurf = BASICFONT.render('Press a key to play.', True, White) pressKeyRect = pressKeySurf.get_rect() pressKeyRect.topleft = (Window_Width - 200, Window_Height - 30) DISPLAYSURF.blit(pressKeySurf, pressKeyRect) def checkForKeyPress(): if len(pygame.event.get(QUIT)) > 0: terminate() keyUpEvents = pygame.event.get(KEYUP) if len(keyUpEvents) == 0: return None if keyUpEvents[0].key == K_ESCAPE: terminate() return keyUpEvents[0].key def showStartScreen(): titleFont = pygame.font.Font('freesansbold.ttf', 100) titleSurf1 = titleFont.render('Snake!', True, White, DARKGreen) degrees1 = 0 degrees2 = 0 while True: DISPLAYSURF.fill(BGCOLOR) rotatedSurf1 = pygame.transform.rotate(titleSurf1, degrees1) rotatedRect1 = rotatedSurf1.get_rect() rotatedRect1.center = (Window_Width / 2, Window_Height / 2) DISPLAYSURF.blit(rotatedSurf1, rotatedRect1) drawPressKeyMsg() if checkForKeyPress(): pygame.event.get() # clear event queue return pygame.display.update() SnakespeedCLOCK.tick(Snakespeed) degrees1 += 3 # rotate by 3 degrees each frame degrees2 += 7 # rotate by 7 degrees each frame def terminate(): pygame.quit() sys.exit() def getRandomLocation(): return {'x': random.randint(0, Cell_W - 1), 'y': random.randint(0, Cell_H - 1)} def showGameOverScreen(): gameOverFont = pygame.font.Font('freesansbold.ttf', 100) gameSurf = gameOverFont.render('Game', True, White) overSurf = gameOverFont.render('Over', True, White) gameRect = gameSurf.get_rect() overRect = overSurf.get_rect() gameRect.midtop = (Window_Width / 2, 10) overRect.midtop = (Window_Width / 2, gameRect.height + 10 + 25) DISPLAYSURF.blit(gameSurf, gameRect) DISPLAYSURF.blit(overSurf, overRect) drawPressKeyMsg() pygame.display.update() pygame.time.wait(500) checkForKeyPress() # clear out any key presses in the event queue while True: if checkForKeyPress(): pygame.event.get() # clear event queue return def drawScore(score): scoreSurf = BASICFONT.render('Score: %s' % (score), True, White) scoreRect = scoreSurf.get_rect() scoreRect.topleft = (Window_Width - 120, 10) DISPLAYSURF.blit(scoreSurf, scoreRect) def drawWorm(wormCoords): for coord in wormCoords: x = coord['x'] * Cell_Size y = coord['y'] * Cell_Size wormSegmentRect = pygame.Rect(x, y, Cell_Size, Cell_Size) pygame.draw.rect(DISPLAYSURF, DARKGreen, wormSegmentRect) wormInnerSegmentRect = pygame.Rect( x + 4, y + 4, Cell_Size - 8, Cell_Size - 8) pygame.draw.rect(DISPLAYSURF, Green, wormInnerSegmentRect) def drawApple(coord): x = coord['x'] * Cell_Size y = coord['y'] * Cell_Size appleRect = pygame.Rect(x, y, Cell_Size, Cell_Size) pygame.draw.rect(DISPLAYSURF, Red, appleRect) def drawGrid(): for x in range(0, Window_Width, Cell_Size): # draw vertical lines pygame.draw.line(DISPLAYSURF, DARKGRAY, (x, 0), (x, Window_Height)) for y in range(0, Window_Height, Cell_Size): # draw horizontal lines pygame.draw.line(DISPLAYSURF, DARKGRAY, (0, y), (Window_Width, y)) if __name__ == '__main__': try: main() except SystemExit: pass
游戏效果:
三、关不掉的窗口
from tkinter import * class YouLikeMe: def __init__(self): window=Tk() label=Label(window,text='你是不是喜欢我?') self.btyes=Button(window,text='不是',height=1,width=6) self.btno=Button(window,text='是的',height=1,width=6) label.place(x=60,y=70) self.btyes.place(x=40,y=130) self.btno.place(x=120,y=130) self.btyes.bind('<Enter>',self.event1)#将按钮与鼠标事件绑定,<Enter>是指鼠标光标进入按钮区域 self.btno.bind('<Enter>',self.event2) window.mainloop() def event1(self,event):#切换按钮文字 self.btyes['text']='是的' self.btno['text']='不是' def event2(self,event): self.btyes['text']='不是' self.btno['text']='是的' YouLikeMe() window=Tk() label=Label(window,text='关闭窗口也改变不了你喜欢我的事实') label.place(x=2,y=80) button=Button(window,text='确定',command=window.destroy) button.place(x=80,y=150) window.mainloop()
游戏效果
四、画玫瑰花
import turtle import time turtle.speed(5) #画笔移动的速度 # 设置初始位置 turtle.penup() #提起画笔,移动画笔但并不会绘制图形 turtle.left(90) #逆时针转动画笔90度 turtle.fd(200) turtle.pendown() #放下画笔,移动画笔即开始绘制 turtle.right(90) #设置画笔的大小 turtle.pensize(2) # 花蕊 turtle.fillcolor("red") #填充颜色 turtle.begin_fill() #开始填充 turtle.circle(10,180) turtle.circle(25,110) turtle.left(50) turtle.circle(60,45) turtle.circle(20,170) turtle.right(24) turtle.fd(30) turtle.left(10) turtle.circle(30,110) turtle.fd(20) turtle.left(40) turtle.circle(90,70) turtle.circle(30,150) turtle.right(30) turtle.fd(15) turtle.circle(80,90) turtle.left(15) turtle.fd(45) turtle.right(165) turtle.fd(20) turtle.left(155) turtle.circle(150,80) turtle.left(50) turtle.circle(150,90) turtle.end_fill() #结束填充 # 花瓣1 turtle.left(150) turtle.circle(-90,70) turtle.left(20) turtle.circle(75,105) turtle.setheading(60) turtle.circle(80,98) turtle.circle(-90,40) # 花瓣2 turtle.left(180) turtle.circle(90,40) turtle.circle(-80,98) turtle.setheading(-83) # 叶子1 turtle.fd(30) turtle.left(90) turtle.fd(25) turtle.left(45) turtle.fillcolor("green") turtle.begin_fill() turtle.circle(-80,90) turtle.right(90) turtle.circle(-80,90) turtle.end_fill() turtle.right(135) turtle.fd(60) turtle.left(180) turtle.fd(85) turtle.left(90) turtle.fd(80) # 叶子2 turtle.right(90) turtle.right(45) turtle.fillcolor("green") turtle.begin_fill() turtle.circle(80,90) turtle.left(90) turtle.circle(80,90) turtle.end_fill() turtle.left(135) turtle.fd(60) turtle.left(180) turtle.fd(60) turtle.right(90) turtle.circle(200,50) #画一个圆 200 是半径,50 是弧度 #不让自动退出,放在程序的最后一行 #不然画画结束后会自动退出 turtle.done()
游戏效果:
五、优美的彩虹线条
import turtle q = turtle.Pen() turtle.bgcolor("black") sides = 7 colors =["red","orange","yellow","green","cyan","blue","blue","purple"] for x in range(360): q.pencolor(colors[x%sides]) q.forward(x*3/sides+x) q.left(360/sides+1) q.width(x*sides/200)
游戏效果:
六、实时钟表
# -*- coding:utf-8 –*- # 用turtlr画时钟 # 以自定义shape的方式实现 import turtle as t import datetime as d def skip(step): # 抬笔,跳到一个地方 t.penup() t.forward(step) t.pendown() def drawClock(radius): # 画表盘 t.speed(0) t.mode("logo") # 以Logo坐标、角度方式 t.hideturtle() t.pensize(7) t.home() # 回到圆点 for j in range(60): skip(radius) if (j % 5 == 0): t.forward(20) skip(-radius - 20) else: t.dot(5) skip(-radius) t.right(6) def makePoint(pointName, len): # 钟的指针,时针、分针、秒针 t.penup() t.home() t.begin_poly() t.back(0.1 * len) t.forward(len * 1.1) t.end_poly() poly = t.get_poly() t.register_shape(pointName, poly) # 注册为一个shape def drawPoint(): # 画指针 global hourPoint, minPoint, secPoint, fontWriter makePoint("hourPoint", 100) makePoint("minPoint", 120) makePoint("secPoint", 140) hourPoint = t.Pen() # 每个指针是一只新turtle hourPoint.shape("hourPoint") hourPoint.shapesize(1, 1, 6) minPoint = t.Pen() minPoint.shape("minPoint") minPoint.shapesize(1, 1, 4) secPoint = t.Pen() secPoint.shape("secPoint") secPoint.pencolor('red') fontWriter = t.Pen() fontWriter.pencolor('gray') fontWriter.hideturtle() def getWeekName(weekday): weekName = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'] return weekName[weekday] def getDate(year, month, day): return "%s-%s-%s" % (year, month, day) def realTime(): curr = d.datetime.now() curr_year = curr.year curr_month = curr.month curr_day = curr.day curr_hour = curr.hour curr_minute = curr.minute curr_second = curr.second curr_weekday = curr.weekday() t.tracer(False) secPoint.setheading(360 / 60 * curr_second) minPoint.setheading(360 / 60 * curr_minute) hourPoint.setheading(360 / 12 * curr_hour + 30 / 60 * curr_minute) fontWriter.clear() fontWriter.home() fontWriter.penup() fontWriter.forward(80) # 用turtle写文字 fontWriter.write(getWeekName(curr_weekday), align="center", font=("Courier", 14, "bold")) fontWriter.forward(-160) fontWriter.write(getDate(curr_year, curr_month, curr_day), align="center", font=("Courier", 14, "bold")) t.tracer(True) print(curr_second) t.ontimer(realTime, 100) # 每隔100毫秒调用一次realTime() def main(): t.tracer(False) drawClock(160) drawPoint() realTime() t.tracer(True) t.mainloop() if __name__ == '__main__': main()
游戏效果
七、画佩奇
# coding: utf-8 import turtle as t t.screensize(400, 300) t.pensize(4) # 设置画笔的大小 t.colormode(255) # 设置GBK颜色范围为0-255 t.color((255, 155, 192), "pink") # 设置画笔颜色和填充颜色(pink) t.setup(840, 500) # 设置主窗口的大小为840*500 t.speed(10) # 设置画笔速度为10 # 鼻子 t.pu() # 提笔 t.goto(-100, 100) # 画笔前往坐标(-100,100) t.pd() # 下笔 t.seth(-30) # 笔的角度为-30° t.begin_fill() # 外形填充的开始标志 a = 0.4 for i in range(120): if 0 <= i < 30 or 60 <= i < 90: a = a + 0.08 t.lt(3) # 向左转3度 t.fd(a) # 向前走a的步长 else: a = a - 0.08 t.lt(3) t.fd(a) t.end_fill() # 依据轮廓填充 t.pu() # 提笔 t.seth(90) # 笔的角度为90度 t.fd(25) # 向前移动25 t.seth(0) # 转换画笔的角度为0 t.fd(10) t.pd() t.pencolor(255, 155, 192) # 设置画笔颜色 t.seth(10) t.begin_fill() t.circle(5) # 画一个半径为5的圆 t.color(160, 82, 45) # 设置画笔和填充颜色 t.end_fill() t.pu() t.seth(0) t.fd(20) t.pd() t.pencolor(255, 155, 192) t.seth(10) t.begin_fill() t.circle(5) t.color(160, 82, 45) t.end_fill() # 头 t.color((255, 155, 192), "pink") t.pu() t.seth(90) t.fd(41) t.seth(0) t.fd(0) t.pd() t.begin_fill() t.seth(180) t.circle(300, -30) # 顺时针画一个半径为300,圆心角为30°的园 t.circle(100, -60) t.circle(80, -100) t.circle(150, -20) t.circle(60, -95) t.seth(161) t.circle(-300, 15) t.pu() t.goto(-100, 100) t.pd() t.seth(-30) a = 0.4 for i in range(60): if 0 <= i < 30 or 60 <= i < 90: a = a + 0.08 t.lt(3) # 向左转3度 t.fd(a) # 向前走a的步长 else: a = a - 0.08 t.lt(3) t.fd(a) t.end_fill() # 耳朵 t.color((255, 155, 192), "pink") t.pu() t.seth(90) t.fd(-7) t.seth(0) t.fd(70) t.pd() t.begin_fill() t.seth(100) t.circle(-50, 50) t.circle(-10, 120) t.circle(-50, 54) t.end_fill() t.pu() t.seth(90) t.fd(-12) t.seth(0) t.fd(30) t.pd() t.begin_fill() t.seth(100) t.circle(-50, 50) t.circle(-10, 120) t.circle(-50, 56) t.end_fill() # 眼睛 t.color((255, 155, 192), "white") t.pu() t.seth(90) t.fd(-20) t.seth(0) t.fd(-95) t.pd() t.begin_fill() t.circle(15) t.end_fill() t.color("black") t.pu() t.seth(90) t.fd(12) t.seth(0) t.fd(-3) t.pd() t.begin_fill() t.circle(3) t.end_fill() t.color((255, 155, 192), "white") t.pu() t.seth(90) t.fd(-25) t.seth(0) t.fd(40) t.pd() t.begin_fill() t.circle(15) t.end_fill() t.color("black") t.pu() t.seth(90) t.fd(12) t.seth(0) t.fd(-3) t.pd() t.begin_fill() t.circle(3) t.end_fill() # 腮 t.color((255, 155, 192)) t.pu() t.seth(90) t.fd(-95) t.seth(0) t.fd(65) t.pd() t.begin_fill() t.circle(30) t.end_fill() # 嘴 t.color(239, 69, 19) t.pu() t.seth(90) t.fd(15) t.seth(0) t.fd(-100) t.pd() t.seth(-80) t.circle(30, 40) t.circle(40, 80) # 身体 t.color("red", (255, 99, 71)) t.pu() t.seth(90) t.fd(-20) t.seth(0) t.fd(-78) t.pd() t.begin_fill() t.seth(-130) t.circle(100, 10) t.circle(300, 30) t.seth(0) t.fd(230) t.seth(90) t.circle(300, 30) t.circle(100, 3) t.color((255, 155, 192), (255, 100, 100)) t.seth(-135) t.circle(-80, 63) t.circle(-150, 24) t.end_fill() # 手 t.color((255, 155, 192)) t.pu() t.seth(90) t.fd(-40) t.seth(0) t.fd(-27) t.pd() t.seth(-160) t.circle(300, 15) t.pu() t.seth(90) t.fd(15) t.seth(0) t.fd(0) t.pd() t.seth(-10) t.circle(-20, 90) t.pu() t.seth(90) t.fd(30) t.seth(0) t.fd(237) t.pd() t.seth(-20) t.circle(-300, 15) t.pu() t.seth(90) t.fd(20) t.seth(0) t.fd(0) t.pd() t.seth(-170) t.circle(20, 90) # 脚 t.pensize(10) t.color((240, 128, 128)) t.pu() t.seth(90) t.fd(-75) t.seth(0) t.fd(-180) t.pd() t.seth(-90) t.fd(40) t.seth(-180) t.color("black") t.pensize(15) t.fd(20) t.pensize(10) t.color((240, 128, 128)) t.pu() t.seth(90) t.fd(40) t.seth(0) t.fd(90) t.pd() t.seth(-90) t.fd(40) t.seth(-180) t.color("black") t.pensize(15) t.fd(20) # 尾巴 t.pensize(4) t.color((255, 155, 192)) t.pu() t.seth(90) t.fd(70) t.seth(0) t.fd(95) t.pd() t.seth(0) t.circle(70, 20) t.circle(10, 330) t.circle(70, 30) t.done()
游戏效果
八、黑客代码雨
# -*- coding:utf-8 -*- #导入系统文件库 import pygame import random from pygame.locals import * from random import randint #定义一些窗体参数及加载字体文件 SCREEN_WIDTH = 900 # 窗体宽度 SCREEN_HEIGHT = 600 # 窗体宽度 LOW_SPEED = 4 # 字体移动最低速度 HIGH_SPEED = 10 # 字体移动最快速度 FONT_COLOR = (00,150,00) # 字体颜色 FONT_SIZE = 5 # 字体尺寸 FONT_NOM = 20 # 显示字体数量 从0开始 FONT_NAME = "calibrii.ttf" # 注意字体的文件名必须与真实文件完全相同(注意ttf的大小写),且文件名不能是中文 FREQUENCE = 10 # 时间频度 times = 0 # 初始化时间 # 定义随机参数 def randomspeed() : return randint(LOW_SPEED,HIGH_SPEED) def randomposition() : return randint(0,SCREEN_WIDTH),randint(0,SCREEN_HEIGHT) def randomoname() : return randint(0,100000) def randomvalue() : return randint(0,100) # this is your own display number range #class of sprite class Word(pygame.sprite.Sprite) : def __init__(self,bornposition) : pygame.sprite.Sprite.__init__(self) self.value = randomvalue() self.font = pygame.font.Font(None,FONT_SIZE) self.image = self.font.render(str(self.value),True,FONT_COLOR) self.speed = randomspeed() self.rect = self.image.get_rect() self.rect.topleft = bornposition def update(self) : self.rect = self.rect.move(0,self.speed) if self.rect.top > SCREEN_HEIGHT : self.kill() #init the available modules pygame.init() screen = pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT)) pygame.display.set_caption("ViatorSun CodeRain") clock = pygame.time.Clock() group = pygame.sprite.Group() group_count = int(SCREEN_WIDTH / FONT_NOM) #mainloop while True : time = clock.tick(FREQUENCE) for event in pygame.event.get() : if event.type == QUIT : pygame.quit() exit() screen.fill((0,0,0)) for i in range(0,group_count) : group.add(Word((i * FONT_NOM,-FONT_NOM))) group.update() group.draw(screen) pygame.display.update()
游戏效果