使用 VSCode 开发少儿编程项目:平台跳跃冒险游戏

平台跳跃游戏是编程学习的绝佳项目,它结合了物理模拟、碰撞检测、关卡设计和动画效果等多种概念。下面我将带您和孩子一步步在 VSCode 中创建一个有趣的平台跳跃冒险游戏。

项目概述

平台跳跃冒险游戏特点:

  1. 玩家控制一个角色在多个平台间跳跃移动
  2. 需要躲避障碍物和敌人
  3. 可以收集物品和金币增加分数
  4. 最终目标是到达关卡终点
  5. 包含重力、跳跃物理和碰撞检测

环境准备

  1. 确保已安装 Python
  2. 确保已安装 VSCode
  3. 安装 Pygame 库(在终端中运行):
    pip install pygame
    

基础版本:平台跳跃游戏

创建一个新文件,命名为 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 中,可以使用以下方法运行游戏:

  1. 使用 Code Runner 扩展(点击右上角的播放按钮)
  2. 在终端中运行:python platform_jumper.py

教学要点解析

在教孩子编写这个游戏时,可以重点讲解以下概念:

  1. 物理模拟:重力、跳跃和移动的物理效果实现
  2. 碰撞检测:使用 Pygame 的 spritecollide 方法检测碰撞
  3. 精灵和精灵组:使用面向对象方式组织游戏元素
  4. 游戏状态管理:处理游戏进行中、结束和通关等不同状态
  5. 关卡设计:通过代码设计平台、敌人和物品的布局
  6. 用户输入处理:键盘控制角色移动和跳跃

使用图片替代几何图形(可选)

如果想使用真实的图片,可以下载一些简单的图片,然后修改代码:

# 在代码开头添加图片加载部分
# 确保图片文件与代码在同一目录下

# 加载图片
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类

扩展挑战

当孩子掌握了基础版本后,可以鼓励他们尝试以下扩展:

  1. 添加更多关卡

    # 创建关卡数据
    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)
    
  2. 添加动画效果

    # 在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]
    
  3. 添加音效和背景音乐

    # 初始化音效
    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()
    
  4. 添加更多游戏元素

    # 添加弹簧类
    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游戏开发的核心概念,为孩子后续学习更复杂的游戏项目奠定了坚实基础。鼓励孩子在完成基础版本后,发挥创意设计自己的关卡和游戏机制!

更多推荐