当前位置:首页>python>Python实战项目之超级玛利亚

Python实战项目之超级玛利亚

  • 2026-09-02 19:41:08
Python实战项目之超级玛利亚

本项目使用 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速度向下 → 消灭敌人

- 被敌人碰:玩家非下落

最新文章

随机文章