• Python


    目标

    • 背景交替滚动的思路确定
    • 显示游戏背景

    01,背景交替滚动的思路确定

    运行 备课代码,观察 背景图像的显示效果:

    • 游戏启动后,背景图像连续不断地 向下方 移动
    • 视觉上 产生英雄的飞机不断向上方飞行的 错觉 - - 在很多跑酷游戏中常用的套路
      • 游戏的背景 不断变化
      • 游戏的主角 位置保持不变

    1.1 实现思路分析

    解决方法
    1,创建两张背景图像精灵

    • 1完全和屏幕重合
    • 2 张在 屏幕的正上方

    2,两张图像 一起向下方运动

    • self.rect.y += self.speed

    3,当 任意背景精灵rect.y >= 屏幕的高度 说明已经 移动到屏幕下方
    4,将 移动到屏幕下方的这张图像 设置到 屏幕的正上方

    • rect.y = -rect.height

    1.2 设计背景类

    • 初始化方法

      • 直接指定 背景图片
      • is_alt 判断是否是另一张图像
        • False 表示 第一张图像,需要与屏幕适合
        • True 表示 另一张图像,在屏幕的正上方
    • update() 方法
      -判断 是否移动出屏幕,如果是,将图像设置到 屏幕的正上方,从而实现 交替滚动

    继承 如果是父类提供的方法,不能满足子类的需求:

    • 派生一个子类
    • 在子类中针对特有的需求,重写父类方法,并且进行扩展

    02,显示游戏背景

    2.1 背景精灵的基本实现

    • plane_sprites 新建 Background 继承自 GameSprite

    plane_sprites.py

    
    import pygame
    
    # 屏幕大小的常量
    SCREEN_RECT = pygame.Rect(0, 0, 480, 700)
    # 刷新的帧率
    FRAME_PER_SEC = 60
    class GameSprite(pygame.sprite.Sprite):
        """飞机大战游戏精灵"""
    
        def __init__(self, image_name, speed=1):
            # 调用父类的初始化方法
            super().__init__()
    
            # 定义对象的属性
            self.image = pygame.image.load(image_name)
            self.rect = self.image.get_rect()
            self.speed = speed
    
        def update(self, *args):
            # 在屏幕的垂直方向上移动
            self.rect.y += self.speed
    
    
    class Background(GameSprite):
        """游戏背景精灵"""
    
        def update(self, *args):
            # 1,调用父类的方法实现
            super().update()
    
            # 2,判断是否移除屏幕,如果移出屏幕,将图像设置到屏幕上方
            if self.rect.y >= SCREEN_RECT.height:
                self.rect.y = -self.rect.height
    
    

    2.2 在 plane_main.py 中显示背景精灵

    1,在 __create_sprites 方法中创建 精灵精灵组
    2,在 __update_sprites 方法中,让 精灵组 调用 update()draw() 方法
    __create_sprites 方法

        def __update_sprites(self):
            self.back_group.update()
            self.back_group.draw(self.screen)
    

    plane_main.py

    
    import pygame
    from Aircraft_War.plane_sprites import *
    
    class PlaneGame(object):
        """飞机大战主游戏"""
    
        def __init__(self):
            print("游戏初始化")
            # 1,创建游戏的窗口
            # self.screen = pygame.display.set_mode((480, 700))
            self.screen = pygame.display.set_mode(SCREEN_RECT.size)
    
            # 2,创建游戏的时钟
            self.clock = pygame.time.Clock()
    
            # 3,调用私有方法, 精灵和精灵组的创建
            self.__create_sprites()
    
        def __create_sprites(self):
            bg1 = Background("./images/background.png")
            bg2 = Background("./images/background.png")
            bg2.rect.y = -bg2.rect.height
    
            self.back_group = pygame.sprite.Group(bg1, bg2)
    
        def start_game(self):
            print("游戏开始...")
    
            while True:
                # 1,设置刷新帧率
                self.clock.tick(FRAME_PER_SEC)
    
                # 2,事件监听
                self.__event_handler()
    
                # 3,碰撞检测
                self.__check_collide()
    
                # 4,更新/绘制精灵组
                self.__update_sprites()
    
                # 5,更新显示
                pygame.display.update()
    
    
        def __event_handler(self):
    
            for event in pygame.event.get():
                # 判断是否退出游戏
                if event.type == pygame.QUIT:
                    PlaneGame.__game_over()
    
        def __check_collide(self):
            pass
    
        def __update_sprites(self):
            self.back_group.update()
            self.back_group.draw(self.screen)
    
        @staticmethod
        def __game_over():
            print("游戏结束")
    
            pygame.QUIT()
            exit()
    
    
    if __name__ == '__main__':
        # 创建游戏对象
        game = PlaneGame()
    
        # 启动游戏
        game.start_game()
    
    

    2.3 利用初始化方法,简化背景精灵创建

    思考 - - 上一小节完成的代码存在什么问题?是否可以简化?

    • 在主程序中,创建的 两个背景精灵,传入了相同的图像文件路径
    • 创建 第二个 背景精灵 时,在主程序中,设置背景精灵的图像位置

    思考 - - 精灵 初始位置 的设置,应该 由主程序负责? 还是 由精灵自己负责
    答案 - - 由精灵自己负责

    • 根据面向对象设计原则,应该将对象的职责,封装到类的代码内部
    • 尽量简化程序调用一方的代码调用

    • 初始化方法
      • 直接指定 背景图片
      • is_alt 判断是否是另一张图像
        • False 表示 第一张图像,需要与屏幕重合
        • True 表示 另一张图像,在屏幕的正上方

    plane_sprites.py 中实现 Background

    plane_sprites.py

    import pygame
    
    # 屏幕大小的常量
    SCREEN_RECT = pygame.Rect(0, 0, 480, 700)
    # 刷新的帧率
    FRAME_PER_SEC = 60
    class GameSprite(pygame.sprite.Sprite):
        """飞机大战游戏精灵"""
    
        def __init__(self, image_name, speed=1):
            # 调用父类的初始化方法
            super().__init__()
    
            # 定义对象的属性
            self.image = pygame.image.load(image_name)
            self.rect = self.image.get_rect()
            self.speed = speed
    
        def update(self, *args):
            # 在屏幕的垂直方向上移动
            self.rect.y += self.speed
    
    
    class Background(GameSprite):
        """游戏背景精灵"""
        def __init__(self, is_alt=False):
            # 1,调用父类方法实现精灵的创建(image/rect/speed)
            super().__init__("./images/background.png")
    
            # 2,判断是否交替图像,如果是,需要设置初始位置
            if is_alt:
                self.rect.y = -self.rect.height
    
        def update(self, *args):
            # 1,调用父类的方法实现
            super().update()
    
            # 2,判断是否移除屏幕,如果移出屏幕,将图像设置到屏幕上方
            if self.rect.y >= SCREEN_RECT.height:
                self.rect.y = -self.rect.height
    

    plane_main.py

    
    import pygame
    from Aircraft_War.plane_sprites import *
    
    class PlaneGame(object):
        """飞机大战主游戏"""
    
        def __init__(self):
            print("游戏初始化")
            # 1,创建游戏的窗口
            # self.screen = pygame.display.set_mode((480, 700))
            self.screen = pygame.display.set_mode(SCREEN_RECT.size)
    
            # 2,创建游戏的时钟
            self.clock = pygame.time.Clock()
    
            # 3,调用私有方法, 精灵和精灵组的创建
            self.__create_sprites()
    
        def __create_sprites(self):
            bg1 = Background()
            bg2 = Background(True)
    
            self.back_group = pygame.sprite.Group(bg1, bg2)
    
        def start_game(self):
            print("游戏开始...")
    
            while True:
                # 1,设置刷新帧率
                self.clock.tick(FRAME_PER_SEC)
    
                # 2,事件监听
                self.__event_handler()
    
                # 3,碰撞检测
                self.__check_collide()
    
                # 4,更新/绘制精灵组
                self.__update_sprites()
    
                # 5,更新显示
                pygame.display.update()
    
    
        def __event_handler(self):
    
            for event in pygame.event.get():
                # 判断是否退出游戏
                if event.type == pygame.QUIT:
                    PlaneGame.__game_over()
    
        def __check_collide(self):
            pass
    
        def __update_sprites(self):
            self.back_group.update()
            self.back_group.draw(self.screen)
    
        @staticmethod
        def __game_over():
            print("游戏结束")
    
            pygame.QUIT()
            exit()
    
    
    if __name__ == '__main__':
        # 创建游戏对象
        game = PlaneGame()
    
        # 启动游戏
        game.start_game()
    
    
  • 相关阅读:
    Java weak reference
    Java 代理模式
    Eclipse 代码自动提示
    Eclipse 设置默认编码为Utf-8
    MyBatis 作用域(Scope)和生命周期
    MyBatis 命名空间与命名解析
    Java 泛型 介绍
    【总结】过去的风口让很多人改变了阶层,我们90后的下一个风口会是什么?
    【前端】js截取or分割字符串的常见方法
    基于react/vue的移动端终极适配方案vw单位(更新css-modules配置)
  • 原文地址:https://www.cnblogs.com/xiaoqshuo/p/9568402.html
Copyright © 2020-2023  润新知