游戏预览
游戏将包含以下元素:

- 玩家角色:一个可以左右移动的滑雪者。
- 障碍物:从屏幕上方不断滚下的树木和石头。
- 计分系统:玩家每成功躲避一个障碍物,分数就会增加。
- 游戏结束:当玩家撞到障碍物时,游戏结束,并显示最终得分。
第1步:准备工作
在开始编写代码之前,你需要安装 Pygame 库,如果你还没有安装,可以在终端或命令提示符中运行以下命令:
pip install pygame
第2步:创建游戏文件
在你的项目文件夹中,创建一个名为 skier_game.py 的文件,我们将把所有的代码都写在这个文件里。
第3步:完整游戏代码
将以下所有代码复制并粘贴到 skier_game.py 文件中。
import pygame
import random
import sys
# --- 常量定义 ---
# 屏幕尺寸
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
# 颜色定义 (R, G, B)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
BROWN = (139, 69, 19)
GRAY = (128, 128, 128)
# --- 初始化 Pygame ---
pygame.init()
# --- 创建游戏窗口 ---
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Python 滑雪游戏")
# --- 加载和设置游戏图标 ---
# 你可以自己准备一个 'skier_icon.png' 图片,或者这行代码可以注释掉
try:
icon = pygame.image.load('skier_icon.png')
pygame.display.set_icon(icon)
except pygame.error:
print("未找到图标文件,跳过设置图标。")
# --- 游戏时钟 ---
clock = pygame.time.Clock()
# --- 字体设置 ---
# 尝试使用系统字体,如果失败则使用默认字体
try:
font_style = pygame.font.SysFont("comicsansms", 35)
except:
font_style = pygame.font.Font(None, 35)
# --- 游戏对象类 ---
class Skier(pygame.sprite.Sprite):
"""滑雪者类"""
def __init__(self):
super().__init__()
# 创建一个简单的矩形代表滑雪者
self.image = pygame.Surface([40, 50], pygame.SRCALPHA)
pygame.draw.rect(self.image, BLUE, (10, 0, 20, 40)) # 身体
pygame.draw.polygon(self.image, RED, [(0, 40), (40, 40), (20, 50)]) # 滑板
self.rect = self.image.get_rect()
# 初始位置在屏幕底部中央
self.rect.centerx = SCREEN_WIDTH // 2
self.rect.bottom = SCREEN_HEIGHT - 20
self.speed_x = 0
def update(self):
"""更新滑雪者位置"""
self.speed_x = 0
keystate = pygame.key.get_pressed()
if keystate[pygame.K_LEFT]:
self.speed_x = -8
if keystate[pygame.K_RIGHT]:
self.speed_x = 8
self.rect.x += self.speed_x
# 限制滑雪者不能移出屏幕左右边界
if self.rect.left < 0:
self.rect.left = 0
if self.rect.right > SCREEN_WIDTH:
self.rect.right = SCREEN_WIDTH
class Obstacle(pygame.sprite.Sprite):
"""障碍物类(树木或石头)"""
def __init__(self):
super().__init__()
# 随机选择是树木还是石头
obstacle_type = random.choice(['tree', 'rock'])
if obstacle_type == 'tree':
self.image = pygame.Surface([30, 40], pygame.SRCALPHA)
pygame.draw.rect(self.image, BROWN, (10, 20, 10, 20)) # 树干
pygame.draw.polygon(self.image, GREEN, [(5, 20), (25, 20), (15, 0)]) # 树冠
else: # rock
self.image = pygame.Surface([40, 30], pygame.SRCALPHA)
pygame.draw.ellipse(self.image, GRAY, (0, 0, 40, 30))
self.rect = self.image.get_rect()
# 随机出现在屏幕顶部的水平位置
self.rect.x = random.randrange(SCREEN_WIDTH - self.rect.width)
self.rect.y = random.randrange(-100, -40)
# 设置下落速度
self.speed_y = random.randrange(4, 8)
def update(self):
"""更新障碍物位置"""
self.rect.y += self.speed_y
# 如果障碍物移出屏幕底部,则重新生成在顶部
if self.rect.top > SCREEN_HEIGHT + 10:
self.rect.x = random.randrange(SCREEN_WIDTH - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speed_y = random.randrange(4, 8)
# --- 游戏主函数 ---
def game_loop():
"""游戏主循环"""
# 创建精灵组
all_sprites = pygame.sprite.Group()
obstacles = pygame.sprite.Group()
# 创建玩家
player = Skier()
all_sprites.add(player)
# 创建初始障碍物
for i in range(8):
obstacle = Obstacle()
# 确保初始障碍物不会在玩家附近生成
while pygame.sprite.collide_rect(player, obstacle):
obstacle = Obstacle()
all_sprites.add(obstacle)
obstacles.add(obstacle)
score = 0
game_over = False
# --- 游戏主循环 ---
while not game_over:
# 1. 事件处理
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# 2. 更新游戏状态
# 更新所有精灵
all_sprites.update()
# 检查玩家和障碍物的碰撞
# 如果碰撞,游戏结束
hits = pygame.sprite.spritecollide(player, obstacles, False)
if hits:
game_over = True
# 如果没有碰撞,增加分数
# 我们可以根据时间或帧数来增加分数,这里简单地在每次循环时增加
score += 1
# 3. 渲染(绘制)
# 绘制背景
screen.fill(WHITE)
# 绘制所有精灵
all_sprites.draw(screen)
# 绘制分数
score_text = font_style.render(f"分数: {score}", True, BLACK)
screen.blit(score_text, [10, 10])
# 4. 更新屏幕
pygame.display.flip()
# 控制游戏帧率
clock.tick(60)
return score
def show_score(final_score):
"""显示游戏结束画面和最终得分"""
screen.fill(WHITE)
# 显示游戏结束文字
game_over_text = font_style.render("游戏结束!", True, RED)
screen.blit(game_over_text, (SCREEN_WIDTH/2 - 100, SCREEN_HEIGHT/2 - 50))
# 显示最终得分
final_score_text = font_style.render(f"最终得分: {final_score}", True, BLACK)
screen.blit(final_score_text, (SCREEN_WIDTH/2 - 120, SCREEN_HEIGHT/2))
# 显示重新开始提示
restart_text = font_style.render("按任意键重新开始 或 ESC 退出", True, BLACK)
screen.blit(restart_text, (SCREEN_WIDTH/2 - 220, SCREEN_HEIGHT/2 + 50))
pygame.display.flip()
# 等待玩家按键
waiting = True
while waiting:
clock.tick(60)
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_ESCAPE:
pygame.quit()
sys.exit()
else:
waiting = False # 退出等待,重新开始游戏
# --- 游戏启动 ---
if __name__ == "__main__":
running = True
while running:
final_score = game_loop()
show_score(final_score)
第4步:如何运行游戏
- 确保你已经安装了 Pygame。
- 将上面的代码保存为
skier_game.py文件。 - 在终端或命令提示符中,导航到你保存文件的目录。
- 运行命令:
python skier_game.py
游戏窗口将会出现,你可以使用键盘的 左箭头 和 右箭头 键来控制滑雪者移动,躲避障碍物。

第5步:代码讲解
-
初始化与设置
pygame.init(): 初始化所有 Pygame 模块。pygame.display.set_mode(): 创建游戏主窗口。pygame.display.set_caption(): 设置窗口标题。pygame.time.Clock(): 创建一个时钟对象,用于控制游戏帧率。pygame.font.SysFont(): 加载一种系统字体,用于在屏幕上显示文字。
-
Skier类- 这个类继承自
pygame.sprite.Sprite,是 Pygame 中创建游戏对象的标准方式。 __init__: 构造函数,我们在这里创建了一个简单的蓝色矩形和红色多边形来代表滑雪者,并设置了它的初始位置。update: 这个方法在每次游戏循环中被调用,它检查键盘按键状态,并更新滑雪者的水平位置 (self.rect.x),它确保滑雪者不会移出屏幕边界。
- 这个类继承自
-
Obstacle类- 同样继承自
pygame.sprite.Sprite。 __init__: 随机选择生成“树”或“石头”,我们用简单的几何图形绘制它们,障碍物从屏幕顶部的随机水平位置生成。update: 每次循环中,障碍物会向下移动 (self.rect.y += self.speed_y),如果它移出屏幕底部,它会重新出现在顶部,实现无限滚动的效果。
- 同样继承自
-
game_loop()函数
(图片来源网络,侵删)- 这是游戏的核心循环。
- 创建精灵组:
all_sprites组包含游戏中所有可见的对象,obstacles组只包含障碍物,使用精灵组可以方便地批量更新和绘制所有对象,并进行碰撞检测。 - 事件处理: 循环检查所有事件,比如点击窗口的关闭按钮,如果发生则退出游戏。
- 更新状态: 调用
all_sprites.update()来更新所有对象的位置。pygame.sprite.spritecollide()检查玩家是否与任何障碍物发生碰撞,如果碰撞,game_over标志被设置为True。 - 渲染: 首先用
screen.fill(WHITE)清空屏幕,然后绘制所有精灵 (all_sprites.draw(screen)),最后绘制分数文本。 pygame.display.flip(): 将所有绘制的内容更新到屏幕上。clock.tick(60): 控制游戏以每秒 60 帧的速度运行。
-
show_score()函数- 当
game_loop()结束时,这个函数被调用。 - 它在屏幕上显示“游戏结束”和最终得分。
- 它进入一个循环,等待玩家按下任意键来重新开始游戏,或按
ESC键退出。
- 当
-
主程序入口 (
if __name__ == "__main__":)- 这是 Python 程序的标准入口点。
- 它创建了一个
while running循环,意味着游戏会一直进行下去。 - 每次循环,它先运行
game_loop(),然后运行show_score(),实现“玩游戏 -> 显示结果 -> 再玩游戏”的循环。
如何扩展和改进这个游戏?
- 图片资源: 用
.png图片替换简单的几何图形,让游戏看起来更精美,你可以使用pygame.image.load()加载图片。 - 难度递增: 随着分数的增加,可以增加障碍物的生成速度或下落速度。
- 音效和背景音乐: 添加
pygame.mixer模块来增加游戏的沉浸感,添加背景音乐、碰撞音效等。 - 更多元素: 增加一些有益的道具,比如金币(加分)或加速道具(临时无敌)。
- 主菜单: 创建一个主菜单界面,让玩家可以选择“开始游戏”、“查看帮助”或“退出游戏”。
