由于疫情的影响,两个孩子在家,天天在家都快翻天了。
计划中的学字母,但孩子总是兴趣不大。只能用游戏来吸引了。
似乎有两三年没用Python了,代码也就是能玩的程度,也没有太多优化之类。最初就是网友的一个打字游戏,在此基本上添加了一些音效、背景之类的东西。
No1
# -*- coding=utf-8 -*-
import pygame,time,random,datetime
from pygame.locals import *
#获取随机字符
def get_random_word():
color = (random.randint(0, 255),random.randint(0, 255),random.randint(0, 255)) # 颜色随机
x = random.randint(100, w-100) # x坐标从左右边距各100之间随机
y = 0
word = random.randint(65, 90)
return x,y,word,color
def Kill():
global PlayState,arr,plane,bullet,boom,Sound
#显示飞机
plane.update()
if PlayState==1:
plane.xto=arr[0][0]
if plane.over:
PlayState=2
bullet.over=False
Sound["fire"].play()
#显示子弹
if PlayState==2:
bullet.update(plane.x,arr[0][1])
if bullet.over:
PlayState=3
boom.over=False
Sound["bomb"].play()
#显示爆炸
if PlayState==3:
boom.update(arr[0][0],arr[0][1])
if boom.over:
arr.pop(0)
PlayState=0
#爆炸显示
class Boom(pygame.sprite.Sprite):
def __init__(self,screen):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.image.load("./res/boom.png").convert_alpha()
self.image.set_colorkey((0,0,0))
self.rect=self.image.get_rect()
self.num=0.1
self.local=[(214,46,234,68),(210,126,252,172),(214,2,254,44),(74,2,138,70),(2,2,72,66),(144,2,212,64),
(2,174,66,234),(144,66,208,128),(2,68,60,116),(64,68,124,114),(210,68,266,110)]
self.screen=screen
self.over=True
self.no=0.6
def update(self,lx,ly):
x1,y1,x2,y2 = self.local[int(self.num)]
x = (x2 - x1)/2
y = (y2 - y1)/2
self.screen.blit(self.image,(lx-x-20,ly-y+40),(x1,y1,x2,y2)) #显示爆炸图
self.num+=self.no
if self.num > 10:
self.num = 0.1
self.over = True
def uplevel(self):
self.no+=0.1
#子弹
class Bullet(pygame.sprite.Sprite):
def __init__(self,screen):
pygame.sprite.Sprite.__init__(self)
self.image=pygame.image.load("./res/bullet0.png").convert_alpha() #子弹
self.image.set_colorkey((255,255,255))
self.rect=self.image.get_rect()
self.screen=screen
self.x = 0
self.y = screen.get_height()-150
self.over = True
self.no = 0
def update(self,lx,ly): #lx,ly目标位置
self.x=lx
self.y-=(15+self.no)
if self.y>ly:
self.screen.blit(self.image,(self.x+10,self.y+60))
else:
self.over = True
self.y = screen.get_height()-150
def uplevel(self):
self.no+=1
#超过20关,应该添加一个终胜利显示
self.image=pygame.image.load("./res/bullet" + str(self.no) + ".png") #子弹
self.image.set_colorkey((255,255,255))
self.rect=self.image.get_rect()
#等级
class Level(pygame.sprite.Sprite):
def __init__(self,screen):
self.image=pygame.image.load("./res/gold.png").convert_alpha()
self.image.set_colorkey((255,255,255))
self.rect=self.image.get_rect()
self.screen=screen
self.level = 1
def update(self):
for i in range(0,self.level):
self.screen.blit(self.image,(i*20+10,10))
#背景
class Background(pygame.sprite.Sprite):
def __init__(self,screen):
self.level = 1
bg = pygame.image.load("./res/bg_level" + str(self.level) +".jpg").convert()
self.image = pygame.transform.scale2x(bg)
self.rect = self.image.get_rect()
self.screen = screen
self.bgy = 0
def uplevel(self):
self.level+=1
self.bgy=0
if self.level>7:
self.level = 1
bg=pygame.image.load("./res/bg_level" + str(self.level) +".jpg").convert()
#self.image= pygame.transform.scale(bg, (bg.get_width()*2, bg.get_height()*2))
self.image = pygame.transform.scale2x(bg)
self.rect=self.image.get_rect()
def get_width(self):
return self.image.get_width()
def get_height(self):
return self.image.get_height()
def image(self):
return self.image
def update(self):
self.bgy-=0.2
if -self.bgy>self.image.get_height()-screen.get_height(): #第一幅背景下方超出
screen.blit(self.image,(0,screen.get_height()+self.bgy+(self.image.get_height()-screen.get_height()))) #第二幅背景补齐
if self.bgy==-self.image.get_height(): #第一幅出背景
self.bgy=0
screen.blit(self.image,(0,self.bgy)) #正常情况下
#飞机
class Plane(pygame.sprite.Sprite):
def __init__(self,screen):
self.level = 1
self.image = pygame.image.load("./res/plane" + str(self.level) +".png")
self.rect = self.image.get_rect()
self.screen = screen
self.xto = 0
self.x = screen.get_width()/2-self.image.get_width()/2
self.over = True
def update(self):
if self.xto!=0:
if self.xto>self.x:
self.x+=(5+self.level)
elif abs(self.xto-self.x)<5+self.level:
self.over=True
self.xto=0
else:
self.x-=(5+self.level)
self.screen.blit(self.image,(self.x-20,screen.get_height()-self.image.get_height()-10))
def uplevel(self):
self.level += 1
if self.level > 5:
self.level = 5
self.image = pygame.image.load("./res/plane" + str(self.level) +".png")
self.rect=self.image.get_rect()
#星空
class Star(pygame.sprite.Sprite):
def __init__(self,screen,width,height):
self.image=pygame.image.load("./res/explode" + str(random.randint(1, 3))+ ".jpg").convert()
self.image.set_colorkey((0,0,0))
self.image.set_alpha(random.randint(100, 250))
self.rect=self.image.get_rect()
self.screen=screen
self.x=random.randint(10, width-10)
self.y=random.randint(10, height-10)
self.speed=random.random()/5
self.maxwidth=width
self.maxheight=height
def update(self):
self.y-=self.speed
if self.y<0:
self.x=random.randint(10, self.maxwidth-10)
self.y=self.maxheight+10
self.speed=random.random()/5
self.image=pygame.image.load("./res/explode" + str(random.randint(1, 3))+ ".jpg").convert()
self.image.set_colorkey((0,0,0))
self.image.set_alpha(random.randint(100, 250))
self.screen.blit(self.image,(self.x,self.y))
#初始化
w,h = 1024,1200
pygame.init()
pygame.mixer.init()
screen = pygame.display.set_mode((w, h), RESIZABLE)
clock = pygame.time.Clock()
pygame.display.set_caption(u'打字等级:1') #标题
#载入相关资源
myfont = pygame.font.Font("./res/ObelixPro.ttf",80) #字体设置
pygame.mixer.music.load("./res/start.ogg") #背景音乐
pygame.mixer.music.set_volume(0.4)
pygame.mixer.music.play(-1)
Sound = {}
jp = pygame.image.load("res/jp.jpg").convert() #键盘图
Sound["win"] = pygame.mixer.Sound("res/Completed.wav")
Sound["lost"] = pygame.mixer.Sound("res/Failed.wav")
Sound["fire"] = pygame.mixer.Sound("res/fire.wav")
Sound["bomb"] = pygame.mixer.Sound("res/bomb.wav")
for i in range(1,27): #载入字母音频
Sound[chr(i+96)] = pygame.mixer.Sound("res/" + chr(i+96) + ".wav")
#变量初始
fullscreen = False
diff_ticks = 100 #字母下落速度
LevelNum = 20 #30个字母升一级
ticks = pygame.time.get_ticks() + diff_ticks
word_diff_ticks = 5000
word_ticks = pygame.time.get_ticks() + word_diff_ticks
clear_word=0 #已消除多少字母
game_state=1 #1.进行中 2.游戏失败
sign=1 #字符闪烁
PlayState = 0
arr=[] #随机添加一个字符
arr.append(get_random_word())
showKey = False
boom = Boom(screen) #一个炸弹
bullet = Bullet(screen)
level = Level(screen)
bg = Background(screen)
plane = Plane(screen)
while True:
clock.tick(60) # 每秒循环60次
#按键捕获
for event in pygame.event.get():
#处理屏幕大小
if event.type == VIDEORESIZE:
w,h = event.size
screen = pygame.display.set_mode((w,h), RESIZABLE)
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == KEYDOWN:
if event.key == pygame.K_F1:
fullscreen=not fullscreen
if fullscreen:
screen=pygame.display.set_mode((w,h),FULLSCREEN)
else:
screen=pygame.display.set_mode((w,h),RESIZABLE)
if event.key == pygame.K_F2:
showKey = not showKey
if game_state==1 and len(arr)>0 and event.type == KEYDOWN:
if event.key==pygame.K_ESCAPE: #ESC退出
pygame.quit()
exit()
if event.key == arr[0][2]+32 and PlayState==0: #小写字母差32
Sound[chr(event.key)].play() #响应按键声音
clear_word += 1 #清除字母计数
PlayState = 1
plane.over=False
if clear_word >= level.level*LevelNum: #升级
level.level+=1
pygame.display.set_caption(u'打字等级:%d' % level.level)
diff_ticks=diff_ticks*0.9
word_diff_ticks=word_diff_ticks*0.95
Sound["win"].play()
bullet.uplevel() #子弹样式升级
boom.uplevel()
bg.uplevel()
plane.uplevel()
if 255-level.level*20>0: #每升一级,键盘表就暗一点
jp.set_alpha(255-level.level*20)
bg.update() #背景处理
if showKey:
screen.blit(jp,(w-jp.get_width()-10,h-jp.get_height()-10)) #绘制键盘图
level.update() #绘金币
#绘制字母
for i in range(len(arr)):
x, y, word, c = arr[i]
if i==0 and sign: #要闪烁字符
c = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
textImage = myfont.render(chr(word), True, c)
screen.blit(textImage, (x, y))
#游戏失败
if game_state == 2:
textImage = myfont.render(u"等级%d失败"%level.level, True, (255,0,0))
sw,sh = textImage.get_size()
screen.blit(textImage, ((w-sw)/2, (h-sh)/2)) # 居中显示
Sound["lost"].play()
time.sleep(5)
exit()
#游戏进行中
if game_state == 1:
if pygame.time.get_ticks()>=word_ticks: # 计时增加新字母
word_ticks +=word_diff_ticks
arr.append(get_random_word())
#移动字符
if pygame.time.get_ticks() >= ticks:
ticks += diff_ticks
sign=1-sign
for i in range(len(arr)):
x, y, word, c = arr[i]
arr[i] = (x, y+1, word, c)
if len(arr) > 0 and arr[0][1] > h: game_state=2
Kill()
pygame.display.update()
No2
增加了一个排行榜,增强学习动力。
可以调节游戏的难度(下落速度等)
游戏背景似乎还有点BUG,暂未处理。
好象附代码有点长,应该附上压缩包。