本项目使用 Python + Pygame 实现一个简化版超级玛丽游戏,包含角色移动、跳跃、碰撞、地图绘制、敌人移动、胜利失败判定等核心功能。适合Python游戏开发入门,代码结构清晰、注释完整,可直接运行扩展。
一、环境准备
1. 安装依赖
bash
pip install pygame
2. 项目结构
plaintext
mario/
├── main.py # 主程序入口
├── settings.py # 游戏配置
├── sprites.py # 精灵类(玩家、敌人、砖块)
├── level.py # 地图与关卡
└── assets/ # 图片、音效资源(可用纯色替代)
二、完整可运行代码
1. settings.py(游戏配置)
python
# 屏幕设置
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60
# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
GRAY = (100, 100, 100)
SKY_BLUE = (135, 206, 235)
# 物理参数
GRAVITY = 0.8
PLAYER_ACC = 0.8
PLAYER_FRICTION = -0.12
JUMP_POWER = 20
# 分层
PLATFORM_LAYER = 1
ENEMY_LAYER = 2
PLAYER_LAYER = 3
2. sprites.py(精灵模块)
python
import pygame
from settings import *
class Player(pygame.sprite.Sprite):
def __init__(self, game):
super().__init__()
self.game = game
self.image = pygame.Surface((40, 60))
self.image.fill(RED)
self.rect = self.image.get_rect()
self.rect.center = (SCREEN_WIDTH // 4, SCREEN_HEIGHT // 2)
# 物理参数
self.pos = pygame.math.Vector2(self.rect.center)
self.vel = pygame.math.Vector2(0, 0)
self.acc = pygame.math.Vector2(0, 0)
self.on_ground = False
def jump(self):
if self.on_ground:
self.vel.y = -JUMP_POWER
def update(self):
# 重力
self.acc = pygame.math.Vector2(0, GRAVITY)
# 键盘控制
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
self.acc.x = -PLAYER_ACC
if keys[pygame.K_RIGHT]:
self.acc.x = PLAYER_ACC
# 摩擦力
self.acc.x += self.vel.x * PLAYER_FRICTION
# 运动公式
self.vel += self.acc
self.pos += self.vel + 0.5 * self.acc
# 边界限制
if self.pos.x < 0:
self.pos.x = 0
if self.pos.x > SCREEN_WIDTH:
self.pos.x = SCREEN_WIDTH
self.rect.midbottom = self.pos
# 地面碰撞
self.on_ground = False
hits = pygame.sprite.spritecollide(self, self.game.platforms, False)
if hits:
if self.vel.y > 0:
self.pos.y = hits[0].rect.top + 1
self.vel.y = 0
self.on_ground = True
class Platform(pygame.sprite.Sprite):
def __init__(self, x, y, w, h):
super().__init__()
self.image = pygame.Surface((w, h))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
class Enemy(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((30, 40))
self.image.fill(BLACK)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.speed = 2
self.direction = 1
def update(self):
self.rect.x += self.speed * self.direction
# 碰到边界折返
if self.rect.left < 0 or self.rect.right > SCREEN_WIDTH:
self.direction *= -1
3. level.py(地图生成)
python
from sprites import Platform
def create_level(all_sprites, platforms):
# 地面
plat = Platform(0, 580, 800, 20)
all_sprites.add(plat)
platforms.add(plat)
# 砖块平台
platforms_list = [
(200, 500, 100, 20),
(400, 450, 100, 20),
(600, 400, 100, 20),
(150, 350, 80, 20),
(350, 300, 80, 20),
(550, 250, 120, 20),
]
for p in platforms_list:
plat = Platform(*p)
all_sprites.add(plat)
platforms.add(plat)
4. main.py(主程序)
python
import pygame
import sys
from settings import *
from sprites import Player, Platform, Enemy
from level import create_level
class Game:
def __init__(self):
pygame.init()
self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("超级玛丽 - Python版")
self.clock = pygame.time.Clock()
self.running = True
self.font = pygame.font.SysFont(None, 40)
# 精灵组
self.all_sprites = pygame.sprite.Group()
self.platforms = pygame.sprite.Group()
self.enemies = pygame.sprite.Group()
# 创建玩家
self.player = Player(self)
self.all_sprites.add(self.player)
# 创建关卡
create_level(self.all_sprites, self.platforms)
# 创建敌人
e1 = Enemy(250, 460)
e2 = Enemy(450, 410)
self.all_sprites.add(e1, e2)
self.enemies.add(e1, e2)
def run(self):
while self.running:
self.clock.tick(FPS)
self.events()
self.update()
self.draw()
def events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
self.player.jump()
def update(self):
self.all_sprites.update()
# 死亡判定:踩敌人 or 被敌人碰
hits = pygame.sprite.spritecollide(self.player, self.enemies, False)
if hits:
# 从上往下踩
if self.player.vel.y > 0:
hits[0].kill()
else:
self.game_over()
# 胜利:到达最顶端
if self.player.rect.top < 50:
self.win()
def draw(self):
self.screen.fill(SKY_BLUE)
self.all_sprites.draw(self.screen)
pygame.display.flip()
def game_over(self):
text = self.font.render("GAME OVER", True, RED)
self.screen.blit(text, (SCREEN_WIDTH//2 - 80, SCREEN_HEIGHT//2))
pygame.display.flip()
pygame.time.wait(2000)
self.running = False
def win(self):
text = self.font.render("YOU WIN!", True, BLUE)
self.screen.blit(text, (SCREEN_WIDTH//2 - 80, SCREEN_HEIGHT//2))
pygame.display.flip()
pygame.time.wait(2000)
self.running = False
if __name__ == "__main__":
game = Game()
game.run()
pygame.quit()
sys.exit()
三、代码逐模块深度解析
1. 项目整体逻辑
游戏采用面向对象+精灵系统,Pygame 精灵(Sprite)适合管理独立运动物体(玩家、敌人、砖块)。
流程:初始化 → 事件监听 → 物理更新 → 碰撞检测 → 画面渲染 → 循环。
2. settings.py 配置解析
统一管理屏幕大小、重力、摩擦力、跳跃力度、颜色。
- GRAVITY:下落加速度,值越大下落越快
- PLAYER_ACC:水平移动加速度
- PLAYER_FRICTION:地面阻力,让移动更平滑
- JUMP_POWER:跳跃初速度,负值向上
3. sprites.py 精灵类解析
(1)Player 类
- 使用 Vector2 存储位置、速度、加速度,比直接改 rect 更精准
- 运动公式: vel += acc 、 pos += vel + 0.5*acc 是标准匀变速运动
- on_ground 防止空中连跳
- 碰撞平台时修正坐标,避免穿模
(2)Platform 类
静态障碍物,仅绘制不运动,用于地面和砖块。
(3)Enemy 类
左右来回移动,碰到屏幕边界折返。
4. level.py 关卡解析
通过列表批量生成平台,便于扩展多关卡、大地图。可替换为地图文件读取(txt/JSON)。
5. main.py 主循环解析
- run():游戏主循环
- events():监听退出、跳跃事件
- update():更新所有精灵、碰撞判定、胜负条件
- draw():填充背景、绘制精灵、刷新屏幕
- game_over() / win():结束画面与退出
四、核心机制讲解
1. 物理引擎(关键)
- 重力持续给Y轴加速度
- 水平移动加摩擦力,实现平滑启停
- 跳跃只有在地面状态才生效
2. 碰撞判定
- spritecollide 检测玩家与平台、敌人
- 踩敌人:玩家Y速度向下 → 消灭敌人
- 被敌人碰:玩家非下落