使用python中的pygame实现飞机大战(二)

使用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()



  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我可以帮你回答这个问题。首先需要安装pygame模块,可以在命令行输入 pip install pygame 进行安装。然后,使用下面的示例代码,可以实现一个基础版的飞机大战游戏: ``` import pygame import random # 初始化pygame pygame.init() # 设置游戏界面大小、背景颜色 screen_width = 480 screen_height = 700 bg_color = pygame.Color('gray') # 创建游戏窗口 screen = pygame.display.set_mode((screen_width, screen_height)) # 设置游戏标题 pygame.display.set_caption('飞机大战') # 加载背景图 bg = pygame.image.load('images/background.png') # 加载玩家飞机图片 player_img = pygame.image.load('images/player.png') player_rect = player_img.get_rect(center=(screen_width//2, screen_height-100)) # 加载子弹图片 bullet_img = pygame.image.load('images/bullet.png') # 加载敌机图片 enemy_img1 = pygame.image.load('images/enemy1.png') enemy_img2 = pygame.image.load('images/enemy2.png') enemy_img3 = pygame.image.load('images/enemy3.png') enemy_imgs = [enemy_img1, enemy_img2, enemy_img3] # 飞机、子弹及敌机列表 player = pygame.sprite.GroupSingle() player.add(pygame.sprite.Sprite()) player.sprite.image = player_img player.sprite.rect = player_rect bullets = pygame.sprite.Group() enemies = pygame.sprite.Group() # 创建敌机 for i in range(6): enemy = pygame.sprite.Sprite() enemy.image = random.choice(enemy_imgs) enemy.rect = enemy.image.get_rect( center=(random.randint(30, screen_width-30), random.randint(-100, -50))) enemies.add(enemy) # 设置帧率 clock = pygame.time.Clock() # 定义游戏循环 while True: # 事件检测 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit() # 玩家移动操作 keys = pygame.key.get_pressed() if keys[pygame.K_UP]: player.sprite.rect.move_ip(0, -5) if keys[pygame.K_DOWN]: player.sprite.rect.move_ip(0, 5) if keys[pygame.K_LEFT]: player.sprite.rect.move_ip(-5, 0) if keys[pygame.K_RIGHT]: player.sprite.rect.move_ip(5, 0) # 玩家边界限制 if player.sprite.rect.left <= 0: player.sprite.rect.left = 0 if player.sprite.rect.right >= screen_width: player.sprite.rect.right = screen_width if player.sprite.rect.top <= 0: player.sprite.rect.top = 0 if player.sprite.rect.bottom >= screen_height: player.sprite.rect.bottom = screen_height # 子弹发射操作 if keys[pygame.K_SPACE]: bullet = pygame.sprite.Sprite() bullet.image = bullet_img bullet.rect = bullet.image.get_rect(center=player.sprite.rect.midtop) bullets.add(bullet) # 子弹移动 for bullet in bullets: bullet.rect.move_ip(0, -5) if bullet.rect.bottom <= 0: bullets.remove(bullet) # 敌机移动 for enemy in enemies: enemy.rect.move_ip(0, 3) if enemy.rect.top >= screen_height: enemy.kill() enemy = pygame.sprite.Sprite() enemy.image = random.choice(enemy_imgs) enemy.rect = enemy.image.get_rect( center=(random.randint(30, screen_width-30), random.randint(-100, -50))) enemies.add(enemy) # 子弹击敌机 for enemy in pygame.sprite.groupcollide(enemies, bullets, True, True): enemy = pygame.sprite.Sprite() enemy.image = random.choice(enemy_imgs) enemy.rect = enemy.image.get_rect( center=(random.randint(30, screen_width-30), random.randint(-100, -50))) enemies.add(enemy) # 玩家与敌机碰撞检测 if pygame.sprite.spritecollide(player.sprite, enemies, True): pygame.quit() exit() # 游戏界面显示 screen.blit(bg, (0,0)) player.draw(screen) bullets.draw(screen) enemies.draw(screen) pygame.display.flip() # 设置帧率 clock.tick(60) ``` 希望以上代码对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苍旻之泪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值