一.经典的俄罗斯方块
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()
二、经典的贪吃蛇游戏
1.项目源码
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
预览效果:
三、关不掉的窗口
1.项目源码
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()
预览效果:
八、表白程序
from tkinter import * #_all_ = [a,b]
from tkinter import messagebox
from PIL import ImageTk
def closeWindow():
messagebox.showinfo(title="警告",message = "不许关闭,好好回答")
return
#点击喜欢触发的方法
def Love():
#Toplevel独立的顶级窗口,和父级标题一样
love = Toplevel(window)
love.geometry("360x200+540+360")
love.title("好巧,我也是")
label = Label(love,text="巧了,我也喜欢你",font =("微软雅黑",20))
label.pack()
label1 = Label(love,text="认识一下,加个微信呗",font =("微软雅黑",20))
label1.pack()
entry = Entry(love,font = ("微软雅黑",15))
entry.pack()
btn = Button(love,text = "确定",width = 10 , height = 1,command = close_all)
btn.pack()
love.protocol("WM_DELETe_WINDOW",closelove)
def closelove():
return
#关闭所有的窗口 注意,如果父级窗口关了,下面的所有窗口均会关闭
def close_all():
#destory 销毁
window.destroy()
#关闭不喜欢框的X时
def closenolove():
messagebox.showinfo("再考虑一下","再考虑一下呗")
return
disLove()
#点击不喜欢触发的事件
def disLove():
no_love = Toplevel(window)
no_love.geometry("300x90+540+360")
no_love.title("再考虑考虑")
label = Label(no_love,text = "再考虑考虑呗!",font = ("微软雅黑",25))
label.pack()
btn = Button(no_love,text = "好的",width = 10 , height = 1,command = no_love.destroy)
btn.pack()
no_love.protocol("WM_DELETE_WINDOW",closenolove)
# 创建窗口
window =Tk() #类的实例化,创建窗口,window仅仅是个变量
# 窗口标题
window.title("你喜欢我吗?")
# 窗口的大小 运用小写的x来连接
window.geometry("380x400")
#窗口位置(距离屏幕左上角) 运用+来连接
window.geometry("+500+240") # geometry意为几何
#上述可以写成window.geometry("380x200+500+245"),其中+是用来连接的
#用户关闭窗口触发的事件
window.protocol("WM_DELETE_WINDOW",closeWindow)
# 标签控件,一般第一个参数均是父级窗口 ,这里传参为window fg设置颜色
label = Label(window, text = "Hey,小姐姐", font = ("微软雅黑",15), fg="black")
# 定位 grid(网格式) pack(包的方式) place(用的最少的一种,根据位置)
label.grid(row=0,column =0) #默认值为 0 0
label_1 = Label(window,text = "喜欢我吗?",font = ("微软雅黑",25))
label_1.grid(row=1,column = 1,sticky = E) #sticky为对齐方式 N上S下W左E右
# 显示图片
photo = ImageTk.PhotoImage(file='Rose.jpg')
imageLable = Label(window,image = photo)
#column 组件所跨越的列数
imageLable.grid(row=2,columnspan =2) #跨列操作
# ques_image = ImageTk.PhotoImage(file='./Image/cache/{}'.format(image_name.group()))
#按钮控件 点击触发command事件
btn = Button(window,text="喜欢",width = 15,height=1,command = Love)
btn.grid(row = 3,column = 0,sticky = W)
btn1 =Button(window,text="不喜欢",command = disLove)
btn1 .grid(row = 3,column = 1,sticky = E)
#显示窗口 消息循环
window .mainloop()
预览效果:
上图的素材贴在这里啦
九、黑客代码雨
# -*- 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()
预览效果:
十、飞机大战游戏
在这里只展示部分代码,需要的可以下载
# 英雄子弹类
class HeroBullet(Bullet):
def __init__(self, screen, x, y):
super().__init__(screen, x, y)
def move(self):
self.y -= settings.bullet_hero_v
# 判断子弹是否出界
if self.y <= -20:
return True
# 敌机子弹类
class EnemyBullet(Bullet):
def __init__(self, screen, x, y):
super().__init__(screen, x, y)
def move(self):
self.y += settings.bullet_enemy_v
# 判断子弹是否出界
if self.y >= settings.screen_height:
return True
# 飞机基类
class Plane:
def __init__(self, screen, style, geo):
self.screen = screen
self.image = pygame.image.load(style)
self.bullet_list = []
self.x = geo[0]
self.y = geo[1]
self.is_dead = False
self.finished = False
self.bomb_seq = ['4','4','3','3','2','2','1','1']
def __del__(self):
pass
def display(self):
for b in self.bullet_list:
b.display()
# 回收子弹
if b.move(): self.bullet_list.remove(b)
# 爆炸效果
if self.is_dead:
death_x = self.x
death_y = self.y
death_w = self.image.get_width()
death_h = self.image.get_height()
try:
bomb_image = './images/bomb'+self.bomb_seq.pop()+'.png'
self.image = pygame.image.load(bomb_image)
except:
self.image = pygame.image.load('./images/bomb4.png')
self.finished = True
finally:
x = death_x + (death_w - self.image.get_width())/2
y = death_y + (death_h - self.image.get_height())/2
self.screen.blit(self.image, (x, y))
else:
# 重新绘制飞机
self.screen.blit(self.image, (self.x, self.y))
def fire(self):
self.bullet_list.append(Bullet(self.screen, self.x, self.y))
print(len(self.bullet_list))
def over(self):
#print("Oops: plane over ...")
#del self
return self.finished
# 英雄飞机
class HeroPlane(Plane):
def __init__(self, screen):
# 英雄机初始位置
geo = (200, 600)
super().__init__(screen, settings.hero_style, geo)
self.step = settings.move_step
# 英雄机移动范围
self.limit_left = -(self.image.get_width()/2)+10
self.limit_right = settings.screen_width-self.image.get_width()/2-10
self.limit_top = 5
self.limit_bottom = settings.screen_height-self.image.get_height()
def fire(self):
self.bullet_list.append(HeroBullet(self.screen, self.x+53, self.y))
def move_left(self):
if self.x <= self.limit_left:
pass
else:
self.x -= self.step
def move_right(self):
if self.x >= self.limit_right:
pass
else:
self.x += self.step
def move_up(self):
if self.y <= self.limit_top:
pass
else:
self.y -= self.step
def move_down(self):
if self.y >= self.limit_bottom:
pass
else:
self.y += self.step
预览效果:
后期我会把这个太空飞机大战的源码地址分享到这里,感谢各位支持!