pygame面向对向版飞机大战

 

 源代码 

import random
import time

import pygame
import sys


# 音乐
class BGM:
    @staticmethod
    def besa_bgm():
        pygame.mixer.init()
        pygame.mixer.music.load("sound/y802.wav")
        pygame.mixer.music.set_volume(0.2)
        pygame.mixer.music.play(-1)

    @staticmethod
    def event_bgm(name):
        sound = pygame.mixer.Sound(name)
        pygame.mixer.music.set_volume(0.1)
        sound.play()


# 鼠标碰撞检测
class Util:
    @staticmethod
    def click_check(sprite):
        if pygame.mouse.get_pressed()[0]:
            if sprite.rect.collidepoint(pygame.mouse.get_pos()):
                return True
        return False


# 普通精灵
class BaseSprite(pygame.sprite.Sprite):
    def __init__(self, name):
        super().__init__()
        self.image = pygame.image.load(name)
        self.rect = self.image.get_rect()

    def update(self):
        pass


# 道具精灵
class PropSprite(BaseSprite):
    def __init__(self, name, type):
        super().__init__(name)
        self.type = type
        self.rect.left = random.randrange(0, 500 - self.rect.width)
        self.rect.bottom = 0

    def update(self):
        self.rect.centery += 5


class PropManage:
    def __init__(self, gm):
        self.gm = gm
        self.prop_group = pygame.sprite.Group()
        self.prop_time = 8

    def generator(self):
        value = random.random()
        # 子弹道具 加子弹速度
        if value > 0.8:
            self.prop = PropSprite("images/bullet_supply.png", 1)
            self.prop.add(self.prop_group)
        # # 变化子弹
        if value > 0.4:
            self.prop1 = PropSprite("images/bomb_supply.png", 2)
            self.prop1.add(self.prop_group)
        # 生命道具
        if value > 0.0:
            self.prop1 = PropSprite("images/enemy1.png", 3)
            self.prop1.add(self.prop_group)

    def clear(self):
        self.prop_group.empty()

    def update(self):
        self.prop_time -= 0.1
        if self.prop_time <= 0:
            self.prop_time = 8

            self.generator()
        self.prop_group.update()
        self.prop_group.draw(self.gm.screen)


# 子弹组
class BulletSprite(BaseSprite):
    def __init__(self, name, centerx, y, speed):
        super().__init__(name)
        self.rect.centerx = centerx
        self.rect.top = y
        self.speed = speed

    def update(self):
        self.rect.top += self.speed


# 敌人精灵
class EnemySprite(BaseSprite):
    def __init__(self, name, speed, gm, hp, type, speed2, names):
        super().__init__(name)
        self.gm = gm
        self.rect.left = random.randrange(0, 500 - self.rect.width)
        self.rect.bottom = 0
        # 飞机移动速度
        self.speed = speed
        self.move_line = random.choice([5, -5])
        self.hp = hp
        self.max_hp = hp
        self.type = type
        self.alive = True
        # 子弹速度
        self.speed2 = speed2
        self.shooter_time = self.speed2
        # 子弹组
        self.bullet_group = pygame.sprite.Group()
        # 死亡动画组
        self.images = [pygame.image.load(name_move) for name_move in names]
        self.image_index = 0

    def shooter(self):
        self.bullet = BulletSprite("images/bullet2.png", self.rect.centerx, self.rect.centery + 20, 20)
        self.bullet.add(self.bullet_group)

    def shooter1(self):
        for i in range(0, 3):
            self.bullet = BulletSprite("images/bullet2.png", self.rect.centerx - 20 + i * 20, self.rect.centery + 30,
                                       15)
            self.bullet.add(self.bullet_group)

    def shooter2(self):
        for i in range(0, 11):
            self.bullet = BulletSprite("images/bullet2.png", self.rect.centerx + i * 25 - 120,
                                       self.rect.centery + 80 + i * 10 if i < 6 else self.rect.centery + 180 - i * 10,
                                       8)
            self.bullet.add(self.bullet_group)

    def draw_hp(self):
        pygame.draw.rect(self.gm.screen, (127, 127, 127), (self.rect.left, self.rect.top - 20, self.rect.width, 5))
        pygame.draw.rect(self.gm.screen, (255, 0, 0),
                         (self.rect.left, self.rect.top - 20, self.hp / self.max_hp * self.rect.width, 5))

    def boom(self):
        self.image_index += 1
        if self.image_index < len(self.images) * 1:
            self.image = self.images[self.image_index // 1]
        else:
            self.kill()

    def update_image(self):
        if self.alive:
            pass
        else:
            self.boom()

    def update(self):
        self.draw_hp()
        self.update_image()

        self.rect.left += self.move_line
        if self.rect.left <= 0:
            self.move_line = 3
        if self.rect.right >= 500:
            self.move_line = -3

        self.rect.top += self.speed
        if self.rect.top > 700:
            self.kill()

        self.shooter_time -= 0.1
        if self.shooter_time <= 0:
            self.shooter_time = self.speed2
            if self.type == 1:
                self.shooter()
            if self.type == 2:
                self.shooter1()
            if self.type == 3:
                self.shooter2()

        self.bullet_group.update()
        self.bullet_group.draw(self.gm.screen)


class EnemyManage:
    def __init__(self, gm):
        self.gm = gm
        self.generator_time = 4
        self.enemy_group = pygame.sprite.Group()

        self.probability_time = 5
        self.i = 0

    def clear(self):
        self.enemy_group.empty()
        for es in self.enemy_group.sprites():
            for e in es:
                e.bullet_group.empty()

    def generator(self):
        self.probability_time -= 1
        if self.probability_time <= 0:
            self.probability_time = 5
            self.i += 2
        value = random.randint(0, 10 + self.i)
        if value > 0.0:
            self.enemy = EnemySprite("images/enemy1.png", 8, self.gm, 1, 1, 1.5,
                                     [f"images/enemy1_down{i}.png" for i in range(1, 5)])
            self.enemy.add(self.enemy_group)
        if value > 6:
            self.enemy1 = EnemySprite("images/enemy2.png", 5, self.gm, 5, 2, 5,
                                      [f"images/enemy2_down{i}.png" for i in range(1, 5)])
            self.enemy1.add(self.enemy_group)

        if value > 15:
            self.enemy2 = EnemySprite("images/enemy3_n1.png", 3, self.gm, 10, 3, 8,
                                      [f"images/enemy3_down{i}.png" for i in range(1, 7)])
            self.enemy2.add(self.enemy_group)
            BGM.event_bgm("sound/enemy3_flying.wav")

    def update(self):
        self.generator_time -= 0.1
        if self.generator_time <= 0:
            self.generator_time = 4
            self.generator()

        self.enemy_group.update()
        self.enemy_group.draw(self.gm.screen)


class PlayerSprite(BaseSprite):
    def __init__(self, name, center, gm, hp, names):
        super().__init__(name)
        self.gm = gm
        self.rect.center = center
        # 移动速度
        self.speed = 15
        self.max_hp = hp
        self.hp = hp
        # 初始攻速
        self.max_shoot = 2.5
        self.shoot_time = self.max_shoot
        # 超级子弹
        self.shoot1_time = 0
        # 子弹组
        self.bullet_group = pygame.sprite.Group()

        self.images = [pygame.image.load(name_move) for name_move in names]
        self.image_index = 0

    # 生成子弹
    def shoot(self):
        self.bullet = BulletSprite("images/bullet2.png", self.rect.centerx + 1, self.rect.top - 20, -15)
        self.bullet.add(self.bullet_group)

    def shoot1(self):
        for i in range(3):
            self.bullet1 = BulletSprite("images/ing.png", self.rect.centerx - 40 + 40 * (i - 1) + 40 * i,
                                        self.rect.top - 50, -15)
            self.bullet1.add(self.bullet_group)

    def draw_hp(self):

        pygame.draw.rect(self.gm.screen, (127, 127, 127), (self.rect.left, self.rect.top + 120, self.rect.width, 10))
        pygame.draw.rect(self.gm.screen, (0, 255, 0),
                         (self.rect.left, self.rect.top + 120, self.hp / self.max_hp * self.rect.width, 10))

    def update(self):

        key_all = pygame.key.get_pressed()
        self.draw_hp()
        self.image_index += 1
        if self.image_index == len(self.images) * 5:
            self.image_index = 0
        self.image = self.images[self.image_index // 5]

        self.shoot_time -= 0.3
        if self.shoot_time <= 0:
            self.shoot_time = self.max_shoot
            if self.shoot1_time > 0:
                self.shoot1_time -= 1
                if key_all[pygame.K_SPACE]:
                    BGM.event_bgm("sound/bullet.wav")
                    self.shoot1()
            else:
                if key_all[pygame.K_SPACE]:
                    BGM.event_bgm("sound/bullet.wav")
                    self.shoot()

        if key_all[pygame.K_LEFT] and self.rect.left > 0:
            self.rect.left -= self.speed
        if key_all[pygame.K_RIGHT] and self.rect.right < 500:
            self.rect.left += self.speed
        if key_all[pygame.K_UP] and self.rect.top > 0:
            self.rect.top -= self.speed
        if key_all[pygame.K_DOWN] and self.rect.bottom < 700:
            self.rect.top += self.speed

        self.bullet_group.draw(self.gm.screen)
        self.bullet_group.update()


class PlayerManage:
    def __init__(self, gm):
        self.gm = gm

        self.player_group = pygame.sprite.Group()
        self.player = PlayerSprite("images/me1.png", (250, 600), self.gm, 10, ["images/me1.png", "images/me2.png"])
        self.player.add(self.player_group)

    def bron(self):
        self.player = PlayerSprite("images/me1.png", (250, 600), self.gm, 10, ["images/me1.png", "images/me2.png"])
        self.player.add(self.player_group)

    def clear(self):
        self.player_group.empty()
        self.player.bullet_group.empty()

    def update(self):
        self.player_group.update()
        self.player_group.draw(self.gm.screen)


# 背景精灵
class BGSprite(BaseSprite):
    def __init__(self, name, top_left):
        super().__init__(name)
        self.rect.topleft = top_left

    def update(self):
        self.rect.top += 5
        if self.rect.top >= 700:
            self.rect.top = -700


# 背景管理
class BGManage:
    def __init__(self, gm):
        self.gm = gm
        self.bg_group = pygame.sprite.Group()
        self.bg = BGSprite("images/base.jpeg", (0, 0))
        self.bg.add(self.bg_group)
        self.bg2 = BGSprite("images/base.jpeg", (0, -700))
        self.bg2.add(self.bg_group)

    # 动
    def update(self):
        self.bg_group.update()
        self.bg_group.draw(self.gm.screen)


# ui精灵
class UISprite(BaseSprite):
    def __init__(self, name, center):
        super().__init__(name)
        self.rect.center = center

    def update(self):
        pass


# 游戏状态管理
class UIManage:
    def __init__(self, gm):
        self.gm = gm
        # 设置字体
        self.font = pygame.font.Font("font/font.ttf", 50)

        # 准备 精灵
        self.ready_group = pygame.sprite.Group()
        self.ready_btn = UISprite("images/1.png", (250, 400))
        self.ready_btn.add(self.ready_group)

        # 游戏中 显示分数
        self.surface = self.font.render(f"Score:{self.gm.score}", True, (255, 255, 200))

        self.surface2 = self.font.render(f"HP:{self.gm.player_manage.player.hp}", True, (255, 255, 200))
        # # 游戏中显示血量

        #  游戏结束
        self.end_group = pygame.sprite.Group()
        self.end_btn = UISprite("images/again.png", (250, 400))
        self.end_btn.add(self.end_group)

    # 游戏状态
    def update(self):
        if self.gm.state == "ready":
            BGM.besa_bgm()

            self.ready_group.draw(self.gm.screen)
            if Util.click_check(self.ready_btn):
                BGM.event_bgm("sound/click.mp3")
                self.gm.state = "gaming"
                self.gm.player_manage.bron()
        if self.gm.state == "gaming":
            self.gm.screen.blit(self.surface, (280, 30))
            self.gm.screen.blit(self.surface2, (280, 70))
            # # # # 显示血量
            # self.hp_draw_group.draw(self.gm.screen)

            self.surface = self.font.render(f"Score:{self.gm.score}", True, (255, 255, 200))
            self.surface2 = self.font.render(f"HP:{self.gm.player_manage.player.hp}", True, (255, 255, 200))

        if self.gm.state == "end":
            self.end_group.draw(self.gm.screen)
            self.gm.player_manage.clear()
            self.gm.enemy_manage.clear()
            self.gm.prop_manage.clear()
            self.gm.screen.blit(self.surface, (150, 250))
            self.surface = self.font.render(f"Score:{self.gm.score}", True, (255, 255, 200))
            if Util.click_check(self.end_btn):
                BGM.event_bgm("sound/click.mp3")
                self.gm.state = "gaming"
                self.gm.score = 0
                self.gm.player_manage.bron()


# 游戏主管理
class GameManage:
    def __init__(self):
        pygame.init()
        # 初始分值
        self.score = 0
        # 初始状态
        self.state = "ready"

        self.screen = pygame.display.set_mode((500, 700))
        pygame.display.set_caption("飞机大战")
        self.check = pygame.time.Clock()

        self.bg_manage = BGManage(self)
        self.player_manage = PlayerManage(self)
        self.enemy_manage = EnemyManage(self)
        self.prop_manage = PropManage(self)
        self.ui_manage = UIManage(self)

    def check_event(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

    # 碰撞检测
    def check_collider(self):
        # 玩家精灵的子弹组 与敌人组碰撞
        for player_sprite in self.player_manage.player_group.sprites():
            p_bullet_enemy = pygame.sprite.groupcollide(player_sprite.bullet_group, self.enemy_manage.enemy_group, True,
                                                        False)
            if p_bullet_enemy:
                for es in p_bullet_enemy.values():
                    for e in es:
                        e.hp -= 1
                        if e.hp <= 0:
                            if e.type == 1:
                                self.score += 1
                                BGM.event_bgm("sound/enemy1_down.wav")
                                e.alive = False

                            if e.type == 2:
                                e.alive = False
                                BGM.event_bgm("sound/enemy2_down.wav")
                                self.score += 5

                            if e.type == 3:
                                e.alive = False
                                BGM.event_bgm("sound/enemy3_down.wav")
                                self.score += 10

        # 玩家组与道具组
        prop_bullet = pygame.sprite.groupcollide(self.player_manage.player_group, self.prop_manage.prop_group, False,
                                                 True)
        if prop_bullet:
            for es in prop_bullet.values():
                for e in es:
                    if e.type == 1 and self.player_manage.player.max_shoot > 1.5:
                        BGM.event_bgm("sound/get_bullet.wav")
                        self.player_manage.player.max_shoot -= 0.5
                    if e.type == 2:
                        BGM.event_bgm("sound/get_bullet.wav")
                        self.player_manage.player.shoot1_time = 5

                    if e.type == 3 and self.player_manage.player.hp < self.player_manage.player.max_hp:
                        BGM.event_bgm("sound/get_bullet.wav")
                        self.player_manage.player.hp += 1
        # 先找到所有 敌人精灵 在找到所有敌人精灵的子弹组
        sprites = self.enemy_manage.enemy_group.sprites()
        for sprite in sprites:
            for player_sprite in self.player_manage.player_group.sprites():

                # 子弹组与子弹组碰撞
                if pygame.sprite.groupcollide(player_sprite.bullet_group, sprite.bullet_group, True, True):
                    pass
                # 玩家组 与敌人子弹
                enemy_bullet_p = pygame.sprite.groupcollide(sprite.bullet_group, self.player_manage.player_group, True,
                                                            False)
                if enemy_bullet_p:

                    for es in enemy_bullet_p.values():
                        for e in es:
                            e.hp -= 1
                            if e.hp <= 1:
                                BGM.event_bgm("sound/2643.wav")
                                e.kill()
                                self.state = "end"
                                print("玩家阵亡")
        # 玩家组与敌人组
        player_bullet_enemy = pygame.sprite.groupcollide(self.player_manage.player_group, self.enemy_manage.enemy_group,
                                                         True,
                                                         True)
        if player_bullet_enemy:
            BGM.event_bgm("sound/2643.wav")
            self.state = "end"

    def run(self):
        while True:
            self.check.tick(20)
            self.check_event()
            self.bg_manage.update()
            self.ui_manage.update()
            if self.state == "gaming":
                self.player_manage.update()
                self.enemy_manage.update()
                self.prop_manage.update()
                self.check_collider()

            pygame.display.flip()


gm = GameManage()
gm.run()

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值