Python 项目:外星人入侵----第一部分
阅读原文时间:2023年07月05日阅读:1

外星人入侵

玩家控制着一艘最初出现在屏幕底部中央的飞船,玩家可以使用箭头键左右移动飞船,还可以使用空格键进行射击,游戏开始时,一群外星人出现在天空中,他们在屏幕中下移动。玩家任务是射杀这些外星人。玩家将所有外星人都消灭干净后,将出现一群新的外星人,他们移动的速度更快。只要有外星人玩家的飞船或到达了屏幕底部,玩家就损失一艘飞船。玩家损失三艘飞船后,游戏结束。

使用pip安装pygame包

  • Linux系统安装
  • OSX系统中安装
  • Windows系统中安装

3.1 创建Pygame窗口以及响应用户输入

  • 导入模块sys和pygame,模块pygame包含开发游戏所需的功能,使用模块sys来退出游戏

  • pygame.init()来初始化背景设置

  • pygame.display.set_mode()来创建一个名为screen的显示窗口,实参(1200,800)是一个元组,指定了游戏窗口的尺寸大小。

  • 对象screen是一个surface(是屏幕的一部分),用于显示游戏元素,每个元素都是一个surface如外星人或飞船

  • pygame.display.set_palette()设置当前窗口的标题栏

  • while循环,包含一个事件循环以及管理屏幕更新代码

  • 访问pygame检测到的事件,使用方法pygame.event.get(),从队列中获取事件,所有键盘和鼠标事件都使用for循环运行。用if语句来检测或响应特定事件。

  • 退出时调用sys.exit()来退出游戏

  • 调用pygame.display.flip(),命令pygame让最近绘制的屏幕可见,不断更新屏幕,以显示元素的新位置,并在原来的位置影藏元素,从而营造平滑移动的效果。简而言之更新整个待显示的 Surface 对象到屏幕上。

    模块sys用于退出游戏

    import sys
    import pygame
    def run_game():
    '''初始化游戏并创建一个屏幕对象'''
    # 初始化背景设置
    pygame.init()
    screen = pygame.display.set_mode((1200,800)) #实参(1200,800)是一个元组,指定了游戏窗口的尺寸
    pygame.display.set_caption("小子,你愁啥啊")

    '''开始游戏的主循环'''
    while True:
        '''监视键盘和鼠标事件'''
        for event in pygame.event.get():
            if event.type ==pygame.QUIT:
                sys.exit()
        pygame.display.flip()

    run_game()

运行:

3.2 设置背景色

  • 创建一个颜色,存储到变量中。

  • 调用screen.fill用背景色填充屏幕,这个方法只接受一个实参:一种颜色

  • 再pygame中,颜色是以RGB指定的,由红、绿、蓝组成的,每个值取值范围为:0~255,通过组合,可创建1600万种颜色。

    模块sys用于退出游戏

    import sys
    import pygame
    def run_game():
    '''初始化游戏并创建一个屏幕对象'''
    # 初始化背景设置
    pygame.init()
    screen = pygame.display.set_mode((1200,800)) #实参(1200,800)是一个元组,指定了游戏窗口的尺寸
    pygame.display.set_caption("小子,你愁啥啊")
    #设置背景色
    '''参数:红、绿、蓝,颜色是以RGB指定的,范围:0~255'''
    color = (0,0,255)

    '''开始游戏的主循环'''
    while True:
        '''监视键盘和鼠标事件'''
        for event in pygame.event.get():
            if event.type ==pygame.QUIT:
                sys.exit()
        '''每次循环时都重绘屏幕'''
        #调用方法screen.fill()用背景色填充屏幕,这个方法只接受一个实参:一种颜色
        screen.fill(color)
        '''让最近绘制的屏幕可见'''
        pygame.display.flip()

    run_game()

运行:

3.3 创建设置类

  • 添加新功能时,也引入一些新设置,编写一个名为settings的模块,包含settings的类,用于将所有设置存储在一个地方,以免在代码中添加设置。从而传递一个设置对象,让函数调用更简单,修改游戏时,只需修改settings.py中的值。

    #settings.py
    class Settings():
    '''存储《外星人入侵》的所有设置的类'''
    def init(self):
    '''初始化游戏设置'''

        self.screen_width = 1200   # 屏幕设置尺寸
        self.screen_height = 800
        self.color = (230,230,230)  # 屏幕背景色

    #window.py

    模块sys用于退出游戏

    import sys
    import pygame
    from settings import Settings
    def run_game():
    # 初始化pygame、设置和屏幕对象
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("小子,你瞅啥啊")
    '''开始游戏的主循环'''
    while True:
    '''监视键盘和鼠标事件'''
    for event in pygame.event.get():
    if event.type ==pygame.QUIT:
    sys.exit()
    '''每次循环时都重绘屏幕'''
    #调用方法screen.fill()用背景色填充屏幕,这个方法只接受一个实参:一种颜色
    screen.fill(ai_settings.color)
    '''让最近绘制的屏幕可见'''
    pygame.display.flip()
    run_game()

运行:

为在屏幕上绘制玩家的飞船,将加载一副图像,再使用Pygame方法blit()绘制它

4.1创建Ship()类

  • pygame默认加载位图(.bmp)

  • 初始化飞船的属性

  • 调用pygame.image.load(),加载图像,返回一个表示飞船的surface。

  • 使用get_rect()获取相应surface的属性rect(矩形)

  • pygame的效率很高原因:能够像处理矩形(rect对象)一样处理游戏元素。

  • 在处理rect对象时,矩形四角和中心的x,y坐标,指定矩形的位置。

  • 要将游戏元素居中,可设置相应rect对象的属性center、centerx或centery,要让游戏元素与屏幕边缘对齐,可使用属性 top 、 bottom 、 left 或 right ;

  • 在 Pygame 中,原点 (0, 0) 位于屏幕左上角,向右下方移动时,坐标值将增大。在 1200×800 的屏幕上,原点位于左上角,而右下角的坐标为 (1200, 800) 。

    ship.py

    创建一个名为ship的模块,包含Ship类,负责管理飞船的大部分行为

    import pygame
    class Ship():
    def init(self,screen):
    '''初始化飞船并设置其初始位置'''
    self.screen = screen
    # 加载飞船图像并获取其它外接矩形
    self.image = pygame.image.load('images/ship.bmp')
    self.rect = self.image.get_rect()
    self.screen_rect = screen.get_rect()
    #将每艘新飞船放在屏幕底部中央
    self.rect.centerx = self.screen_rect.centerx
    self.rect.bottom = self.screen_rect.bottom
    def blitme(self):
    '''在指定位置绘制飞船'''
    self.screen.blit(self.image,self.rect)

运行:

4.2 添加飞船图像

  • self.screen.blit()通过访问图片及图片矩形位置,来显示在屏幕上。

    模块sys用于退出游戏

    import sys
    import pygame
    from settings import Settings
    from ship import Ship
    def run_game():
    '''初始化游戏并创建一个屏幕对象'''
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("小子,你瞅啥啊")
    '''创建一艘飞船'''
    ship = Ship(screen)

    '''开始游戏的主循环'''
    while True:
        '''监视键盘和鼠标事件'''
        for event in pygame.event.get():
            if event.type ==pygame.QUIT:
                sys.exit()
        '''每次循环时都重绘屏幕'''
        #调用方法screen.fill()用背景色填充屏幕,这个方法只接受一个实参:一种颜色
        screen.fill(ai_settings.bg_color)
        ship.blitme()
        '''让最近绘制的屏幕可见'''
        pygame.display.flip()

    run_game()

运行:

  • 重构旨在简化既有代码的结构,使其更容易扩展。
  • 创建game_functions模块,它将存储大量让游戏运行的函数,通过创建模块game_functions,可避免主运行模块alien_inbasion.py太长,使其逻辑更容易理解

5.1函数check_events()

  • 把管理事件的代码移到一个名为 check_events() 的函数中,以简化 run_game() 并隔离事件管理循环。

  • 通过隔离事件循环,可将事件管理与游戏的其他方面(如更新屏幕)分离。

  • 函数 check_events() 不需要任何形参,其函数体复制了 alien_invasion.py 的事件循环。

  • 在主程序文件中,不再需要直接导入 sys ,因为当前只在模块 game_functions 中使用了它。出于简化的目的,我们给导入的模块 game_functions 指定了别名 gf。

    game_functions.py

    模块sys用于退出游戏

    import sys
    import pygame

    def check_events():
    '''响应按键和鼠标事件'''
    for event in pygame.event.get():
    if event.type == pygame.QUIT:
    sys.exit()

    alien_inbasion.py

    import pygame
    from settings import Settings
    from ship import Ship
    import game_functions as gf
    def run_game():
    '''初始化游戏并创建一个屏幕对象'''
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("小子,你瞅啥啊")
    '''创建一艘飞船'''
    ship = Ship(screen)
    '''开始游戏的主循环'''
    while True:
    '''监视键盘和鼠标事件'''
    gf.check_events()
    '''每次循环时都重绘屏幕'''
    #调用方法screen.fill()用背景色填充屏幕,这个方法只接受一个实参:一种颜色
    screen.fill(ai_settings.bg_color)
    ship.blitme()
    '''让最近绘制的屏幕可见'''
    pygame.display.flip()

    run_game()

运行:

5.2函数update_screen()

  • 为进一步简化run_game(),将更新屏幕的代码移动到update_screen()的函数中,并将这个函数放在game_functions.py中

    game_functions.py

    模块sys用于退出游戏

    import sys
    import pygame

    def check_events():
    '''响应按键和鼠标事件'''
    for event in pygame.event.get():
    if event.type == pygame.QUIT:
    sys.exit()

    def update_screen(ai_settings,screen,ship):
    '''更新屏幕上的图像'''
    # 每次循环时都重绘屏幕
    screen.fill(ai_settings.bg_color)
    # 调用方法screen.fill()用背景色填充屏幕,这个方法只接受一个实参:一种颜色
    ship.blitme()
    # 让最近绘制的屏幕可见
    pygame.display.flip()

    alien_inbasion.py

    import pygame
    from settings import Settings
    from ship import Ship
    import game_functions as gf
    def run_game():
    '''初始化游戏并创建一个屏幕对象'''
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
    pygame.display.set_caption("小子,你瞅啥啊")
    '''创建一艘飞船'''
    ship = Ship(screen)
    '''开始游戏的主循环'''
    while True:
    '''监视键盘和鼠标事件'''
    gf.check_events()
    '''每次循环时都重绘屏幕'''
    gf.update_screen(ai_settings,screen,ship)

    run_game()

运行: