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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM