pygame面向对象版本游戏制作

引言

        在本博客中,我们将探讨如何使用Pygame库来制作一个简单的2D射击游戏。通过这个示例,我们将学习如何使用面向对象的编程方法来构建游戏中的各种元素,包括玩家飞船、敌人、背景、音效等。      

基本结构

        首先,我们导入了需要的模块:randomsyspygame。接着定义了一个工具类Utils,其中包含了一些静态方法,用于实现点击检测。此外,我们还定义了一个音频管理类AudioManage,用于处理游戏中的声音效果。

import random, sys, pygame


class Utils:
    """
    提供一些静态方法
    """

    @staticmethod
    def click_check(sprite):
        if pygame.mouse.get_pressed()[0]:
            if sprite.rect.collidepoint(pygame.mouse.get_pos()):
                return True
        return False


class AudioManage:

    @staticmethod
    def start_music():
        pygame.mixer.music.load("sound/start.wav")
        pygame.mixer.music.play(loops=-1)

    @staticmethod
    def play_bg_music():
        pygame.mixer.music.load("sound/background.wav")
        pygame.mixer.music.play(loops=-1)

    @staticmethod
    def bullet(name):
        sound = pygame.mixer.Sound(name)
        channel = pygame.mixer.Channel(4)
        channel.play(sound)

    @staticmethod
    def killing(name):
        sound = pygame.mixer.Sound(name)
        channel = pygame.mixer.Channel(5)
        channel.play(sound)

  

游戏元素类

接下来,我们定义了一些游戏元素的类:

  • BaseSprite:这是所有精灵类的基类,包含了精灵的基本属性和方法。
  • EnemySprite:敌人飞船类,继承自BaseSprite,表示游戏中的敌人。
  • BulletSprite:子弹类,用于表示玩家飞船发射的子弹。
  • PlayerSprite:玩家飞船类,继承自BaseSprite,表示玩家操控的飞船。
    class BaseSprite(pygame.sprite.Sprite):
        def __init__(self, image_name):
            super().__init__()
            self.image = pygame.image.load(image_name)
            self.rect = self.image.get_rect()
    
    
    class EnemySprite(BaseSprite):
        def __init__(self, image_name, center):
            super().__init__(image_name)
            self.rect.center = center
    
    
    class BulletSprite(BaseSprite):
        def __init__(self, image_name, center):
            super().__init__(image_name)
            self.rect.center = center
    
        def update(self):
            self.rect.top -= 1
            if self.rect.bottom < 0:
                self.kill()
    
    
    class PlayerSprite(BaseSprite):
        def __init__(self, image_name, center):
            super().__init__(image_name)
            self.rect.center = center
            self.bullet_group = pygame.sprite.Group()
    
            self.bullet_gap = 5
    
        def shot(self):
            key_pressed = pygame.key.get_pressed()
            if key_pressed[pygame.K_SPACE]:
                self.bullet_gap -= 0.1
                if self.bullet_gap <= 0:
                    self.bullet_gap = 5
                    AudioManage.bullet("sound/bullet2.wav")
                    BulletSprite("img/bullet.png", (self.rect.centerx, self.rect.centery)).add(self.bullet_group)
                self.bullet_group.update()

管理类

然后,我们定义了一些管理类:

  • EnemyManage:管理敌人的生成、移动和碰撞检测等逻辑。
  • PlayerManage:管理玩家飞船的移动、射击和碰撞检测逻辑。
  • BGManage:管理游戏背景的移动和更新逻辑。
  • UIManage:管理游戏界面的显示和状态切换。

class EnemyManage:
    def __init__(self, gm):
        self.gm = gm
        self.init_enemy_num = 4

        # 生成敌人组
        self.enemy_group = pygame.sprite.Group()

        # 生成敌人计时器
        self.count_time = 10

    def generate_enemy(self):
        self.count_time -= 0.1
        if self.count_time <= 0:
            self.count_time = 10
            enemy = EnemySprite("img/enemy.png", ((random.randint(0, 736), 0)))
            enemy.add(self.enemy_group)

    def update(self):
        self.enemy_group.draw(self.gm.screen)
        self.generate_enemy()
        self.move()

    def move(self):
        for every_enemy in self.enemy_group.sprites():
            every_enemy.rect.top += 1
            if every_enemy.rect.bottom > 600:
                every_enemy.kill()


class PlayerManage:
    def __init__(self, gm):
        self.gm = gm
        self.player_group = pygame.sprite.Group()
        self.player = PlayerSprite("img/player.png", (400, 568))
        self.player.add(self.player_group)

    def player_move(self):
        keyword_pressed = pygame.key.get_pressed()
        if keyword_pressed[pygame.K_LEFT] and self.player.rect.left > 0:
            self.player.rect.left -= 5
        if keyword_pressed[pygame.K_RIGHT] and self.player.rect.right < 800:
            self.player.rect.left += 5
        if keyword_pressed[pygame.K_UP] and self.player.rect.top > 0:
            self.player.rect.top -= 5
        if keyword_pressed[pygame.K_DOWN] and self.player.rect.bottom < 600:
            self.player.rect.top += 5

    def is_kill(self):
        if pygame.sprite.groupcollide(self.player.bullet_group, self.gm.enemy_manage.enemy_group, True, True):
            AudioManage.killing("sound/explosion.wav")
            self.gm.score += 50
            return True
        return False

    def update(self):

        self.player_group.draw(self.gm.screen)
        self.player.add(self.player_group)
        self.player.shot()
        self.player_move()
        self.player.bullet_group.update()
        self.is_kill()
        self.player.bullet_group.draw(self.gm.screen)



class BGManage:
    def __init__(self, gm):
        self.gm = gm
        self.bg_group = pygame.sprite.Group()
        self.bg_image_1 = BGSprite("img/background.png", (0, 0))
        self.bg_image_2 = BGSprite("img/background.png", (0, -600))
        self.bg_image_1.add(self.bg_group)
        self.bg_image_2.add(self.bg_group)

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



class UIManage:
    def __init__(self, gm):
        self.gm = gm
        self.score_surface = self.gm.game_font.render(f"score:{self.gm.score}", True, "red")

        # 设置游戏开始组
        self.start_group = pygame.sprite.Group()
        self.start_button = UISprite("img/start_but.png", (400, 300))
        self.start_button.add(self.start_group)

        # 设置游戏结束组
        self.end_group = pygame.sprite.Group()
        self.restart_button = UISprite("img/restart_but.png", (400, 250))
        self.exit_button = UISprite("img/exit_but.png", (400, 350))
        self.exit_button.add(self.end_group)
        self.restart_button.add(self.end_group)

    def update(self, state):
        if state == "ready":
            self.start_group.draw(self.gm.screen)
            if Utils.click_check(self.start_button):
                AudioManage.play_bg_music()
                self.gm.player_manage.update()
                self.gm.state = "gaming"

        if state == "gaming":
            self.score_surface = self.gm.game_font.render(f"score:{self.gm.score}", True, "red")
            self.gm.screen.blit(self.score_surface, (0, 0))
            for i in self.gm.enemy_manage.enemy_group.sprites():
                if pygame.sprite.groupcollide(self.gm.enemy_manage.enemy_group, self.gm.player_manage.player_group,
                                              True, True):
                    AudioManage.killing("sound/isdead.wav")
            if not self.gm.player_manage.player_group:
                AudioManage.start_music()
                self.gm.state = "end"

        if state == "end":
            self.end_group.draw(self.gm.screen)
            if Utils.click_check(self.exit_button):
                pygame.quit()
                sys.exit()
            elif Utils.click_check(self.restart_button):
                self.gm.player_manage.player_group.empty()
                self.gm.enemy_manage.enemy_group.empty()
                self.end_group.empty()
                self.gm.score = 0
                self.gm.state = "gaming"
                AudioManage.play_bg_music()
                self.gm.player_manage = PlayerManage(self.gm)
                self.gm.enemy_manage = EnemyManage(self.gm)
                self.exit_button.add(self.end_group)
                self.restart_button.add(self.end_group)

游戏管理类

        最后,我们定义了GameManage类,该类负责游戏的初始化、运行和主循环。在主循环中,我们检测退出事件,然后根据游戏状态更新背景、界面以及各个元素的状态。

class GameManage:
    def __init__(self):
        # 初始化pygame
        pygame.init()
        # 游戏状态有三种:ready,gaming和end,初始化游戏状态为ready
        self.state = "ready"
        self.score = 0
        # 初始化背景音乐
        AudioManage.start_music()
        # 设置游戏图标
        self.icon = pygame.image.load("img/ufo.png")
        pygame.display.set_icon(self.icon)
        # 设置帧数
        self.clock = pygame.time.Clock()
        # 设置游戏字体
        self.game_font = pygame.font.Font("font/game.ttf", 30)
        # 初始化主屏幕
        self.screen = pygame.display.set_mode((800, 600))
        # 设置游戏窗口标题
        pygame.display.set_caption("AIR_WAR")
        # 导入UIManage类
        self.ui_manage = UIManage(self)
        # 导入BGManage类
        self.bg_manage = BGManage(self)
        # 导入PlayerManage类
        self.player_manage = PlayerManage(self)
        # 导入EnemyManage类
        self.enemy_manage = EnemyManage(self)

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

    def updating(self):
        self.bg_manage.update()
        self.player_manage.update()
        self.enemy_manage.update()

    # 定义运行函数
    def run(self):
        while True:
            self.exit_detect()
            # 设置主屏幕背景图
            self.bg_manage.update()
            self.ui_manage.update(self.state)
            if self.state == "gaming":
                self.updating()
                self.ui_manage.update("gaming")
            pygame.display.flip()

游戏展示

        接下来我们可以创建一个游戏类的实例来用于启动这个游戏

gm = GameManage()
gm.run()

图片展示

       

视频展示

AIR_WAR

结尾

        通过这段代码,我们展示了如何使用Pygame库和面向对象的编程方法来制作一个简单的2D射击游戏。每个类都有其独特的功能,通过组合它们,我们可以构建出一个完整的游戏。

附录

        最后,我会将这个项目上传到免费资源中,对这个项目感兴趣的读者可以进入我的个人主页进行获取,我也会将相关下载链接加入下方使读者方便获取可以在需要时进行获取并可以根据实际操作。

获取资源:可免费下载

https://download.csdn.net/download/qq_62278240/88209345icon-default.png?t=N6B9https://download.csdn.net/download/qq_62278240/88209345

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值