You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pygame中为超级马里奥实现图像滑动窗口算法?

实现Pygame马里奥地图的滑动窗口(相机跟随)

你的代码目前存在几个关键问题导致无法实现地图部分显示:

  • 主循环内嵌套了另一个while True循环,导致马里奥移动逻辑完全无法执行,程序直接卡在地图绘制循环里
  • 每次循环都重新加载并缩放地图,严重影响性能
  • 直接将完整地图绘制到窗口,没有做视口裁剪

要实现滑动窗口(相机跟随),核心是通过跟踪相机偏移量,只绘制地图在窗口范围内的部分,同时让相机跟随马里奥移动。以下是修改后的完整代码及关键逻辑解释:

import pygame
import pygame.transform 

pygame.init()

# 窗口尺寸
WIN_WIDTH = 640
WIN_HEIGHT = 480
window = pygame.display.set_mode((WIN_WIDTH, WIN_HEIGHT))
pygame.display.set_caption("Mario Game")

# 预加载资源(避免循环内重复加载)
mario_left = pygame.image.load("F:\\Mario in Python\\Mario_Standing_Left.png").convert_alpha()
mario_right = pygame.image.load("F:\\Mario in Python\\Mario_Standing_Right.png").convert_alpha()
# 适配地图比例缩放马里奥
mario_left = pygame.transform.smoothscale(mario_left, (40, 60))
mario_right = pygame.transform.smoothscale(mario_right, (40, 60))
mario_width = mario_left.get_width()
mario_height = mario_left.get_height()

# 加载并缩放地图(仅执行一次)
world_map = pygame.image.load('World 1-1.png').convert()
world_map = pygame.transform.smoothscale(world_map, (8750, 1400))
map_width = world_map.get_width()
map_height = world_map.get_height()

# 马里奥初始状态
mario_x = 50
mario_y = 430
speed = 5
is_jump = False
jump_count = 10
facing_left = False

# 相机偏移量(控制地图显示范围)
camera_x = 0
camera_y = 0
# 相机跟随边界:让马里奥保持在屏幕中间区域
camera_border_left = WIN_WIDTH // 3
camera_border_right = WIN_WIDTH - camera_border_left

run = True
clock = pygame.time.Clock()  # 稳定控制帧率

while run:
    clock.tick(60)  # 锁定60帧
    
    # 事件处理
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    # 马里奥移动逻辑
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT] and mario_x > speed:
        mario_x -= speed
        facing_left = True
    if keys[pygame.K_RIGHT] and mario_x < map_width - mario_width - speed:
        mario_x += speed
        facing_left = False
    if not is_jump:
        if keys[pygame.K_SPACE]:
            is_jump = True
    else:
        if jump_count >= -10:
            neg = 1
            if jump_count < 0:
                neg = -1
            mario_y -= (jump_count ** 2) * 0.5 * neg
            jump_count -= 1
        else:
            is_jump = False
            jump_count = 10

    # 更新相机偏移(滑动窗口核心)
    # 水平方向跟随:马里奥超出屏幕左右边界区域时,相机同步移动
    if mario_x - camera_x > camera_border_right:
        camera_x = mario_x - camera_border_right
    elif mario_x - camera_x < camera_border_left:
        camera_x = mario_x - camera_border_left
    # 限制相机不超出地图范围
    camera_x = max(0, min(camera_x, map_width - WIN_WIDTH))
    # 垂直方向跟随(可选,马里奥1-1以水平滚动为主)
    camera_y = max(0, min(camera_y, map_height - WIN_HEIGHT))

    # 绘制流程
    window.fill((0, 0, 0))
    # 绘制偏移后的地图,只显示窗口范围内的部分
    window.blit(world_map, (-camera_x, -camera_y))
    # 绘制马里奥:位置需减去相机偏移量,保证相对位置正确
    if facing_left:
        window.blit(mario_left, (mario_x - camera_x, mario_y - camera_y))
    else:
        window.blit(mario_right, (mario_x - camera_x, mario_y - camera_y))

    pygame.display.update()

pygame.quit()

关键逻辑说明

  1. 资源预加载:将地图、角色图片的加载和缩放放在主循环外,避免重复操作消耗性能。
  2. 相机偏移控制:通过camera_x、camera_y控制地图的显示起始位置,当马里奥移动到屏幕边界区域时,相机同步移动,保持角色在视野内。同时用max/min限制偏移范围,防止显示地图外的空白。
  3. 绘制顺序:先绘制偏移后的地图,再绘制角色,角色位置需减去相机偏移量,确保角色与地图的相对位置正确。
  4. 帧率稳定:用Clock.tick()替代delay,让游戏帧率更稳定流畅。

内容的提问来源于stack exchange,提问作者Asad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 00:55:24