本程序要在python3环境下运行,是一个模仿游戏,敢不敢来应战?
#第一部分:常用初始内容
#Simulate(a Simon clone)
#By Al Sweigart al@inventwithpython.com
#http://inventwithpython.com/pygame
#Creative Commons BY-NC-SA 3.0 US
import random,sys,time,pygame
from pygame.locals import *
FPS=30
WINDOWWIDTH=640
WINDOWHEIGHT=480
FLASHSPEED=500 #毫秒
FLASHDELAY=200
BUTTONSIZE=200
BUTTONGAPSIZE=20 #按钮的间隙距离
TIMEOUT=4 #无按钮按下,4s后结束游戏
# R G B
WHITE= (255,255,255)
BLACK= ( 0, 0, 0)
BRIGHTRED= (255, 0, 0)
RED= (155, 0, 0)
BRIGHTGREEN= ( 0,255, 0)
GREEN= ( 0,155, 0)
BRIGHTBLUE= ( 0, 0,255)
BLUE= ( 0, 0,155)
BRIGHTYELLOW=(255,255, 0)
YELLOW= (155,155, 0)
DARKGRAY= ( 40, 40, 40)
bgColor=BLACK
XMARGIN=int((WINDOWWIDTH - (2 * BUTTONSIZE) - BUTTONGAPSIZE) / 2)
YMARGIN=int((WINDOWHEIGHT - (2 * BUTTONSIZE) - BUTTONGAPSIZE) / 2)
#第二部分:设置按钮
#四个按钮的矩阵对象
YELLOWRECT=pygame.Rect(XMARGIN,YMARGIN,BUTTONSIZE,BUTTONSIZE)
BLUERECT=pygame.Rect(XMARGIN+BUTTONSIZE+BUTTONGAPSIZE,YMARGIN,BUTTONSIZE,BUTTONSIZE)
REDRECT=pygame.Rect(XMARGIN,YMARGIN+BUTTONSIZE+BUTTONGAPSIZE,BUTTONSIZE,BUTTONSIZE)
GREENRECT=pygame.Rect(XMARGIN+BUTTONSIZE+BUTTONGAPSIZE,YMARGIN+BUTTONSIZE+BUTTONGAPSIZE,BUTTONSIZE,BUTTONSIZE)
#第三部分:main()函数
def main():
global FPSCLOCK,DISPLAYSURF,BASICFONT,BEEP1,BEEP2,BEEP3,BEEP4
pygame.init()
FPSCLOCK=pygame.time.Clock()#动画
DISPLAYSURF=pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT))
pygame.display.set_caption('Simulate')#游戏主题
BASICFONT=pygame.font.Font('freesansbold.ttf',16)#字体
infoSurf=BASICFONT.render('Match the pattern by clicking on the button or using the Q,W,A,S keys.',1,DARKGRAY)#提示信息的内容和位置
infoRect=infoSurf.get_rect()
infoRect.topleft=(10,WINDOWHEIGHT-25)
#下载声音文件
BEEP1=pygame.mixer.Sound('beep1.ogg')
BEEP2=pygame.mixer.Sound('beep2.ogg')
BEEP3=pygame.mixer.Sound('beep3.ogg')
BEEP4=pygame.mixer.Sound('beep4.ogg')
#第四部分:程序中用到的一些局部变量
pattern=[]#记录玩家必须点击的一串颜色
currentStep=0#记录玩家接下来一步必须点击的颜色
lastClickTime=0#记录玩家上一次点击的时间点
score=0#记录分数,包含两种模式:当waitingForInput=False时,程序为玩家播放按钮顺序;waitingForInput=True时,等待玩家以正确顺序点击按钮
waitingForInput=False
#第五部分:绘制游戏板并处理输入
while True:#主游戏循环
clickedButton=None#初始值为None,一旦按下按钮,就被赋值为YELLOW或RED或......
DISPLAYSURF.fill(bgColor)#重新绘制显示图
drawButtons()
scoreSurf=BASICFONT.render('Score:'+str(score),1,WHITE)#显示累加分数和位置
scoreRect=scoreSurf.get_rect()
scoreRect.topleft=(WINDOWWIDTH-100,10)
DISPLAYSURF.blit(scoreSurf,scoreRect)
DISPLAYSURF.blit(infoSurf,infoRect)
#第六部分:检查鼠标点击
checkForQuit()
for event in pygame.event.get():
if event.type==MOUSEBUTTONUP:
mousex,mousey=event.pos
clickedButton=getButtonClicked(mousex,mousey)#getButtonClicked函数返回点击坐标对应的颜色对象,否则返回None
#第七部分:检查键盘按下
elif event.type==KEYDOWN:
if event.key==K_q:
clickedButton=YELLOW
elif event.key==K_w:
clickedButton=BLUE
elif event.key==K_a:
clickedButton=RED
elif event.key==K_s:
clickedButton=GREEN
#第八部分:游戏循环的两种状态
if not waitingForInput:#开始时waitingForInput=False,程序为玩家播放按钮顺序
pygame.display.update()
pygame.time.wait(1000)
pattern.append(random.choice((YELLOW,BLUE,RED,GREEN)))
for button in pattern:
flashButtonAnimation(button)#点亮随机添加的按钮
pygame.time.wait(FLASHDELAY)#等待waitingForInput变为True
waitingForInput=True#等待玩家以正确顺序点击按钮,执行第九部分
#第九部分:搞清楚玩家是否按下了正确的按钮
else:
if clickedButton and clickedButton==pattern[currentStep]:#正确按下
flashButtonAnimation(clickedButton)#点亮一下玩家按下的按钮
currentStep+=1#currentStep变量记录玩家应该点击的下一按钮的索引
lastClickTime=time.time()#lastClickTime变量更新为当前时间
if currentStep==len(pattern):#一串按钮都点击正确
changeBackgroundAnimation()#修改背景颜色,提醒玩家成功进入下一轮
score+=1
waitingForInput=False
currentStep=0
elif (clickedButton and clickedButton!=pattern[currentStep])or(currentStep!=0 and time.time()-TIMEOUT>lastClickTime):#点错了或者该点超过4s却没点
gameOverAnimation()#播放游戏结束画面,一切恢复初值(分数也要清0),等待一会换个背景颜色
pattern=[]
currentStep=0
waitingForInput=False
score=0
pygame.time.wait(1000)
changeBackgroundAnimation()
#第十部分:将游戏板绘制到屏幕
pygame.display.update()
FPSCLOCK.tick(FPS)
#第十一部分:相同的旧的terminate()函数 ......这部分先不做解释
def terminate():
pygame.quit()
sys.exit()
def checkForQuit():
for event in pygame.event.get(QUIT):
terminate()
for event in pygame.event.get(KEYUP):
if event.key==K_ESCAPE:
terminate()
pygame.event.post(event)
#第十二部分:复用常量变量
def flashButtonAnimation(color,animationSpeed=50):
if color==YELLOW:#每个颜色参数对应的闪烁声音、闪烁颜色、闪烁矩形区域不同
sound=BEEP1
flashColor=BRIGHTYELLOW
rectangle=YELLOWRECT
elif color==BLUE:
sound=BEEP2
flashColor=BRIGHTBLUE
rectangle=BLUERECT
elif color==RED:
sound=BEEP3
flashColor=BRIGHTRED
rectangle=REDRECT
elif color==GREEN:
sound=BEEP4
flashColor=BRIGHTGREEN
rectangle=GREENRECT
#第十三部分:实现按钮闪烁动画
origSurf=DISPLAYSURF.copy()
flashSurf=pygame.Surface((BUTTONSIZE,BUTTONSIZE))#点亮按钮
flashSurf=flashSurf.convert_alpha()#通过设置alpha的值,控制按钮先逐渐变亮再逐渐变暗
r,g,b=flashColor
sound.play()
for start,end,step in ((0,255,1),(255,0,-1)):#两阶段:变亮阶段和变暗阶段
for alpha in range(start,end,animationSpeed*step):#针对上面两阶段将下列程序循环两次
checkForQuit()#QUIT事件防止用户试图在动画过程中关闭程序
DISPLAYSURF.blit(origSurf,(0,0))#将origSurfSurface复制到显示Surface ???
flashSurf.fill((r,g,b,alpha))#fill()绘制origSurfSurface,目的是提供r,g,b和alpha的值
DISPLAYSURF.blit(flashSurf,rectangle.topleft)#将origSurfSurface复制到显示Surface ???
pygame.display.update()#更新屏幕
FPSCLOCK.tick(FPS)#防止计算机过快播放,加短暂暂停
DISPLAYSURF.blit(origSurf,(0,0))#将origSurfSurface复制到显示Surface ???
#第十四部分:绘制按钮
def drawButtons():
pygame.draw.rect(DISPLAYSURF,YELLOW,YELLOWRECT)#将按钮显示到Surface
pygame.draw.rect(DISPLAYSURF,BLUE,BLUERECT)
pygame.draw.rect(DISPLAYSURF,RED,REDRECT)
pygame.draw.rect(DISPLAYSURF,GREEN,GREENRECT)
#第十五部分:实现背景颜色改变的动画
def changeBackgroundAnimation(animationSpeed=40):
global bgColor
newBgColor=(random.randint(0,255),random.randint(0,255),random.randint(0,255))
newBgSurf=pygame.Surface((WINDOWWIDTH,WINDOWHEIGHT))
newBgSurf=newBgSurf.convert_alpha()
r,g,b=newBgColor
for alpha in range(0,255,animationSpeed):
checkForQuit()
DISPLAYSURF.fill(bgColor)#旧的背景颜色填充Surface,存到DISPLAYSURF中
newBgSurf.fill((r,g,b,alpha))#使用新的背景颜色的r,g,b,alpha值
DISPLAYSURF.blit(newBgSurf,(0,0))#将新的背景颜色逐渐混合到旧的背景颜色中
drawButtons()#重新绘制按钮
pygame.display.update()#将Surface绘制到屏幕
FPSCLOCK.tick(FPS)
bgColor=newBgColor
#第十六部分:结束游戏画面
def gameOverAnimation(color=WHITE,animationSpeed=50):
#四种声音一起响,背景闪烁三次
origSurf=DISPLAYSURF.copy()
flashSurf=pygame.Surface(DISPLAYSURF.get_size())
flashSurf=flashSurf.convert_alpha()
BEEP1.play()
BEEP2.play()
BEEP3.play()
BEEP4.play()
r,g,b=color
for i in range(3):
for start,end,step in ((0,255,1),(255,0,-1)):
for alpha in range(start,end,animationSpeed*step):
checkForQuit()
DISPLAYSURF.blit(origSurf,(0,0))
flashSurf.fill((r,g,b,alpha))
DISPLAYSURF.blit(flashSurf,(0,0))
drawButtons()
pygame.display.update()
FPSCLOCK.tick(FPS)
#第十七部分:将像素坐标转换为按钮
def getButtonClicked(x,y):
if YELLOWRECT.collidepoint((x,y)):
return YELLOW
elif BLUERECT.collidepoint((x,y)):
return BLUE
elif REDRECT.collidepoint((x,y)):
return RED
elif GREENRECT.collidepoint((x,y)):
return GREEN
return None
if __name__=='__main__':
main()
别看游戏不难,十几轮、二十几轮下去,你还可以吗?