Python笔记14-实战小游戏飞机大战(上)

news2025/1/17 0:45:58

文章目录

  • 功能规划
  • 安装pygame
  • 绘制游戏窗口
  • 添加玩家飞机图像
  • 屏幕上绘制飞船
  • 代码重构
  • 驾驶飞船
  • 全屏模式
  • 射击

功能规划

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

第一阶段将为玩家创建一艘飞船,它可左右移动,并且能在用户按空格键时开火。
第二阶段生成一群外星人。然后让这群外星人向两边和下面移动,并删除被子弹击中的外星人。示玩家拥有的飞船数量,并在玩家的飞船
用完后结束游戏
第三阶段添加一个Play按钮,让玩家能够开始游戏,以及在游戏结束后重玩。每当玩家消灭一群外星人后,我们都将加快游戏的节奏,并添加一个记分系统

安装pygame

Pygame是一组功能强大而有趣的模块,可用于管理图形、动画乃至声音,让你能够更轻松地开发复杂的游戏
执行如下命令安装pygame

C:\Users\eric>python -m pip install --user pygame
Collecting pygame
  Obtaining dependency information for pygame from https://files.pythonhosted.org/packages/82/61/93ae7afbd931a70510cfdf0a7bb0007540020b8d80bc1d8762ebdc46479b/pygame-2.5.2-cp311-cp311-win_amd64.whl.metadata
  Downloading pygame-2.5.2-cp311-cp311-win_amd64.whl.metadata (13 kB)
Downloading pygame-2.5.2-cp311-cp311-win_amd64.whl (10.8 MB)
   ---- ----------------------------------- 1.2/10.8 MB 20.4 kB/s eta 0:07:49 
      ---------------------------------------- 10.8/10.8 MB 14.7 kB/s eta 0:00:00
Installing collected packages: pygame
Successfully installed pygame-2.5.2
[notice] A new release of pip is available: 23.2.1 -> 23.3.2
[notice] To update, run: python.exe -m pip install --upgrade pip

绘制游戏窗口

建空的Pygame窗口。为此,在文本编辑器中新建一个文件,将其保存为alien_invasion.py,代码如下

import sys
import pygame
class AlienInvasion:
    """管理游戏资源和行为的类"""
    def __init__(self):
        """初始化游戏并创建游戏资源。"""
        pygame.init()
        self.screen = pygame.display.set_mode((1200, 800))
        pygame.display.set_caption("Alien Invasion")
    def run_game(self):
        """开始游戏的主循环"""
        while True:
            # 监视键盘和鼠标事件。
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
            # 让最近绘制的屏幕可见
            pygame.display.flip()

if __name__ == '__main__':
    # 创建游戏实例并运行游戏。
    ai = AlienInvasion()
    ai.run_game()

运行可以看到个黑色屏幕窗口如下:
在这里插入图片描述
给游戏添加新功能时,通常也将引入一些新设置。下面来编写一个名为settings 的模块,在其中包含一个名为Settings 的类,用于将所有设置都存储在一个地方,以免在代码中到处添加设置。这样,每当需要访问设置时,只需使用一个设置对象。另外,在项目增大时,这使得修改游戏的外观和行为更容易:要修改游戏,只需修改(接下来将创建的)settings.py中的一些值,而无须查找散布在项目中的各种设置。

class Settings:
    """存储游戏《外星人入侵》中所有设置的类"""
    def __init__(self):
        """初始化游戏的设置。"""
        # 屏幕设置
        self.screen_width = 1200
        self.screen_height = 800
        self.bg_color = (230, 230, 230)

修改原来的窗口代码,并使用settings中的配置项设置背景颜色,宽度 高度

import sys
import pygame
from settings import Settings
class AlienInvasion:
    """管理游戏资源和行为的类"""
    def __init__(self):
        """初始化游戏并创建游戏资源。"""
        pygame.init()
        self.settings = Settings()
        self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("Alien Invasion")
    def run_game(self):
        """开始游戏的主循环"""
        while True:

            # 每次循环时都重绘屏幕。
            self.screen.fill(self.settings.bg_color)
            # 监视键盘和鼠标事件。
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
            # 让最近绘制的屏幕可见
            pygame.display.flip()

if __name__ == '__main__':
    # 创建游戏实例并运行游戏。
    ai = AlienInvasion()
    ai.run_game()

运行效果
在这里插入图片描述

添加玩家飞机图像

下面将飞船加入游戏中。为了在屏幕上绘制玩家的飞船,我们将加载一幅图像,再使用Pygame方法blit() 绘制它。为游戏选择素材时,务必要注意许可。最安全、最不费钱的方式是使用Pixabay等网站提供的免费图形,无须授权许可即可使用并修改。
我们使用如下图片
在这里插入图片描述

选择用于表示飞船的图像后,需要将其显示到屏幕上。我们创建一个名为ship 的模块,其中包含Ship 类,负责管理飞船的大部分行为。

import pygame
class Ship:
    """
    管理飞船的类
    ai_game参数就是游戏窗口对象
    """
    def __init__(self, ai_game):
        """初始化飞船并设置其初始位置。"""
        self.screen = ai_game.screen
        self.screen_rect = ai_game.screen.get_rect()
        # 加载飞船图像并获取其外接矩形。
        self.image = pygame.image.load('images/me1.png')
        self.rect = self.image.get_rect()
        # 对于每艘新飞船,都将其放在屏幕底部的中央。 这里通过飞穿图像 和 游戏窗口图像 的中间位置相等,来实现放在中间
        self.rect.midbottom = self.screen_rect.midbottom
    def blitme(self):
        """在指定位置绘制飞船。"""
        self.screen.blit(self.image, self.rect)#绘制图像

Pygame之所以高效,是因为它让你能够像处理矩形(rect 对象)一样处理所有的游戏元素,即便其形状并非矩形。像处理矩形一样处理游戏元素之所以高效,是因为矩形是简单的几何形状。例如,通过将游戏元素视为矩形,Pygame能够更快地判断出它们是否发生了碰撞。这种做法的效果通常很好,游戏玩家几乎注意不到我们处理的并不是游戏元素的实际形状。在这个类中,我们将把飞船和屏幕作为矩形进行处理。

屏幕上绘制飞船

创建一艘飞船并调用其方法blitme()代码如下:

import sys
import time

import pygame
from settings import Settings
from ship import Ship

class AlienInvasion:
    """管理游戏资源和行为的类"""
    def __init__(self):
        """初始化游戏并创建游戏资源。"""
        pygame.init()
        self.settings = Settings()
        self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("Alien Invasion")
        self.ship = Ship(self)

    def run_game(self):
        """开始游戏的主循环"""
        while True:

            # 每次循环时都重绘屏幕。
            self.screen.fill(self.settings.bg_color)
            self.ship.blitme()# 绘制飞船
            # 监视键盘和鼠标事件。
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()
            # 让最近绘制的屏幕可见
            pygame.display.flip()
            time.sleep(0.05) #设置每50ms刷新一次

if __name__ == '__main__':
    # 创建游戏实例并运行游戏。
    ai = AlienInvasion()
    ai.run_game()

运行效果
在这里插入图片描述

代码重构

在大型项目中,经常需要在添加新代码前重构既有代码。重构旨在简化既有代码的结构,使其更容易扩展。本节将把越来越长的方法run_game() 拆分成两个辅助方法(helper method)。辅助方法 在类中执行任务,但并非是通过实例调用的。在Python中,辅助方法的名称以单个下划线打头。
把管理事件的代码移到一个名为_check_events() 的方法中,以简化run_game() 并隔离事件管理循环。通过隔离事件循环,可将事件管理与游戏的其他方面(如更新屏幕)分离
简化run_game() ,将更新屏幕的代码移到一个名为_update_screen() 的方法中:

import sys
import time

import pygame
from settings import Settings
from ship import Ship

class AlienInvasion:
    """管理游戏资源和行为的类"""
    def __init__(self):
        """初始化游戏并创建游戏资源。"""
        pygame.init()
        self.settings = Settings()
        self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("Alien Invasion")
        self.ship = Ship(self)

    def run_game(self):
        """开始游戏的主循环"""
        while True:
            #检测事件
            self._check_events()

            # 每次循环时都重绘屏幕。
            self._update_screen()
            time.sleep(0.05) #设置每50ms刷新一次

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

    def _update_screen(self):
        """更新屏幕上的图像,并切换到新屏幕。"""
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        pygame.display.flip()


if __name__ == '__main__':
    # 创建游戏实例并运行游戏。
    ai = AlienInvasion()
    ai.run_game()

驾驶飞船

每当用户按键时,都将在Pygame中注册一个事件。事件都是通过方法pygame.event.get() 获取的,因此需要在方法_check_events() 中指定要检查哪些类型的事件。每次按键都被注册为一个KEYDOWN 事件。
玩家按住右箭头键不放时,我们希望飞船不断向右移动,直到玩家松开为止。我们将让游戏检测pygame.KEYUP 事件,以便知道玩家何时松开右箭头键。然后,结合使用KEYDOWN 和KEYUP 事件以及一个名为moving_right 的标志来实现持续移动,当标志moving_right 为False 时,飞船不会移动。玩家按下右箭头键时,我们将该标志设置为True ,在玩家松开时将该标志重新设置为False 。
飞船的属性都由Ship 类控制,因此要给这个类添加一个名为moving_right 的属性和一个名为update() 的方法。方法update() 检查标志moving_right 的状态。如果该标志为True ,就调整飞船的位置。我们将在while 循环中调用这个方法,以调整飞船的位置。

import pygame
class Ship:
    """
    管理飞船的类
    ai_game参数就是游戏窗口对象
    """
    def __init__(self, ai_game):
        """初始化飞船并设置其初始位置。"""
        self.screen = ai_game.screen
        self.screen_rect = ai_game.screen.get_rect()
        # 加载飞船图像并获取其外接矩形。
        self.image = pygame.image.load('images/me1.png')
        self.rect = self.image.get_rect()
        # 对于每艘新飞船,都将其放在屏幕底部的中央。 这里通过飞穿图像 和 游戏窗口图像 的中间位置相等,来实现放在中间
        self.rect.midbottom = self.screen_rect.midbottom

        # 移动标志。
        self.moving_right = False
        self.moving_left = False

    def update(self):
        """根据移动标志调整飞船的位置。"""
        if self.moving_right:
            self.rect.x += 1
        if self.moving_left:
            self.rect.x -= 1

    def blitme(self):
        """在指定位置绘制飞船。"""
        self.screen.blit(self.image, self.rect)#绘制图像

修改_check_events() ,使其在玩家按下右箭头键时将moving_right 设置为True ,并在玩家松开时将moving_right 设置为False
向左移动的逻辑和向右相同

   import sys
import time

import pygame
from settings import Settings
from ship import Ship

class AlienInvasion:
    """管理游戏资源和行为的类"""
    def __init__(self):
        """初始化游戏并创建游戏资源。"""
        pygame.init()
        self.settings = Settings()
        self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("Alien Invasion")
        self.ship = Ship(self)

    def run_game(self):
        """开始游戏的主循环"""
        while True:
            #检测事件
            self._check_events()
            #更新飞船位置
            self.ship.update()
            # 每次循环时都重绘屏幕。
            self._update_screen()
            time.sleep(0.05) #设置每50ms刷新一次

    def _check_events(self):
        """响应按键和鼠标事件。"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    self.ship.moving_right = True
                elif event.key == pygame.K_LEFT:
                    self.ship.moving_left = True

            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_RIGHT:
                    self.ship.moving_right = False
                elif event.key == pygame.K_LEFT:
                    self.ship.moving_left = False

    def _update_screen(self):
        """更新屏幕上的图像,并切换到新屏幕。"""
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        pygame.display.flip()


if __name__ == '__main__':
    # 创建游戏实例并运行游戏。
    ai = AlienInvasion()
    ai.run_game()

运行 可以左右移动飞船了

目前飞船每次移动1像素,在Settings 类中添加属性ship_speed ,用于控制飞船的速度。我们将根据这个属性决定飞船在每次循环时最多移动多远。下面演示了如何在settings.py中添加这个新属性:

class Settings:
    """存储游戏《外星人入侵》中所有设置的类"""
    def __init__(self):
        """初始化游戏的设置。"""
        # 屏幕设置
        self.screen_width = 1200
        self.screen_height = 800
        self.bg_color = (230, 230, 230)
        #飞船移动速度
        self.ship_speed =5

修改 飞船 类代码,按照配置中的速度 移动飞船,支持小数设置,同时限制飞船的移动范围

import pygame
from settings import Settings
class Ship:
    """
    管理飞船的类
    ai_game参数就是游戏窗口对象
    """
    def __init__(self, ai_game):
        """初始化飞船并设置其初始位置。"""
        self.screen = ai_game.screen
        self.screen_rect = ai_game.screen.get_rect()
        # 加载飞船图像并获取其外接矩形。
        self.image = pygame.image.load('images/me1.png')
        self.rect = self.image.get_rect()
        # 对于每艘新飞船,都将其放在屏幕底部的中央。 这里通过飞穿图像 和 游戏窗口图像 的中间位置相等,来实现放在中间
        self.rect.midbottom = self.screen_rect.midbottom
        # 在飞船的属性x中存储小数值。
        self.x = float(self.rect.x)

        self.settings = ai_game.settings
        # 移动标志。
        self.moving_right = False
        self.moving_left = False

    def update(self):
        """根据移动标志调整飞船的位置。"""
        # 更新飞船而不是rect对象的x值。

        if self.moving_right and self.rect.right < self.screen_rect.right:
            self.x += self.settings.ship_speed
        if self.moving_left and self.rect.left >0:
            self.x -= self.settings.ship_speed
        # 根据self.x更新rect对象。 自动转成int型
        self.rect.x = self.x

    def blitme(self):
        """在指定位置绘制飞船。"""
        self.screen.blit(self.image, self.rect)#绘制图像

运行发现飞船的速度可以调整,而且飞船只能在屏幕范围内移动

拆分 _check_events方法,将keyup 和 keydown 事件处理分开,并增加按F1退出的事件监听

  def _check_events(self):
        """响应按键和鼠标事件。"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(self, event)

            elif event.type == pygame.KEYUP:
                self._check_keyup_events(self, event)

    def _check_keydown_events(self, event):
        """响应按键。"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_F1: #按F1 退出
            sys.exit()

    def _check_keyup_events(self, event):
        """响应松开。"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

全屏模式

Pygame支持全屏模式,你可能会更喜欢在这种模式下而非常规窗口中运行游戏。有些游戏在全屏模式下看起来更舒服,而在macOS系统中用全屏模式运行会提升性能。要在全屏模式下运行该游戏,可在__init__() 中做如下修改:

class AlienInvasion:
    """管理游戏资源和行为的类"""
    def __init__(self):
        """初始化游戏并创建游戏资源。"""
        pygame.init()
        self.settings = Settings()
        self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
        self.settings.screen_width = self.screen.get_rect().width
        self.settings.screen_height = self.screen.get_rect().height
       # self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("Alien Invasion")
        self.ship = Ship(self)

射击

更新settings.py,在方法__init__() 末尾存储新类Bullet所需的值,创建宽3像素、高15像素的深灰色子弹。子弹的速度比飞船稍低

#子弹设置
self.bullet_speed = 1.0
self.bullet_width = 3
self.bullet_height = 15
self.bullet_color = (60, 60, 60)

Bullet 类继承了从模块pygame.sprite 导入的Sprite 类。通过使用精灵(sprite),可将游戏中相关的元素编组,进而同时操作编组中的所有元素。为创建子弹实例,init() 需要当前的AlienInvasion 实例,我们还调用了super() 来继承Sprite 。另外,我们还定义了用于存储屏幕以及设置对象和子弹颜色的属性。

import pygame
from pygame.sprite import Sprite
class Bullet(Sprite):
    """管理飞船所发射子弹的类"""
    def __init__(self, ai_game):
        """在飞船当前位置创建一个子弹对象。"""
        super().__init__()
        self.screen = ai_game.screen
        self.settings = ai_game.settings
        self.color = self.settings.bullet_color
        #在(0,0)处创建一个表示子弹的矩形,再设置正确的位置。
        self.rect = pygame.Rect(0, 0, self.settings.bullet_width,
        self.settings.bullet_height)
        self.rect.midtop = ai_game.ship.rect.midtop
        # 存储用小数表示的子弹位置。
        self.y = float(self.rect.y)

    def update(self):
        """向上移动子弹。"""
        # 更新表示子弹位置的小数值。
        self.y -= self.settings.bullet_speed
        # 更新表示子弹的rect的位置。
        self.rect.y = self.y

    def draw_bullet(self):
        """在屏幕上绘制子弹。"""
        pygame.draw.rect(self.screen, self.color, self.rect)

定义Bullet 类和必要的设置后,便可编写代码在玩家每次按空格键时都射出一发子弹了。我们将在AlienInvasion 中创建一个编组(group),用于存储所有有效的子弹,以便管理发射出去的所有子弹。这个编组是pygame.sprite.Group 类的一个实例。pygame.sprite.Group 类似于列表,但提供了有助于开发游戏的额外功能。在主循环中,将使用这个编组在屏幕上绘制子弹以及更新每颗子弹的位置。
在这里插入图片描述
后在while 循环中更新子弹的位置

    def run_game(self):
        """开始游戏的主循环"""
        while True:
            #检测事件
            self._check_events()
            #更新飞船位置
            self.ship.update()
            #更新子弹
            """
            对编组调用update() 时,编组自动对其中的每个精灵调
            用update() 。因此代码行bullets.update() 将为编组bullets
            中的每颗子弹调用bullet.update()"""
            self.bullets.update()
            # 每次循环时都重绘屏幕。
            self._update_screen()
            time.sleep(0.05) #设置每50ms刷新一次

发射
在AlienInvasion 中,需要修改_check_keydown_events() ,以便在玩家按空格键时发射一颗子弹,此编写一个新方法_fire_bullet() 来完成这项任务

    def _check_keydown_events(self, event):
        """响应按键。"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_F1: #按F1 退出
            sys.exit()
        elif event.key == pygame.K_SPACE: # 空格发射子弹
            self._fire_bullet()


    def _fire_bullet(self):
        """创建一颗子弹,并将其加入编组bullets中。"""
        new_bullet = Bullet(self)
        self.bullets.add(new_bullet)

  def _update_screen(self):
        """更新屏幕上的图像,并切换到新屏幕。"""
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        pygame.display.flip()

删除子弹
子弹在抵达屏幕顶端后消失,但这仅仅是因为Pygame无法在屏幕外面绘制它们。这些子弹实际上依然存在,其 坐标为负数且越来越小。这是个问题,因为它们将继续消耗内存和处理能力

def run_game(self):
    """开始游戏的主循环"""
    while True:
        #检测事件
        self._check_events()
        #更新飞船位置
        self.ship.update()
        #更新子弹
        """
        对编组调用update() 时,编组自动对其中的每个精灵调
        用update() 。因此代码行bullets.update() 将为编组bullets
        中的每颗子弹调用bullet.update()"""
        self.bullets.update()
        # 删除消失的子弹。
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)
        print(len(self.bullets))
        # 每次循环时都重绘屏幕。
        self._update_screen()
        time.sleep(0.05) #设置每50ms刷新一次

限制子弹数量
很多射击游戏对可同时出现在屏幕上的子弹数量进行了限制,以鼓励玩家有目标地射击

在settings.py中存储最大子弹数

 self.bullets_allowed = 3

在创建新子弹前检查未消失的子弹数是否小于该设置

    def _fire_bullet(self):
        """创建一颗子弹,并将其加入编组bullets中。"""
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

创建一个名为_update_bullets() 的新方法,存放子弹管理的逻辑,完整代码如下

import sys
import time

import pygame
from settings import Settings
from ship import Ship
from bullet import Bullet

class AlienInvasion:
    """管理游戏资源和行为的类"""
    def __init__(self):
        """初始化游戏并创建游戏资源。"""
        pygame.init()
        self.settings = Settings()
        #全屏模式代码
        # self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
        # self.settings.screen_width = self.screen.get_rect().width
        # self.settings.screen_height = self.screen.get_rect().height
        #非全屏模式
        self.screen = pygame.display.set_mode((self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("Alien Invasion")
        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()

    def run_game(self):
        """开始游戏的主循环"""
        while True:
            #检测事件
            self._check_events()
            #更新飞船位置
            self.ship.update()
            #更新子弹
            """
            对编组调用update() 时,编组自动对其中的每个精灵调
            用update() 。因此代码行bullets.update() 将为编组bullets
            中的每颗子弹调用bullet.update()"""
            self._update_bullets()
            # 每次循环时都重绘屏幕。
            self._update_screen()
            time.sleep(0.05) #设置每50ms刷新一次

    def _update_bullets(self):
        """更新子弹的位置并删除消失的子弹。"""
        # 更新子弹的位置。
        self.bullets.update()
        # 删除消失的子弹。
        for bullet in self.bullets.copy():
            if bullet.rect.bottom <= 0:
                self.bullets.remove(bullet)

    def _check_events(self):
        """响应按键和鼠标事件。"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events( event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events( event)

    def _check_keydown_events(self, event):
        """响应按键。"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_F1: #按F1 退出
            sys.exit()
        elif event.key == pygame.K_SPACE: # 空格发射子弹
            self._fire_bullet()


    def _fire_bullet(self):
        """创建一颗子弹,并将其加入编组bullets中。"""
        if len(self.bullets) < self.settings.bullets_allowed:
            new_bullet = Bullet(self)
            self.bullets.add(new_bullet)

    def _check_keyup_events(self, event):
        """响应松开。"""
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _update_screen(self):
        """更新屏幕上的图像,并切换到新屏幕。"""
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        pygame.display.flip()


if __name__ == '__main__':
    # 创建游戏实例并运行游戏。
    ai = AlienInvasion()
    ai.run_game()

运行之后可以发射子弹了,并且最多三个子弹
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1416701.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何从 Android SD 卡恢复已删除的照片

您是否不小心从 Android SD 卡中删除了一些照片&#xff1f;您是否尝试访问昨天拍摄的照片&#xff0c;但无论您在哪里查看都找不到它们&#xff1f;您的 Android 手机的外部存储是否已损坏&#xff0c;其内容无法访问&#xff1f; 在这种情况下&#xff0c;您应该尽快采取行动…

LV老板重夺全球首富 再次超过马斯克;新东方安徽总部大厦启用;中国与泰国签署互免签证协定

今日精选 • LV老板重夺全球首富 再次超过马斯克• 新东方安徽总部大厦启用• 中国与泰国签署互免签证协定 投融资与企业动态 • ​​传Temu将于3月在美国上线半托管业务• 国内数字支付解决方案提供商 “连连数字” 估值150亿&#xff0c;即将IPO• 滴滴与宁德时代宣布成立…

【Javaweb程序设计】【C00164】基于SSM的飞机订票系统(论文+PPT)

基于SSM的飞机订票系统&#xff08;论文PPT&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目包运行、免费远程调试 项目简介 这是一个基于ssm的飞机订票系统 本系统分为前台用户模块和后台管理员模块。 前台用户模块&#xff1a;当游客打开系统的网址后&#xff0…

营销领域有哪些著名的模型?如销售漏斗等

一、金字塔原理 模型 适用场景&#xff1a;提案 沟通 思考理论 模型 来源&#xff1a;麦肯锡 芭芭明托 1、表达的逻辑 遵循金字塔模型的逻辑&#xff0c;先说结论&#xff0c;后说论据。所有表达的内容都可归纳出一个核心论点。这个核心论点由N个论据作为支持&#xff0c;而…

Qt扩展-QXlsx读写Excel配置使用

QXlsx读写Excel配置使用 一、概述1. 功能概述2. 其他维护 二、安装1. 下载源码2. 配置项目3. 测试代码4. 运行结果 一、概述 项目介绍&#xff1a;https://qtexcel.github.io/QXlsx/Example.html GitHub&#xff1a;https://github.com/QtExcel/QXlsx/tree/master QXlsx 是一个…

时序分析中的去趋势化方法

时序分析中的去趋势化方法 时序分析是研究随时间变化的数据模式的一门学科。在时序数据中&#xff0c;趋势是一种随着时间推移而呈现的长期变化趋势&#xff0c;去趋势化是为了消除或减弱这种趋势&#xff0c;使数据更具平稳性。本文将简单介绍时序分析中常用的去趋势化方法&a…

java自定义异常处理操作

目录 引入 介绍 一、为我们的方法创建异常类 二、使用我们定义的异常类 引入 我们在编写java代码的时候,想要在我们自己写的方法中加入我们的异常处理 介绍 一、为我们的方法创建异常类 我们先单独创建一个类,来当作我们抛出异常的类 public class AgeIllegalException ex…

JavaScript DOM属性和方法之element元素对象

在HTML DOM中&#xff0c;elment对象表示HTML与纳素&#xff0c;可以包含的节点类型有元素u节点、文本节点、注释节点。它们有响应的属性和方法&#xff0c;有很多都是我们之前用过的。 一、element对象属性 1、attributes 2、childNodes 3、className 4、clientWidth、of…

计算机中丢失mfc100u.dll怎么解决,详细解析mfc100u.dll丢失的解决方法

遭遇“无法找到mfc100u.dll”的错误不必过分担忧&#xff0c;这是一个普遍现象。许多用户在启动某些软件或游戏的时候可能会碰到这样的情况。通常&#xff0c;这个错误信息表明你的计算机系统中缺失了一个关键的动态链接库(DLL)文件&#xff0c;它可能会妨碍应用程序的顺利启动…

Centos7 升级Docker 至最新版本

卸载旧版本的Docker yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 安装需要的软件包 yum install -y yum-utils device-mapper-persistent-data lvm2 添加Docker的yum源 #yu…

uniapp,页面当有按钮的时候,可以做一个动态的效果

效果&#xff1a; 这个是当点着按钮的时候没有松开按钮的效果&#xff08;没有阴影&#xff09; 这个是当松开按钮的效果&#xff08;有阴影&#xff09; 原理讲解&#xff1a; 这段代码实现的业务逻辑是在一个Vue组件中控制“现金”按钮的阴影效果。具体来说&#xff0c;它通…

Qt WebEngine模块使用(开发环境安装和程序开发)

一、Qt WebEngine Qt WebEngine_hitzsf的博客-CSDN博客 Qt WebEngine模块提供了一个Web浏览器引擎&#xff0c;可以轻松地将万维网上的内容嵌入到没有本机Web引擎的平台上的Qt应用程序中。Qt WebEngine提供了用于渲染HTML&#xff0c;XHTML和SVG文档的C 类和QML类型&#xff…

服务端开发小记02——Maven

这里写目录标题 Maven简介Maven在Linux下的安装Maven常用命令 Maven简介 Apache Maven Project是一个apache的开源项目&#xff0c;是用于构建和管理Java项目的工具包。 用Maven可以方便地创建项目&#xff0c;基于archetype可以创建多种类型的java项目&#xff1b;Maven仓库…

带libc源码gdb动态调试(导入glibc库使得可执行文件动态调试时可看见调用库函数源码)

文章目录 查看源码是否编译时有-g调试信息和符号表在 gdb 中加载 debug 文件/符号表将 debug 文件放入 ".debug" 文件夹通过 gdb 命令 set debug-file-directory directories GCC的gcc和g区别指定gcc/g&#xff0c;glibc的版本进行编译指定gcc/g的版本指定glibc的和l…

最新计算机软件毕业设计选题大全

最新计算机软件毕业设计选题大全 1、毕业设计选题 博主介绍&#xff1a;✌️大厂码农|毕设布道师&#xff0c;阿里云开发社区乘风者计划专家博主&#xff0c;CSDN平台Java领域优质创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。✌️ 主要项目&#xff1a;小…

ppt背景图片怎么设置?让你的演示更加出彩!

PowerPoint是一款广泛应用于演示文稿制作的软件&#xff0c;而背景图片是演示文稿中不可或缺的一部分。一个好的背景图片能够提升演示文稿的整体效果&#xff0c;使观众更加关注你的演示内容。可是ppt背景图片怎么设置呢&#xff1f;本文将介绍ppt背景图片设置的三个方法&#…

JavaScript DOM属性和方法之event事件对象

event对象代表事件的状态&#xff0c;比如事件在其中发生的元素&#xff0c;键盘按键的状态、鼠标的位置、鼠标按钮的状态&#xff0c;事件通常与函数结合使用&#xff0c;函数不会在事件发生前被执行&#xff0c;只有当事件被触发的时候才会执行函数。 一、句柄事件 1、oncl…

免费且安全的SSL证书:JoySSL为您的网站安全保驾护航

在当今这个数字化飞速发展的时代&#xff0c;网络安全问题日益凸显&#xff0c;特别是对于网站所有者而言&#xff0c;如何保障用户数据的安全传输显得尤为重要。SSL&#xff08;安全套接层&#xff09;证书作为一种有效的加密工具&#xff0c;被广泛应用于各类网站中。那么&am…

【计算机网络】深入掌握计算机网络的核心要点

写在前面 前言四层模型网络地址管理Linux下设置ipARP请求包总结 前言 计算机网络是指将分散的计算机设备通过通信线路连接起来&#xff0c;形成一个统一的网络。为了使得各个计算机之间能够相互通信&#xff0c;需要遵循一定的协议和规范。OSI参考模型和TCP/IP参考模型是计算机…

专业133总分400+上海交通大学819考研经验分享上交819电子信息与通信工程

今年专业819信号系统与信号处理133&#xff0c;总分400&#xff0c;如愿考上梦中上海交通大学&#xff0c;通过自己将近一年的复习&#xff0c;实现了人生中目前为止最大的逆袭&#xff08;自己本科学校很普通&#xff09;&#xff0c;总结自己的复习经历&#xff0c;希望可以给…