使用 VSCode 开发少儿编程项目:平台跳跃冒险游戏
·
使用 VSCode 开发少儿编程项目:平台跳跃冒险游戏
平台跳跃游戏是编程学习的绝佳项目,它结合了物理模拟、碰撞检测、关卡设计和动画效果等多种概念。下面我将带您和孩子一步步在 VSCode 中创建一个有趣的平台跳跃冒险游戏。
项目概述
平台跳跃冒险游戏特点:
- 玩家控制一个角色在多个平台间跳跃移动
- 需要躲避障碍物和敌人
- 可以收集物品和金币增加分数
- 最终目标是到达关卡终点
- 包含重力、跳跃物理和碰撞检测
环境准备
基础版本:平台跳跃游戏
创建一个新文件,命名为 platform_jumper.py,然后输入以下代码:
# 平台跳跃冒险游戏 - 使用Pygame
import pygame
import sys
import random
# 初始化Pygame
pygame.init()
# 游戏窗口设置
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("平台跳跃冒险")
# 颜色定义
SKY_BLUE = (135, 206, 235)
BROWN = (139, 69, 19)
GREEN = (34, 139, 34)
RED = (255, 0, 0)
YELLOW = (255, 215, 0)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
# 游戏时钟
clock = pygame.time.Clock()
FPS = 60
# 重力常数
GRAVITY = 0.5
# 玩家类
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((30, 50))
self.image.fill(RED)
self.rect = self.image.get_rect()
self.rect.center = (100, 100)
self.velocity_x = 0
self.velocity_y = 0
self.jump_power = -12
self.speed = 5
self.on_ground = False
self.score = 0
self.health = 3
def update(self, platforms):
# 应用重力
self.velocity_y += GRAVITY
# 水平移动
self.rect.x += self.velocity_x
# 检测水平碰撞
platform_hit = pygame.sprite.spritecollide(self, platforms, False)
for p in platform_hit:
if self.velocity_x > 0: # 向右移动
self.rect.right = p.rect.left
elif self.velocity_x < 0: # 向左移动
self.rect.left = p.rect.right
# 垂直移动
self.rect.y += self.velocity_y
self.on_ground = False
# 检测垂直碰撞
platform_hit = pygame.sprite.spritecollide(self, platforms, False)
for p in platform_hit:
if self.velocity_y > 0: # 下落
self.rect.bottom = p.rect.top
self.velocity_y = 0
self.on_ground = True
elif self.velocity_y < 0: # 跳跃
self.rect.top = p.rect.bottom
self.velocity_y = 0
# 限制玩家不超出屏幕左右边界
if self.rect.left < 0:
self.rect.left = 0
if self.rect.right > WIDTH:
self.rect.right = WIDTH
# 如果掉出屏幕底部,重置位置
if self.rect.top > HEIGHT:
self.rect.center = (100, 100)
self.velocity_y = 0
self.health -= 1
def jump(self):
if self.on_ground:
self.velocity_y = self.jump_power
def move_left(self):
self.velocity_x = -self.speed
def move_right(self):
self.velocity_x = self.speed
def stop(self):
self.velocity_x = 0
# 平台类
class Platform(pygame.sprite.Sprite):
def __init__(self, x, y, width, height):
super().__init__()
self.image = pygame.Surface((width, height))
self.image.fill(BROWN)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
# 金币类
class Coin(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((20, 20), pygame.SRCALPHA)
pygame.draw.circle(self.image, YELLOW, (10, 10), 10)
self.rect = self.image.get_rect()
self.rect.center = (x, y)
# 敌人类
class Enemy(pygame.sprite.Sprite):
def __init__(self, x, y, distance):
super().__init__()
self.image = pygame.Surface((30, 30))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.distance = distance
self.start_x = x
self.direction = 1
self.speed = 2
def update(self):
self.rect.x += self.speed * self.direction
# 改变方向
if self.rect.x > self.start_x + self.distance:
self.direction = -1
elif self.rect.x < self.start_x:
self.direction = 1
# 终点类
class Goal(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((40, 40))
self.image.fill((0, 255, 255)) # 青色
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
# 创建精灵组
all_sprites = pygame.sprite.Group()
platforms = pygame.sprite.Group()
coins = pygame.sprite.Group()
enemies = pygame.sprite.Group()
# 创建玩家
player = Player()
all_sprites.add(player)
# 创建平台 - 可以设计你自己的关卡布局
platform_positions = [
(0, HEIGHT - 40, WIDTH, 40), # 地面
(100, 400, 200, 20),
(400, 350, 200, 20),
(200, 300, 150, 20),
(500, 250, 100, 20),
(300, 200, 200, 20),
(100, 150, 100, 20),
(600, 150, 100, 20),
(700, 500, 100, 20) # 终点平台
]
for pos in platform_positions:
p = Platform(*pos)
all_sprites.add(p)
platforms.add(p)
# 创建金币
coin_positions = [
(200, 380),
(450, 330),
(250, 280),
(550, 230),
(350, 180),
(150, 130),
(650, 130)
]
for pos in coin_positions:
c = Coin(*pos)
all_sprites.add(c)
coins.add(c)
# 创建敌人
enemy_positions = [
(300, 380, 100), # (x, y, 移动距离)
(500, 180, 80)
]
for pos in enemy_positions:
e = Enemy(*pos)
all_sprites.add(e)
enemies.add(e)
# 创建终点
goal = Goal(740, 460)
all_sprites.add(goal)
# 游戏状态
game_over = False
level_complete = False
font = pygame.font.SysFont(None, 36)
# 游戏主循环
running = True
while running:
# 控制游戏速度
clock.tick(FPS)
# 处理事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
player.jump()
elif event.key == pygame.K_r and (game_over or level_complete):
# 重置游戏
player.rect.center = (100, 100)
player.velocity_y = 0
player.score = 0
player.health = 3
game_over = False
level_complete = False
# 重新生成金币
for c in coins:
all_sprites.add(c)
coins.empty()
for pos in coin_positions:
c = Coin(*pos)
all_sprites.add(c)
coins.add(c)
if not game_over and not level_complete:
# 获取按键状态
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player.move_left()
elif keys[pygame.K_RIGHT]:
player.move_right()
else:
player.stop()
# 更新
player.update(platforms)
enemies.update()
# 检测金币收集
coin_hits = pygame.sprite.spritecollide(player, coins, True)
for coin in coin_hits:
player.score += 10
# 检测敌人碰撞
enemy_hits = pygame.sprite.spritecollide(player, enemies, False)
if enemy_hits:
player.health -= 1
player.rect.center = (100, 100)
player.velocity_y = 0
if player.health <= 0:
game_over = True
# 检测是否到达终点
if pygame.sprite.collide_rect(player, goal):
level_complete = True
# 绘制
screen.fill(SKY_BLUE)
all_sprites.draw(screen)
# 显示分数和生命值
score_text = font.render(f"分数: {player.score}", True, BLACK)
health_text = font.render(f"生命: {player.health}", True, BLACK)
screen.blit(score_text, (10, 10))
screen.blit(health_text, (10, 50))
# 游戏结束或通关显示
if game_over:
game_over_text = font.render("游戏结束! 按R键重新开始", True, RED)
screen.blit(game_over_text, (WIDTH//2 - 150, HEIGHT//2))
if level_complete:
level_complete_text = font.render("关卡通过! 按R键重新开始", True, GREEN)
screen.blit(level_complete_text, (WIDTH//2 - 150, HEIGHT//2))
# 更新显示
pygame.display.flip()
# 退出游戏
pygame.quit()
sys.exit()
运行游戏
在 VSCode 中,可以使用以下方法运行游戏:
- 使用 Code Runner 扩展(点击右上角的播放按钮)
- 在终端中运行:
python platform_jumper.py
教学要点解析
在教孩子编写这个游戏时,可以重点讲解以下概念:
- 物理模拟:重力、跳跃和移动的物理效果实现
- 碰撞检测:使用 Pygame 的
spritecollide方法检测碰撞 - 精灵和精灵组:使用面向对象方式组织游戏元素
- 游戏状态管理:处理游戏进行中、结束和通关等不同状态
- 关卡设计:通过代码设计平台、敌人和物品的布局
- 用户输入处理:键盘控制角色移动和跳跃
使用图片替代几何图形(可选)
如果想使用真实的图片,可以下载一些简单的图片,然后修改代码:
# 在代码开头添加图片加载部分
# 确保图片文件与代码在同一目录下
# 加载图片
player_img = pygame.image.load('player.png').convert_alpha()
platform_img = pygame.image.load('platform.png').convert_alpha()
coin_img = pygame.image.load('coin.png').convert_alpha()
enemy_img = pygame.image.load('enemy.png').convert_alpha()
goal_img = pygame.image.load('goal.png').convert_alpha()
# 在相应的类中修改
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = player_img # 使用图片替代Surface
self.rect = self.image.get_rect()
# 其余代码保持不变
# 同样修改Platform、Coin、Enemy和Goal类
扩展挑战
当孩子掌握了基础版本后,可以鼓励他们尝试以下扩展:
-
添加更多关卡:
# 创建关卡数据 levels = [ # 第一关 { "platforms": [(0, HEIGHT - 40, WIDTH, 40), (100, 400, 200, 20), ...], "coins": [(200, 380), (450, 330), ...], "enemies": [(300, 380, 100), (500, 180, 80)], "goal": (740, 460) }, # 第二关 { "platforms": [...], "coins": [...], "enemies": [...], "goal": (...) } ] current_level = 0 def load_level(level_index): # 清空当前精灵 all_sprites.empty() platforms.empty() coins.empty() enemies.empty() # 加载新关卡数据 level_data = levels[level_index] # 创建平台 for pos in level_data["platforms"]: p = Platform(*pos) all_sprites.add(p) platforms.add(p) # 创建金币、敌人和终点... # 最后添加玩家 all_sprites.add(player) -
添加动画效果:
# 在Player类中添加动画相关代码 class Player(pygame.sprite.Sprite): def __init__(self): super().__init__() self.frames_right = [] # 向右移动的动画帧 self.frames_left = [] # 向左移动的动画帧 self.current_frame = 0 self.animation_time = 0 self.direction = "right" # 默认朝向 # 加载动画帧 for i in range(4): # 假设有4帧动画 frame = pygame.image.load(f"player_right_{i}.png").convert_alpha() self.frames_right.append(frame) frame = pygame.image.load(f"player_left_{i}.png").convert_alpha() self.frames_left.append(frame) self.image = self.frames_right[0] self.rect = self.image.get_rect() def update(self, platforms): # 原有更新代码... # 动画更新 self.animation_time += 1 if self.animation_time % 5 == 0: # 每5帧更新一次动画 self.current_frame = (self.current_frame + 1) % len(self.frames_right) if self.velocity_x > 0: # 向右移动 self.direction = "right" self.image = self.frames_right[self.current_frame] elif self.velocity_x < 0: # 向左移动 self.direction = "left" self.image = self.frames_left[self.current_frame] else: # 静止 if self.direction == "right": self.image = self.frames_right[0] # 使用第一帧作为静止状态 else: self.image = self.frames_left[0] -
添加音效和背景音乐:
# 初始化音效 pygame.mixer.init() # 加载音效 jump_sound = pygame.mixer.Sound('jump.wav') coin_sound = pygame.mixer.Sound('coin.wav') hurt_sound = pygame.mixer.Sound('hurt.wav') victory_sound = pygame.mixer.Sound('victory.wav') # 在相应的地方播放音效 def jump(self): if self.on_ground: self.velocity_y = self.jump_power jump_sound.play() # 播放跳跃音效 # 在收集金币时播放音效 coin_hits = pygame.sprite.spritecollide(player, coins, True) for coin in coin_hits: player.score += 10 coin_sound.play() -
添加更多游戏元素:
# 添加弹簧类 class Spring(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() self.image = pygame.Surface((20, 10)) self.image.fill((255, 165, 0)) # 橙色 self.rect = self.image.get_rect() self.rect.x = x self.rect.y = y def apply_effect(self, player): player.velocity_y = -18 # 更强的跳跃力 # 在游戏循环中检测弹簧碰撞 spring_hits = pygame.sprite.spritecollide(player, springs, False) for spring in spring_hits: spring.apply_effect(player)
学习收获
通过这个项目,孩子将学会:
- 物理模拟和碰撞检测的实现
- 面向对象编程在游戏开发中的应用
- 游戏状态管理和关卡设计
- 动画效果和用户输入处理
- 调试复杂系统和解决问题的能力
- 创意表达和游戏设计思维
平台跳跃冒险项目是游戏编程的综合性练习,它涵盖了2D游戏开发的核心概念,为孩子后续学习更复杂的游戏项目奠定了坚实基础。鼓励孩子在完成基础版本后,发挥创意设计自己的关卡和游戏机制!
更多推荐



所有评论(0)