如何构建你的第一个 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
完成后,您就可以开始创建游戏了!
步骤 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)
让我们来分析一下:
-
导入库:我们首先导入
pygame
和sys
。pygame
库是我们用来创建游戏的,而 可以sys
帮助我们在需要时干净地退出程序。 -
初始化 PyGame:这一行
pygame.init()
至关重要——它设置了 PyGame 运行所需的所有模块。你应该在 PyGame 项目开始时调用这行代码。 -
创建游戏窗口:我们使用
pygame.display.set_mode()
创建一个宽度为 800 像素、高度为 600 像素的窗口。游戏中的所有内容都将在此显示。该pygame.display.set_caption()
函数允许我们将窗口的标题设置为有意义的名称,例如“简单射击游戏”。 -
设置帧速率:此
clock = pygame.time.Clock()
行代码创建了一个时钟对象,用于控制游戏的运行速度。通过将帧速率设置为每秒 60 帧,我们可以确保游戏运行流畅。 -
主游戏循环:
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)
事情是这样的:
-
播放器设置:我们定义播放器的尺寸(
player_width
和player_height
)、起始位置(player_x
和player_y
)以及速度(player_speed
)。起始位置的计算方式是使播放器水平居中显示在窗口底部附近。 -
处理玩家移动:在主游戏循环中,我们使用 检查哪些按键被按下
pygame.key.get_pressed()
。此函数返回键盘上所有按键的列表,其中包含True
当前按下的按键的值。如果按下了左箭头键,且玩家不在屏幕边缘,则我们通过player_speed
从 中减去 来将玩家向左移动player_x
。同样,如果按下了右箭头键,则将玩家向右移动。 -
绘制玩家:该
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)
让我们来分析一下:
-
子弹设置:我们定义子弹的大小(
bullet_width
和bullet_height
)、速度(bullet_speed
)和一个列表(bullets
)来跟踪所有活动子弹。 -
发射子弹:在主循环中,我们检查
KEYDOWN
按下任意键时发生的事件。如果pygame.K_SPACE
按下空格键 ( ),我们会在玩家当前位置创建一颗新的子弹。子弹的 x 位置计算为以玩家为中心水平居中,然后将子弹添加到列表中bullets
。 -
更新项目符号位置:列表中的每个项目符号
bullets
都会通过减少其 y 轴位置向上移动bullet_speed
。超出屏幕顶部的项目符号将从列表中移除,以节省内存。 -
绘制项目符号:我们循环遍历
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)
以下是我们添加敌人的方式:
-
敌人设置:我们定义大小(
enemy_width
和enemy_height
)、速度(enemy_speed
)和列表(enemies
)来追踪所有活跃的敌人。 -
生成敌人:我们使用计时器每 2 秒生成一个新敌人。当前时间通过 进行跟踪
pygame.time.get_ticks()
。如果距离上一个敌人生成已经过去了足够的时间,我们会在屏幕上方随机的水平位置创建一个新敌人(因此它会向下移动)。然后,这个敌人会被添加到列表中enemies
。 -
更新敌人位置:
enemies
列表中的每个敌人都会向下移动,增加enemy_speed
其 y 轴位置。如果敌人移出了屏幕底部,则会将其从列表中移除。 -
绘制敌人:我们循环遍历
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)
以下是我们所做的:
-
碰撞检测:我们定义一个函数
check_collision
,它获取两个矩形的位置和大小,并使用 检查它们是否重叠colliderect()
。这就是我们检测子弹是否击中敌人的方法。 -
移除碰撞对象:在主循环中,更新子弹和敌人的位置后,我们检查是否有子弹与敌人发生碰撞。如果发生碰撞,则将子弹和敌人从各自的列表中移除。
现在,当你运行游戏时,击中敌人的子弹会使敌人消失。你已经创建了一个简单但功能齐全的射击游戏!
重要提示:在这个简单的游戏中,与敌人碰撞不会受到惩罚。玩家可以穿过敌人而不会受到伤害或输掉游戏。这让游戏变得简单,但在更高级的版本中,你可能需要做出一些改变。
整合起来
如果您需要,以下是我们写的所有内容:
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)
通过所有这些代码,你应该得到一个像这样的游戏,其中你是蓝色方块,而敌人是红色方块:
下一步是什么?
恭喜,你刚刚用 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