如何构建你的第一个 Python 游戏:使用 PyGame 创建简单射击游戏的分步指南

2025-05-25

如何构建你的第一个 Python 游戏:使用 PyGame 创建简单射击游戏的分步指南

嗨,亲爱的读者们,

你有没有想过创建自己的电子游戏?也许你想过构建一个简单的射击游戏,你可以在其中移动、躲避来袭的敌人并射击目标。好吧,今天是你的幸运日!我们将深入探索 PyGame 的奇妙世界,这是一个非常棒的 Python 库,即使你只接触过 Python 编写的基本控制台应用程序,它也能让游戏开发变得简单易行、充满乐趣。

如果您已经了解 Python 的基础知识(例如变量、循环、条件和函数),那么现在就可以开始构建自己的游戏了。如果您以前从未使用过 PyGame,也不用担心;读完这篇文章后,您将拥有一个简单但功能齐全的游戏来炫耀。那就开始吧!

为什么选择 PyGame?

在深入代码之前,我们先来聊聊为什么 PyGame 是一个优秀的游戏开发工具,尤其适合新手。PyGame 是一个 2D 桌面游戏库,它具备以下特点:

  • 易于学习:PyGame 简单易学,适合初学者。它抽象了游戏开发中许多复杂的部分,让你专注于游戏的构建。
  • 跨平台:使用 PyGame 制作的游戏可以在 Windows、Mac 和 Linux 上运行,而无需对代码进行任何更改。
  • 活跃:PyGame 拥有一个庞大且乐于助人的开发者社区。您可以找到大量的教程、示例和论坛,在这里您可以提问并分享您的项目。

设置您的环境

在开始编程之前,你需要在电脑上安装 Python。如果你还没有安装,请访问 python.org 下载最新版本。正确设置 Python 非常重要,因为它是 PyGame 运行的基础。

接下来,你需要安装 PyGame。这是一个提供创建游戏所需工具的库,例如管理窗口、绘制形状以及处理用户输入。安装 PyGame 很简单——只需打开终端(如果使用的是 Windows,则打开命令提示符)并输入:



pip install pygame


Enter fullscreen mode Exit fullscreen mode

完成后,您就可以开始创建游戏了!

步骤 1:设置游戏窗口

我们要做的第一件事是创建一个游戏运行的窗口。所有操作都将在这个窗口进行,所以可以把它想象成游戏的舞台。让我们编写代码来设置它。



import pygame
import sys

# Initialize PyGame
pygame.init()

# Set up the game window
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Simple Shooter Game")

# Set the frame rate
clock = pygame.time.Clock()

# Main game loop
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    # Fill the screen with a color (black in this case)
    screen.fill((0, 0, 0))

    # Update the display
    pygame.display.flip()

    # Cap the frame rate at 60 frames per second
    clock.tick(60)


Enter fullscreen mode Exit fullscreen mode

让我们来分析一下:

  1. 导入库:我们首先导入pygamesyspygame库是我们用来创建游戏的,而 可以sys帮助我们在需要时干净地退出程序。

  2. 初始化 PyGame:这一行pygame.init()至关重要——它设置了 PyGame 运行所需的所有模块。你应该在 PyGame 项目开始时调用这行代码。

  3. 创建游戏窗口:我们使用pygame.display.set_mode()创建一个宽度为 800 像素、高度为 600 像素的窗口。游戏中的所有内容都将在此显示。该pygame.display.set_caption()函数允许我们将窗口的标题设置为有意义的名称,例如“简单射击游戏”。

  4. 设置帧速率:此clock = pygame.time.Clock()行代码创建了一个时钟对象,用于控制游戏的运行速度。通过将帧速率设置为每秒 60 帧,我们可以确保游戏运行流畅。

  5. 主游戏循环:while True循环是我们游戏的核心。它持续运行,使我们能够更新游戏并检查诸如关闭窗口之类的事件。在此循环内部:
    * 事件处理:我们用它pygame.event.get()来检查玩家是否要退出游戏。如果玩家想要退出游戏,我们会调用此函数pygame.quit()进行清理并sys.exit()退出程序。
    * 绘制背景:screen.fill((0, 0, 0))线条会用黑色填充屏幕,实际上是清除屏幕以准备下一帧。
    * 更新显示:最后,pygame.display.flip()更新窗口以显示我们绘制的内容。

运行此代码后,您应该会看到一个纯黑色的窗口。恭喜!您已经完成了游戏的基础设置。

步骤 2:添加播放器

现在我们有了游戏窗口,让我们添加一些更有趣的东西——玩家角色。为了简单起见,我们将玩家表示为一个可以左右移动的矩形。敌人也将表示为矩形,以保持简单,并专注于游戏逻辑,而不是复杂的图形。



# Player settings
player_width = 50
player_height = 60
player_x = screen_width // 2 - player_width // 2
player_y = screen_height - player_height - 10
player_speed = 5

# Main game loop
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    # Handle player movement
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT] and player_x > 0:
        player_x -= player_speed
    if keys[pygame.K_RIGHT] and player_x < screen_width - player_width:
        player_x += player_speed

    # Fill the screen with black
    screen.fill((0, 0, 0))

    # Draw the player
    pygame.draw.rect(screen, (0, 128, 255), (player_x, player_y, player_width, player_height))

    # Update the display
    pygame.display.flip()

    # Cap the frame rate at 60 FPS
    clock.tick(60)


Enter fullscreen mode Exit fullscreen mode

事情是这样的:

  1. 播放器设置:我们定义播放器的尺寸(player_widthplayer_height)、起始位置(player_xplayer_y)以及速度(player_speed)。起始位置的计算方式是使播放器水平居中显示在窗口底部附近。

  2. 处理玩家移动:在主游戏循环中,我们使用 检查哪些按键被按下pygame.key.get_pressed()。此函数返回键盘上所有按键的列表,其中包含True当前按下的按键的值。如果按下了左箭头键,且玩家不在屏幕边缘,则我们通过player_speed从 中减去 来将玩家向左移动player_x。同样,如果按下了右箭头键,则将玩家向右移动。

  3. 绘制玩家:该pygame.draw.rect()函数在屏幕上绘制一个矩形(我们的玩家)。参数包括要绘制的屏幕、矩形的颜色(本例中为蓝色)以及矩形的位置和大小。

运行此代码后,你会看到一个蓝色矩形,你可以使用箭头键左右移动它。这个矩形就是我们的玩家,它将成为我们游戏的英雄。

第三步:发射子弹

射击游戏怎么能少了射击功能呢?让我们添加发射子弹的功能。玩家每次按下空格键时,我们都会创建一颗子弹。



# Bullet settings
bullet_width = 5
bullet_height = 10
bullet_speed = 7
bullets = []

# Main game loop
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                # Create a bullet at the current player position
                bullet_x = player_x + player_width // 2 - bullet_width // 2
                bullet_y = player_y
                bullets.append(pygame.Rect(bullet_x, bullet_y, bullet_width, bullet_height))

    # Handle player movement
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT] and player_x > 0:
        player_x -= player_speed
    if keys[pygame.K_RIGHT] and player_x < screen_width - player_width:
        player_x += player_speed

    # Update bullet positions
    for bullet in bullets:
        bullet.y -= bullet_speed

    # Remove bullets that are off the screen
    bullets = [bullet for bullet in bullets if bullet.y > 0]

    # Fill the screen with black
    screen.fill((0, 0, 0))

    # Draw the player
    pygame.draw.rect(screen, (0, 128, 255), (player_x, player_y, player_width, player_height))

    # Draw the bullets
    for bullet in bullets:
        pygame.draw.rect(screen, (255, 255, 255), bullet)

    # Update the display
    pygame.display.flip()

    # Cap the frame rate at 60 FPS
    clock.tick(60)


Enter fullscreen mode Exit fullscreen mode

让我们来分析一下:

  1. 子弹设置:我们定义子弹的大小(bullet_widthbullet_height)、速度(bullet_speed)和一个列表(bullets)来跟踪所有活动子弹。

  2. 发射子弹:在主循环中,我们检查KEYDOWN按下任意键时发生的事件。如果pygame.K_SPACE按下空格键 ( ),我们会在玩家当前位置创建一颗新的子弹。子弹的 x 位置计算为以玩家为中心水平居中,然后将子弹添加到列表中bullets

  3. 更新项目符号位置:列表中的每个项目符号bullets都会通过减少其 y 轴位置向上移动bullet_speed。超出屏幕顶部的项目符号将从列表中移除,以节省内存。

  4. 绘制项目符号:我们循环遍历bullets列表并用来pygame.draw.rect()在屏幕上绘制每个项目符号。

现在,当你运行游戏时,按下空格键将从玩家位置发射白色子弹。子弹会向上移动,就像你在射击游戏中预期的那样。

步骤 4:添加敌人

让我们通过添加玩家需要射击的敌人来增加游戏的挑战性。首先,我们将创建一些沿着屏幕向下移动到玩家的敌人。同样,为了简单起见,我们将敌人表示为红色矩形。



import random

# Enemy settings
enemy_width = 50
enemy_height = 60
enemy_speed = 2
enemies = []

# Spawn an enemy every 2 seconds
enemy_timer = 0
enemy_spawn_time = 2000

# Main game loop
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                bullet_x = player_x + player_width // 2 - bullet_width // 2
                bullet_y = player_y
                bullets.append(pygame.Rect(bullet_x, bullet_y, bullet_width, bullet_height))

    # Handle player movement
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT] and player_x > 0:
        player_x -= player_speed
    if keys[pygame.K_RIGHT] and player_x < screen_width - player_width:
        player_x += player_speed

    # Update bullet positions
    for bullet in bullets:
        bullet.y -= bullet_speed
    bullets = [bullet for bullet in bullets if bullet.y > 0]

    # Update enemy positions and spawn new ones
    current_time = pygame.time.get_ticks()
    if current_time - enemy_timer > enemy_spawn_time:
        enemy_x = random.randint(0, screen_width - enemy_width)
        enemy_y = -enemy_height
        enemies.append(pygame.Rect(enemy_x, enemy_y, enemy_width, enemy_height))
        enemy_timer = current_time

    for enemy in enemies:
        enemy.y += enemy_speed

    # Remove enemies that are off the screen
    enemies = [enemy for enemy in enemies if enemy.y < screen_height]

    # Fill the screen with black
    screen.fill((0, 0, 0))

    # Draw the player
    pygame.draw.rect(screen, (0, 128, 255), (player_x, player_y, player_width, player_height))

    # Draw the bullets
    for bullet in bullets:
        pygame.draw.rect(screen, (255, 255, 255), bullet)

    # Draw the enemies
    for enemy in enemies:
        pygame.draw.rect(screen, (255, 0, 0), enemy)

    # Update the display
    pygame.display.flip()

    # Cap the frame rate at 60 FPS
    clock.tick(60)


Enter fullscreen mode Exit fullscreen mode

以下是我们添加敌人的方式:

  1. 敌人设置:我们定义大小(enemy_widthenemy_height)、速度(enemy_speed)和列表(enemies)来追踪所有活跃的敌人。

  2. 生成敌人:我们使用计时器每 2 秒生成一个新敌人。当前时间通过 进行跟踪pygame.time.get_ticks()。如果距离上一个敌人生成已经过去了足够的时间,我们会在屏幕上方随机的水平位置创建一个新敌人(因此它会向下移动)。然后,这个敌人会被添加到列表中enemies

  3. 更新敌人位置:enemies列表中的每个敌人都会向下移动,增加enemy_speed其 y 轴位置。如果敌人移出了屏幕底部,则会将其从列表中移除。

  4. 绘制敌人:我们循环遍历enemies列表并用来pygame.draw.rect()在屏幕上绘制每个敌人。

运行这段代码,你会看到红色矩形(我们的敌人)从屏幕顶部落下。游戏开始成形了!

步骤5:检测碰撞

现在,让我们添加一些逻辑,这样当子弹击中敌人时,子弹和敌人都会消失。这涉及到检测子弹和敌人之间的碰撞。



# Collision detection function
def check_collision(rect1, rect2):
    return rect1.colliderect(rect2)

# Main game loop
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                bullet_x = player_x + player_width // 2 - bullet_width // 2
                bullet_y = player_y
                bullets.append(pygame.Rect(bullet_x, bullet_y, bullet_width, bullet_height))

    # Handle player movement
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT] and player_x > 0:
        player_x -= player_speed
    if keys[pygame.K_RIGHT] and player_x < screen_width - player_width:
        player_x += player_speed

    # Update bullet positions
    for bullet in bullets:
        bullet.y -= bullet_speed
    bullets = [bullet for bullet in bullets if bullet.y > 0]

    # Update enemy positions and spawn new ones
    current_time = pygame.time.get_ticks()
    if current_time - enemy_timer > enemy_spawn_time:
        enemy_x = random.randint(0, screen_width - enemy_width)
        enemy_y = -enemy_height
        enemies.append(pygame.Rect(enemy_x, enemy_y, enemy_width, enemy_height))
        enemy_timer = current_time

    for enemy in enemies:
        enemy.y += enemy_speed

    # Check for collisions
    for bullet in bullets[:]:
        for enemy in enemies[:]:
            if check_collision(bullet, enemy):
                bullets.remove(bullet)
                enemies.remove(enemy)
                break

    # Remove enemies that are off the screen
    enemies = [enemy for enemy in enemies if enemy.y < screen_height]

    # Fill the screen with black
    screen.fill((0, 0, 0))

    # Draw the player
    pygame.draw.rect(screen, (0, 128, 255), (player_x, player_y, player_width, player_height))

    # Draw the bullets
    for bullet in bullets:
        pygame.draw.rect(screen, (255, 255, 255), bullet)

    # Draw the enemies
    for enemy in enemies:
        pygame.draw.rect(screen, (255, 0, 0), enemy)

    # Update the display
    pygame.display.flip()

    # Cap the frame rate at 60 FPS
    clock.tick(60)


Enter fullscreen mode Exit fullscreen mode

以下是我们所做的:

  1. 碰撞检测:我们定义一个函数check_collision,它获取两个矩形的位置和大小,并使用 检查它们是否重叠colliderect()。这就是我们检测子弹是否击中敌人的方法。

  2. 移除碰撞对象:在主循环中,更新子弹和敌人的位置后,我们检查是否有子弹与敌人发生碰撞。如果发生碰撞,则将子弹和敌人从各自的列表中移除。

现在,当你运行游戏时,击中敌人的子弹会使敌人消失。你已经创建了一个简单但功能齐全的射击游戏!

重要提示:在这个简单的游戏中,与敌人碰撞不会受到惩罚。玩家可以穿过敌人而不会受到伤害或输掉游戏。这让游戏变得简单,但在更高级的版本中,你可能需要做出一些改变。

整合起来

如果您需要,以下是我们写的所有内容:



import pygame
import sys
import random

# Initialize PyGame
pygame.init()

# Set up the game window
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Simple Shooter Game")

# Set the frame rate
clock = pygame.time.Clock()

# Player settings
player_width = 50
player_height = 60
player_x = screen_width // 2 - player_width // 2
player_y = screen_height - player_height - 10
player_speed = 5

# Bullet settings
bullet_width = 5
bullet_height = 10
bullet_speed = 7
bullets = []

# Enemy settings
enemy_width = 50
enemy_height = 60
enemy_speed = 2
enemies = []

# Spawn an enemy every 2 seconds
enemy_timer = 0
enemy_spawn_time = 2000

# Collision detection function
def check_collision(rect1, rect2):
    return pygame.Rect(rect1).colliderect(pygame.Rect(rect2))

# Main game loop
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                # Create a bullet at the current player position
                bullet_x = player_x + player_width // 2 - bullet_width // 2
                bullet_y = player_y
                bullets.append([bullet_x, bullet_y])

    # Handle player movement
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT] and player_x > 0:
        player_x -= player_speed
    if keys[pygame.K_RIGHT] and player_x < screen_width - player_width:
        player_x += player_speed

    # Update bullet positions
    for bullet in bullets:
        bullet[1] -= bullet_speed
    bullets = [bullet for bullet in bullets if bullet[1] > 0]

    # Update enemy positions and spawn new ones
    current_time = pygame.time.get_ticks()
    if current_time - enemy_timer > enemy_spawn_time:
        enemy_x = random.randint(0, screen_width - enemy_width)
        enemy_y = -enemy_height
        enemies.append([enemy_x, enemy_y])
        enemy_timer = current_time

    for enemy in enemies:
        enemy[1] += enemy_speed

    # Check for collisions
    for bullet in bullets[:]:
        for enemy in enemies[:]:
            if check_collision((bullet[0], bullet[1], bullet_width, bullet_height),
                               (enemy[0], enemy[1], enemy_width, enemy_height)):
                bullets.remove(bullet)
                enemies.remove(enemy)
                break

    # Remove enemies that are off the screen
    enemies = [enemy for enemy in enemies if enemy[1] < screen_height]

    # Fill the screen with black
    screen.fill((0, 0, 0))

    # Draw the player
    pygame.draw.rect(screen, (0, 128, 255), (player_x, player_y, player_width, player_height))

    # Draw the bullets
    for bullet in bullets:
        pygame.draw.rect(screen, (255, 255, 255), (bullet[0], bullet[1], bullet_width, bullet_height))

    # Draw the enemies
    for enemy in enemies:
        pygame.draw.rect(screen, (255, 0, 0), (enemy[0], enemy[1], enemy_width, enemy_height))

    # Update the display
    pygame.display.flip()

    # Cap the frame rate at 60 FPS
    clock.tick(60)


Enter fullscreen mode Exit fullscreen mode

通过所有这些代码,你应该得到一个像这样的游戏,其中你是蓝色方块,而敌人是红色方块:
射击游戏

下一步是什么?

恭喜,你刚刚用 PyGame 构建了你的第一个简单的射击游戏!但这仅仅是个开始——你还可以做更多:

  • 添加计分系统:跟踪玩家消灭了多少敌人并在屏幕上显示分数。
  • 创建不同类型的敌人:制造以不同方式移动、反击或需要多次打击才能摧毁的敌人。
  • 增强图形:用玩家、子弹和敌人的图像替换矩形。
  • 添加音效:通过添加射击、击中敌人和其他动作的声音,使游戏更具沉浸感。
  • 引入级别:随着玩家的进步,添加不同级别或不同波次的敌人来增加难度。
  • 添加玩家生命值和伤害:允许玩家在与敌人碰撞时受到伤害,如果他们的生命值达到零则输掉游戏。

PyGame 非常灵活,所以尽情发挥你的想象力,不断尝试吧。你玩得越多,学到的东西就越多,你的游戏也会越精彩。

结束了!

就这样!只需几步,你就从一个空白窗口变成了一个可以运行的射击游戏。无论你是想扩展这个项目,还是想开始新的项目,你都已经在游戏开发之旅中迈出了一大步。欢迎分享你的进度或提出问题——我随时准备为你提供帮助!

如有任何问题或意见,请在此处留言,或在社交媒体平台上通过@lovelacecoding联系我。感谢您的参与!

文章来源:https://dev.to/lovelacecoding/how-to-build-your-first-python-game-a-step-by-step-guide-to-creating-a-simple-shooter-with-pygame-f0k
PREV
像专业人士一样加速数据库查询
NEXT
这些是 2021 年最有趣的前端开发工具吗?