使用python中的pygame实现飞机大战(二)
前言
接上篇
文章目录
3、指示器面板
(1)最高分加载、得分算法与暂停提示信息
"""game.py中"""
def run(self):
clock = py.time.Clock()
if self.pause == False:
print("游戏开始")
while True:
# 用尽生命
self.over = self.panel.lives == 0
if self.event_handler(): #键盘事件监听
return
if self.pause == True:
# print("游戏暂停")
self.panel.panel_paused(False,self.allgroup)
elif self.over == True:
# print("游戏结束")
self.panel.panel_paused(True,self.allgroup)
else:
# print("游戏进行中")
self.panel.panel_resume(self.allgroup)
self.panel.load_bestscore()
if self.panel.increase_score(10):
print("升级到%s"%self.panel.level)
self.allgroup.update()
# self.mainwindow.blit(self.backgroundimage,self.backgroundreact)
# self.mainwindow.blit(self.zhanjiimage,self.zhanjireact)
self.allgroup.draw(self.mainwindow)
py.display.update() #刷新界面
clock.tick(60)# 刷新率
"""tips.py中"""
import pygame as py
from 飞机大战.module import *
from 飞机大战.game import *
class Panel(object):
margin = 10 #间距
white = (255,255,255)
gray = (64,64,64)
screen = py.Rect(0, 0, 480, 700)
reward_score = 100000 #奖励生命相关
level2_score = 10000 #关卡2
level3_score = 50000 #关卡3
record_best = "best.txt"
def __init__(self,display_group):
self.score = 0 #得分
self.lives = 6 #命数
self.level = 1 #关卡
self.best_score = 0 #最佳分数
# 按钮
self.status_sprite = Button(("pause.png","resume.png"),display_group)
self.status_sprite.rect.topleft = (self.margin,self.margin)
self.bomb_sprite = GameSprite("bomb.png", 0, display_group) # 生命精灵
self.bomb_sprite.rect.bottomleft = (self.margin,self.screen.bottom-self.margin )
self.lives_sprite = GameSprite("life.png", 0, display_group) # 炸弹精灵
self.lives_sprite.rect.right = self.screen.right-6*self.margin
self.lives_sprite.rect.bottom = self.screen.bottom-self.margin
# bullet_sprite.rect.bottomleft = screen.bottomleft
# lives_sprite.rect.bottomright = screen.bottomright
# 图像精灵
# 标签
self.best_label = Label('Best score:%d'%self.best_score,36,self.white)
self.best_label.rect.center = self.screen.center
self.status_label = Label('Game pause',48,self.white)
self.status_label.rect.midbottom = (self.best_label.rect.centerx,
self.best_label.rect.y-2*self.margin)
self.c_score_label = Label('Current score:', 21, self.gray, display_group)
self.c_score_label.rect.right = self.screen.right - 2 * self.margin
self.c_score_label.rect.top = self.screen.top + 2 * self.margin
self.score_label = Label('%d'%self.score, 21, self.gray)
self.score_label.rect.right = self.screen.right - 2 * self.margin
self.score_label.rect.top = self.screen.top + 9*self.margin
self.bomb_label = Label('X 3', 32, self.gray,display_group)
self.bomb_label.rect.midleft = (self.bomb_sprite.rect.right + self.margin,
self.bomb_sprite.rect.centery)
self.lives_label = Label('X %d'%self.lives,32,self.gray,display_group)
self.lives_label.rect.midright = (self.screen.right-self.margin,
self.bomb_sprite.rect.centery)
# 提示标签
self.tips_label = Label('Press space to continue',22,self.white)
self.tips_label.rect.midtop = (self.best_label.rect.centerx,
self.best_label.rect.bottom + 8*self.margin)
def revise_bombs(self,count):
# 修改炸弹数量
self.bomb_label.set_text("X %d"%count)
self.bomb_label.rect.midleft = (self.bomb_sprite.rect.right + self.margin,
self.bomb_sprite.rect.centery)
def revise_lives(self):
# 修改生命数值
self.lives_label.set_text("X %d"%self.lives)
self.lives_label.rect.midright = (self.screen.right - self.margin,
self.bomb_sprite.rect.centery)
# 重新修正生命精灵的位置
self.lives_sprite.rect.right = self.lives_label.rect.x - self.margin
def revise_scores(self,score):
# 修改得分
self.score_label.set_text('Current score:%d'%score)
self.score_label.rect.right = self.screen.right - 2 * self.margin
self.score_label.rect.top = self.screen.top + 2 * self.margin
def increase_score(self,enemy_score):
# 分数 生命 关卡
# 计算得分
score = self.score + enemy_score
# 加命
if score // self.reward_score != self.score // self.reward_score:
self.lives += 1
self.revise_lives()
# 最好成绩
self.score = score
self.best_score = score if score > self.best_score else self.best_score
# 关卡等级
if self.score < self.level2_score:
level = 1
elif self.score < self.level3_score:
level = 2
else:
level = 3
is_update = level != self.level
self.level = level
# 得分更新
self.score_label.set_text('%d'%score)
self.score_label.rect.right = self.screen.right - 3 * self.margin
self.score_label.rect.top = self.screen.top + 5 * self.margin
return is_update
def save_bestscore(self):
f = open(self.record_best,"w")
f.write("%d"%self.best_score)
f.close()
def load_bestscore(self):
try:
f = open(self.record_best,"r")
result = f.read()
f.close()
self.best_score = int(result)
except (FileNotFoundError,ValueError):
print("Abnormal file loading!")
def panel_paused(self,is_game_over,display_group):
# 是否已经显示了提示信息
if display_group.has(self.best_label,self.status_label,self.tips_label):
return
# 由游戏状态提示相关信息
status = 'Game Over!'if is_game_over else 'Game Paused!'
tips = 'Press spacebar to'
tips += 'play again' if is_game_over else 'continue'
# 修改文本信息
self.best_label.set_text('Best score:%d'%self.best_score)
self.status_label.set_text(status)
self.tips_label.set_text(tips)
# 修正精灵位置
self.best_label.rect.center = self.screen.center
self.status_label.rect.midbottom = (self.best_label.rect.centerx,
self.best_label.rect.y - 2 * self.margin)
self.tips_label.rect.midtop = (self.best_label.rect.centerx,
self.best_label.rect.bottom + 8 * self.margin)
# 精灵添加到组
display_group.add(self.tips_label,self.best_label,self.status_label)
# 精灵添加到组状态修改
self.status_sprite.switch(True)
暂停提示信息:
(2)取消停止状态 隐藏提示信息
代码如下:
def panel_resume(self,display):
"""取消停止状态 隐藏提示信息"""
display.remove(self.status_label,self.best_label,self.tips_label)
self.status_sprite.switch(False)
效果:
(3)游戏结束时的重置数值与重置面板
代码如下:
"""生命减为零 game.py中的测试"""
if not self.pause and not self.over:
# 游戏期间释放炸弹
if event.type == py.KEYDOWN and event.key == py.K_b:
self.panel.revise_bombs(random.randint(1,66))
# self.panel.lives = random.randint(0,10)
# self.panel.revise_lives()
# self.panel.revise_scores(random.randint(1,100000))
self.panel.lives -= 1
self.panel.revise_lives()
"""tips.py中"""
def panel_reset(self):
# 重置面板
self.score = 0
self.lives = 6
# 重置炸弹、生命、得分、关卡数据
self.increase_score(0)
self.revise_bombs(3)
self.revise_lives()
"""game.py中"""
def reset(self):#游戏重置
self.pause = False
self.over = False
self.panel.panel_reset()
效果:不停按B键减少生命,达到over状态
游戏重置:
4.逐帧动画与飞机类
(1)飞机类初始化、飞机重置与状态更新
飞机类初始化
:
class Plane(GameSprite):
def __init__(self,plane_names,speed,hp,value,wav_names,hurt_images,destroy_images,*groups):
"""飞机类初始化"""
# 加载图片飞机
super(Plane, self).__init__(plane_names[0], speed, *groups)
# 飞机基本属性
self.hp = hp #当前生命值
self.max_hp = hp #初始化生命值
self.value = value #分值
self.wav_name = wav_names #音效
self.normal_images = [py.image.load(self.path + name)for name in plane_names]
# print(self.images)
self.normal_index = 0
self.hurt_images = py.image.load(self.path+hurt_images)
self.destroy_images = [py.image.load(self.path + name)for name in destroy_images]
self.destroy_index = 0 #摧毁索引
飞机重置
:
def reset_plane(self):
# 重置飞机
self.hp = self.max_hp
self.normal_index = 0
self.destroy_index = 0
self.image = self.normal_images[0]
飞机状态更新
:
def update(self, *args, **kwargs):
"""更新状态"""
if not args[0]:
return
if self.hp ==self.max_hp:
# 显示图片
self.image = self.normal_images[self.normal_index]
# 图片下次索引
count = len(self.normal_images)
self.normal_index = (self.normal_index + 1) % count
elif self.hp > 0:
# 受伤
self.image = self.hurt_images
else:
# 死亡时的图片加载
if self.destroy_index < len(self.destroy_images):
self.image = self.destroy_images[self.destroy_index]
self.destroy_index += 1
else:
self.reset_plane()
(2)敌机类初始化
class Enermy(Plane):
# 敌机
def __init__(self,kind,max_speed,*groups):
self.kind = kind
self.max_speed = max_speed
if kind == 0:
# 小敌机
super(Enermy, self).__init__(['enemy1.png'],1,1,1000,
'enemy1_down.wav','enemy1.png',
['enemy1_down%d.png'%i for i in range(1,5)],
*groups)
elif kind == 1:
# 中敌机
super(Enermy, self).__init__(['enemy2.png'], 1, 1, 1000,
'enemy2_down.wav', 'enemy2_hit.png',
['enemy2_down%d.png'%i for i in range(1, 5)],
*groups)
elif kind == 2:
# 大敌机
super(Enermy, self).__init__(['enemy3_n1.png'], 1, 15, 6000,
'enemy3_down.wav', 'enemy3_hit.png',
['enemy3_down%d.png'%i for i in range(1, 7)],
*groups)
重置敌机位置
:
def reset_plane(self):
# 重置敌机
super(Enermy, self).reset_plane()
x = random.randint(0,SCRENN_RECT.w - self.rect.w)
y = random.randint(0,SCRENN_RECT.h - self.rect.h)-SCRENN_RECT.h
self.rect.topleft = (x,y)
# 重置速度
self.speed = random.randint(1,self.max_speed)
更新敌机位置
:
def update(self, *args, **kwargs):
"""更新飞机位置"""
super(Enermy, self).update(*args)
# 由血量判断
if self.hp > 0:
self.rect.y += self.speed
# 屏幕外 飞机重置
if self.rect.y >= SCRENN_RECT.h:
self.reset_plane()
重置敌机
:
// An highlighted block
var foo = 'bar';
```## (2)敌机类初始化
```python
// An highlighted block
var foo = 'bar';
(3)英雄战机类
战机初始化
:
class Hero(Plane):
"""战机类"""
def __init__(self,*groups):
self.is_power = False # 是否无敌
self.bomb_count = HERO_BOMB_COUNT # 炸弹数
self.bullets_kind = 0 # 子弹类型单排
self.bullets_group = py.sprite.Group() # 子弹精灵组
super(Hero, self).__init__(('me1.png','me2.png'),5,1,0,
'me_down.wav','me1.png',
['me_destroy_%d.png'%i for i in range(1,5)],
*groups)
self.rect.midbottom = HERO_DEFAULT_BOTTOM # 位置
战机位置更新
:
def update(self, *args, **kwargs):
"""args的0下标是否更新下帧动画 1 水平基数 2垂直基数"""
super(Hero, self).update(*args)
if len(args) != 5 or self.hp <=0:
# 传的值个数 死亡
return
# 屏幕边缘位置修正
self.rect.x += args[1] * self.speed
self.rect.y += args[2] * self.speed
self.rect.x += args[3] * self.speed
self.rect.y += args[4] * self.speed
# 范围限定
self.rect.x = 0 if self.rect.x <=0 else self.rect.x
self.rect.right = SCRENN_RECT[2] if self.rect.right >= SCRENN_RECT[2] else self.rect.right
self.rect.y = 0 if self.rect.y <=0 else self.rect.y
self.rect.bottom = SCRENN_RECT[3] if self.rect.bottom >=SCRENN_RECT[3] else self.rect.bottom
炸弹炸毁敌机记分数
:
def blowup(self,enermies_group):
"""炸敌机 记分数"""
if self.bomb_count <= 0 or self.hp <= 0:
return 0
self.bomb_count -= 1
score = 0
count = 0
for enermy in enermies_group.sprites():
if enermy.rect.bottom > 0:
score += enermy.value
enermy.hp = 0
count += 1
print('炸毁敌机%d架,获取得分%d'%(count,score))
return score
创建敌机
:
def create_enermies(self):
# 创建敌机
count = len(self.enemiesgroup.sprites())
groups = (self.allgroup,self.enemiesgroup)
# 不同关卡创建不同敌机
if self.panel.level ==1 and count ==0:
for i in range(16):
Enermy(0,3,*groups)
elif self.panel.level ==2 and count ==16:
for enermy in self.enemiesgroup.sprites():
enermy.max_speed = 5
for i in range(8):
Enermy(0,5,*groups)
for i in range(2):
Enermy(1,1,*groups)
elif self.panel.level == 3 and count == 26:
for enermy in self.enemiesgroup.sprites():
enermy.max_speed = 7 if enermy.kind ==0 else 3
for i in range(8):
Enermy(0,7,*groups)
for i in range(2):
Enermy(1,3,*groups)
for i in range(2):
Enermy(2, 1, *groups)
效果:
完整代码
:
"""game.py"""
# 核心模块
import pygame as py
import random
from 飞机大战.module import *
from 飞机大战.music import *
from 飞机大战.tips import *
class Game(object):
def __init__(self):
# 游戏窗口初始化
self.screen = py.Rect(0, 0, 480, 700) # 游戏窗口
self.mainwindow = py.display.set_mode(self.screen.size)
py.display.set_caption("飞机大战")
# 游戏状态
self.pause = False
self.over = False
#游戏精灵组
self.allgroup = py.sprite.Group() #界面精灵组
self.enemiesgroup = py.sprite.Group() #敌机
self.propsgroup = py.sprite.Group() #道具
self.zhanjigroup = py.sprite.Group() #战机
# self.creatimage()
# 游戏精灵
# Background(True,self.allgroup) #背景精灵
# Background(False,self.allgroup) #背景精灵
self.allgroup.add(Background(True,self.allgroup),Background(False,self.allgroup))
#控制面板
self.panel = Panel(self.allgroup)
# enemies_sprite = GameSprite("enemy1.png",0,self.allgroup) #敌机精灵
self.zhanji_sprite = Hero(self.allgroup)
self.panel.revise_bombs(self.zhanji_sprite.bomb_count)
# enemies_sprite.rect.midtop = self.screen.midtop
# 初始化敌机
self.create_enermies()
def reset(self):#游戏重置
self.pause = False
self.over = False
self.panel.panel_reset()
def run(self):
clock = py.time.Clock()
if self.pause == False:
print("游戏开始")
frame_interval = 0
while True:
# 用尽生命
self.over = self.panel.lives == 0
if self.event_handler(): #键盘事件监听
return
if self.pause == True:
# print("游戏暂停")
self.panel.panel_paused(False,self.allgroup)
elif self.over == True:
# print("游戏结束")
self.panel.panel_paused(True,self.allgroup)
else:
# print("游戏进行中")
self.panel.panel_resume(self.allgroup)
self.panel.load_bestscore()
keys = py.key.get_pressed() #键盘元祖
move_hor = keys[py.K_RIGHT] - keys[py.K_LEFT] # 水平方向基数
move_hor1 = keys[py.K_d] - keys[py.K_a] # 水平方向基数
move_ver = keys[py.K_DOWN] - keys[py.K_UP] # 水平方向基数
move_ver1 = keys[py.K_s] - keys[py.K_w] # 水平方向基数
if self.panel.increase_score(100):
print("升级到%s"%self.panel.level)
self.create_enermies()
# self.zhanji_sprite.hp -= 10 # 战机爆炸测试
frame_interval = (frame_interval + 1)% FRAME_INTERVAL
self.allgroup.update(frame_interval == 0,move_hor,move_ver,move_hor1,move_ver1)
self.allgroup.draw(self.mainwindow)
py.display.update() #刷新界面
clock.tick(60)# 刷新率
def event_handler(self):
for event in py.event.get():
self.panel.save_bestscore()
if event.type == py.QUIT:#窗口叉叉退出
return True
elif event.type == py.KEYDOWN and event.key == py.K_ESCAPE: #ESC退出
return True
elif event.type == py.KEYDOWN and event.key == py.K_SPACE: #空格暂停与游戏重新开始
if self.over:
self.reset()
else:
self.pause = not self.pause
if not self.pause and not self.over:
# 游戏期间释放炸弹
if event.type == py.KEYDOWN and event.key == py.K_b:
score = self.zhanji_sprite.blowup(self.enemiesgroup)
self.panel.revise_bombs(self.zhanji_sprite.bomb_count)
if self.panel.increase_score(score):
self.create_enermies()
return False
def create_enermies(self):
# 创建敌机
count = len(self.enemiesgroup.sprites())
groups = (self.allgroup,self.enemiesgroup)
# 不同关卡创建不同敌机
if self.panel.level ==1 and count ==0:
for i in range(16):
Enermy(0,3,*groups)
elif self.panel.level ==2 and count ==16:
for enermy in self.enemiesgroup.sprites():
enermy.max_speed = 5
for i in range(8):
Enermy(0,5,*groups)
for i in range(2):
Enermy(1,1,*groups)
elif self.panel.level == 3 and count == 26:
for enermy in self.enemiesgroup.sprites():
enermy.max_speed = 7 if enermy.kind ==0 else 3
for i in range(8):
Enermy(0,7,*groups)
for i in range(2):
Enermy(1,3,*groups)
for i in range(2):
Enermy(2, 1, *groups)
if __name__ == '__main__':
game = Game()
game.run()
"""module.py"""
# 游戏模块
import pygame as py
import random
FRAME_INTERVAL = 20 # 逐帧动画显示间隔
SCRENN_RECT = py.Rect(0, 0, 480, 700)
HERO_BOMB_COUNT = 4
HERO_DEFAULT_BOTTOM = (SCRENN_RECT.centerx,
SCRENN_RECT.bottom - 90)
class GameSprite(py.sprite.Sprite):
path = "./static/images/"
def __init__(self,imagename,speed,*group):
#初始化精灵对象 调用父类方法把当前对象加入精灵组中
super(GameSprite, self).__init__(*group)
# 创建图片
self.image = py.image.load(self.path+imagename)
# 获取矩形
self.rect = self.image.get_rect()
# 设置速度
self.speed = speed
def update(self, *args, **kwargs):
"""更新元素数据"""
self.rect.y += self.speed
class Background(GameSprite):
def __init__(self,outside,*group):
super(Background, self).__init__("background.png",1,*group)
if outside:
self.rect.y = -self.rect.h
def update(self, *args, **kwargs):
super(Background, self).update(*args)
# 背景拼接
if self.rect.y > self.rect.h:
self.rect.y = -self.rect.y
class Button(GameSprite):
def __init__(self,image_names,*groups):
#image_names是元组,0暂停,1继续
super(Button, self).__init__(image_names[0],0,*groups)
self.images = [py.image.load(self.path + image) for image in image_names]
def switch(self,is_pause):
self.image = self.images[1 if is_pause else 0]
class Label(py.sprite.Sprite):
"""标签精灵类"""
font_path = './static/font/MarkerFelt.ttc'
def __init__(self,text,size,color,*groups):
super(Label, self).__init__(*groups)
# 字体
py.init()
self.font = py.font.Font(self.font_path,size)
self.color = color
self.image = self.font.render(text,True,self.color)
self.rect = self.image.get_rect()
def set_text(self,text):
"""设置文字"""
self.image = self.font.render(text, True, self.color)
self.rect = self.image.get_rect()
class Plane(GameSprite):
def __init__(self,plane_names,speed,hp,value,wav_names,hurt_images,destroy_images,*groups):
"""飞机类初始化"""
# 加载图片飞机
super(Plane, self).__init__(plane_names[0], speed, *groups)
# 飞机基本属性
self.hp = hp #当前生命值
self.max_hp = hp #初始化生命值
self.value = value #分值
self.wav_name = wav_names #音效
self.normal_images = [py.image.load(self.path + name)for name in plane_names]
# print(self.images)
self.normal_index = 0
self.hurt_images = py.image.load(self.path+hurt_images)
self.destroy_images = [py.image.load(self.path + name)for name in destroy_images]
self.destroy_index = 0 #摧毁索引
def reset_plane(self):
# 重置飞机
self.hp = self.max_hp
self.normal_index = 0
self.destroy_index = 0
self.image = self.normal_images[0]
def update(self, *args, **kwargs):
"""更新状态"""
if not args[0]:
return
if self.hp ==self.max_hp:
# 显示图片
self.image = self.normal_images[self.normal_index]
# 图片下次索引
count = len(self.normal_images)
self.normal_index = (self.normal_index + 1) % count
elif self.hp > 0:
# 受伤
self.image = self.hurt_images
else:
# 死亡时的图片加载
if self.destroy_index < len(self.destroy_images):
self.image = self.destroy_images[self.destroy_index]
self.destroy_index += 1
else:
self.reset_plane()
class Enermy(Plane):
# 敌机
def __init__(self,kind,max_speed,*groups):
self.kind = kind
self.max_speed = max_speed
if kind == 0:
# 小敌机
super(Enermy, self).__init__(['enemy1.png'],1,1,1000,
'enemy1_down.wav','enemy1.png',
['enemy1_down%d.png'%i for i in range(1,5)],
*groups)
elif kind == 1:
# 中敌机
super(Enermy, self).__init__(['enemy2.png'], 1, 1, 1000,
'enemy2_down.wav', 'enemy2_hit.png',
['enemy2_down%d.png'%i for i in range(1, 5)],
*groups)
elif kind == 2:
# 大敌机
super(Enermy, self).__init__(['enemy3_n1.png'], 1, 15, 6000,
'enemy3_down.wav', 'enemy3_hit.png',
['enemy3_down%d.png'%i for i in range(1, 7)],
*groups)
def reset_plane(self):
# 重置敌机
super(Enermy, self).reset_plane()
x = random.randint(0,SCRENN_RECT.w - self.rect.w)
y = random.randint(0,SCRENN_RECT.h - self.rect.h)-SCRENN_RECT.h
self.rect.topleft = (x,y)
# 重置速度
self.speed = random.randint(1,self.max_speed)
def update(self, *args, **kwargs):
"""更新飞机位置"""
super(Enermy, self).update(*args)
# 由血量移动
if self.hp > 0:
self.rect.y += self.speed
# 屏幕外 飞机重置
if self.rect.y >= SCRENN_RECT.h:
self.reset_plane()
class Hero(Plane):
"""战机类"""
def __init__(self,*groups):
self.is_power = False # 是否无敌
self.bomb_count = HERO_BOMB_COUNT # 炸弹数
self.bullets_kind = 0 # 子弹类型单排
self.bullets_group = py.sprite.Group() # 子弹精灵组
super(Hero, self).__init__(('me1.png','me2.png'),5,1,0,
'me_down.wav','me1.png',
['me_destroy_%d.png'%i for i in range(1,5)],
*groups)
self.rect.midbottom = HERO_DEFAULT_BOTTOM # 位置
def update(self, *args, **kwargs):
"""args的0下标是否更新下帧动画 1 水平基数 2垂直基数"""
super(Hero, self).update(*args)
if len(args) != 5 or self.hp <=0:
# 传的值个数 死亡
return
# 屏幕边缘位置修正
self.rect.x += args[1] * self.speed
self.rect.y += args[2] * self.speed
self.rect.x += args[3] * self.speed
self.rect.y += args[4] * self.speed
# 范围限定
self.rect.x = 0 if self.rect.x <=0 else self.rect.x
self.rect.right = SCRENN_RECT[2] if self.rect.right >= SCRENN_RECT[2] else self.rect.right
self.rect.y = 0 if self.rect.y <=0 else self.rect.y
self.rect.bottom = SCRENN_RECT[3] if self.rect.bottom >=SCRENN_RECT[3] else self.rect.bottom
def blowup(self,enermies_group):
"""炸敌机 记分数"""
if self.bomb_count <= 0 or self.hp <= 0:
return 0
self.bomb_count -= 1
score = 0
count = 0
for enermy in enermies_group.sprites():
if enermy.rect.bottom > 0:
score += enermy.value
enermy.hp = 0
count += 1
print('炸毁敌机%d架,获取得分%d'%(count,score))
return score
"""tips.py"""
# 提示信息
import pygame as py
from 飞机大战.module import *
from 飞机大战.game import *
class Panel(object):
margin = 10 #间距
white = (255,255,255)
gray = (64,64,64)
screen = py.Rect(0, 0, 480, 700)
reward_score = 100000 #奖励生命相关
level2_score = 10000 #关卡2
level3_score = 50000 #关卡3
record_best = "best.txt"
def __init__(self,display_group):
self.score = 0 #得分
self.lives = 6 #命数
self.level = 1 #关卡
self.best_score = 0 #最佳分数
# 按钮
self.status_sprite = Button(("pause.png","resume.png"),display_group)
self.status_sprite.rect.topleft = (self.margin,self.margin)
self.bomb_sprite = GameSprite("bomb.png", 0, display_group) # 炸弹精灵
self.bomb_sprite.rect.bottomleft = (self.margin,self.screen.bottom-self.margin )
self.lives_sprite = GameSprite("life.png", 0, display_group) # 生命精灵
self.lives_sprite.rect.right = self.screen.right-6*self.margin
self.lives_sprite.rect.bottom = self.screen.bottom-self.margin
# bullet_sprite.rect.bottomleft = screen.bottomleft
# lives_sprite.rect.bottomright = screen.bottomright
# 图像精灵
# 标签
self.best_label = Label('Best score:%d'%self.best_score,36,self.white)
self.best_label.rect.center = self.screen.center
self.status_label = Label('Game pause',48,self.white)
self.status_label.rect.midbottom = (self.best_label.rect.centerx,
self.best_label.rect.y-2*self.margin)
self.c_score_label = Label('Current score:', 21, self.gray, display_group)
self.c_score_label.rect.right = self.screen.right - 2 * self.margin
self.c_score_label.rect.top = self.screen.top + 2 * self.margin
self.score_label = Label('%d'%self.score, 21, self.gray, display_group)
self.score_label.rect.right = self.screen.right - 2 * self.margin
self.score_label.rect.top = self.screen.top + 9*self.margin
self.bomb_label = Label('X 3', 32, self.gray,display_group)
self.bomb_label.rect.midleft = (self.bomb_sprite.rect.right + self.margin,
self.bomb_sprite.rect.centery)
self.lives_label = Label('X %d'%self.lives,32,self.gray,display_group)
self.lives_label.rect.midright = (self.screen.right-self.margin,
self.bomb_sprite.rect.centery)
# 提示标签
self.tips_label = Label('Press space to continue',22,self.white)
self.tips_label.rect.midtop = (self.best_label.rect.centerx,
self.best_label.rect.bottom + 8*self.margin)
def revise_bombs(self,count):
# 修改炸弹数量
self.bomb_label.set_text("X %d"%count)
self.bomb_label.rect.midleft = (self.bomb_sprite.rect.right + self.margin,
self.bomb_sprite.rect.centery)
def revise_lives(self):
# 修改生命数值
self.lives_label.set_text("X %d"%self.lives)
self.lives_label.rect.midright = (self.screen.right - self.margin,
self.bomb_sprite.rect.centery)
# 重新修正生命精灵的位置
self.lives_sprite.rect.right = self.lives_label.rect.x - self.margin
def revise_scores(self,score):
# 修改得分
self.score_label.set_text('Current score:%d'%score)
self.score_label.rect.right = self.screen.right - 2 * self.margin
self.score_label.rect.top = self.screen.top + 2 * self.margin
def increase_score(self,enemy_score):
# 分数 生命 关卡
# 计算得分
score = self.score + enemy_score
# 加命
if score // self.reward_score != self.score // self.reward_score:
self.lives += 1
self.revise_lives()
# 最好成绩
self.score = score
self.best_score = score if score > self.best_score else self.best_score
# 关卡等级
if self.score < self.level2_score:
level = 1
elif self.score < self.level3_score:
level = 2
else:
level = 3
is_update = level != self.level
self.level = level
# 得分更新
self.score_label.set_text('%d'%score)
self.score_label.rect.right = self.screen.right - 3 * self.margin
self.score_label.rect.top = self.screen.top + 5 * self.margin
return is_update
def save_bestscore(self):
f = open(self.record_best,"w")
f.write("%d"%self.best_score)
f.close()
def load_bestscore(self):
try:
f = open(self.record_best,"r")
result = f.read()
f.close()
self.best_score = int(result)
except (FileNotFoundError,ValueError):
print("Abnormal file loading!")
def panel_paused(self,is_game_over,display_group):
# 是否已经显示了提示信息
if display_group.has(self.best_label,self.status_label,self.tips_label):
return
# 由游戏状态提示相关信息
status = 'Game Over!'if is_game_over else 'Game Paused!'
tips = 'Press spacebar to '
tips += 'play again' if is_game_over else 'continue'
# 修改文本信息
self.best_label.set_text('Best score:%d'%self.best_score)
self.status_label.set_text(status)
self.tips_label.set_text(tips)
# 修正精灵位置
self.best_label.rect.center = self.screen.center
self.status_label.rect.midbottom = (self.best_label.rect.centerx,
self.best_label.rect.y - 2 * self.margin)
self.tips_label.rect.midtop = (self.best_label.rect.centerx,
self.best_label.rect.bottom + 8 * self.margin)
# 标签添加到组
display_group.add(self.tips_label,self.best_label,self.status_label)
# 精灵添加到组状态修改
self.status_sprite.switch(True)
def panel_resume(self,display):
"""取消停止状态 隐藏提示信息"""
display.remove(self.status_label,self.best_label,self.tips_label)
self.status_sprite.switch(False)
def panel_reset(self):
# 重置面板
self.score = 0
self.lives = 6
# 重置炸弹、生命、得分、关卡数据
self.increase_score(0)
self.revise_bombs(3)
self.revise_lives()