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

如何在Pygame中实现无类的最简碰撞检测系统?

Pygame 无类实现简单碰撞检测方案

原代码核心问题

  • move函数无法访问主循环中定义的player、block矩形对象,存在作用域错误
  • 错误覆盖time时钟对象,导致时间计算逻辑混乱
  • 碰撞位置修正的计算逻辑有误

修正后的完整代码

import pygame
from pygame.locals import *
from sys import exit

pygame.init()

G = 9.807  # 重力加速度
screen = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()  # 重命名避免与时间变量冲突

y_speed = 0
playersize = [20, 20]
playerpos = [0, 0]
# 提前定义方块矩形,无需每次绘制时重新生成
block_rect = pygame.Rect(100, 380, 20, 20)

def move(dx):
    global playerpos
    # 先执行移动,再检测碰撞
    playerpos[0] += dx
    # 生成当前玩家的矩形对象
    player_rect = pygame.Rect(playerpos[0], playerpos[1], playersize[0], playersize[1])
    
    # 检测与方块的碰撞
    if player_rect.colliderect(block_rect):
        # 根据移动方向修正位置,避免卡入方块
        if dx > 0:
            # 向右移动碰撞:将玩家左边缘对齐方块右边缘
            playerpos[0] = block_rect.right
        else:
            # 向左移动碰撞:将玩家右边缘对齐方块左边缘
            playerpos[0] = block_rect.left - playersize[0]

while True:
    dt = clock.tick(30) / 1000  # 获取帧间隔时间(秒),用于物理计算
    screen.fill((255,255,255))
    
    # 绘制玩家和方块,同时获取玩家矩形
    player_rect = pygame.draw.rect(screen, (255,0,0), (playerpos[0], playerpos[1], playersize[0], playersize[1]))
    pygame.draw.rect(screen, (0,0,0), block_rect)

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            exit()
        if event.type == KEYDOWN:
            if event.key in (K_SPACE, K_UP, K_w):
                # 仅当玩家站在地面时允许跳跃
                if playerpos[1] >= 380 - playersize[1]:
                    y_speed = -5

    # 重力加速度计算
    y_speed += G * dt
    playerpos[1] += y_speed
    
    # 地面碰撞检测与修正
    if playerpos[1] >= 380 - playersize[1]:
        playerpos[1] = 380 - playersize[1]
        y_speed = 0
    
    # 左右移动控制
    keys = pygame.key.get_pressed()
    if keys[K_a] or keys[K_LEFT]:
        move(-5)
    if keys[K_d] or keys[K_RIGHT]:
        move(5)
        
    pygame.display.update()

关键修改说明

  • 作用域修复:在move函数内动态生成玩家矩形,或提前将方块矩形设为全局变量,确保函数能访问碰撞所需的矩形对象
  • 时钟逻辑修复:将原time变量重命名为clock,避免覆盖时钟对象,用clock.tick()直接获取帧间隔时间dt,保证重力计算稳定
  • 碰撞逻辑优化:移动后立即检测碰撞,根据移动方向直接修正玩家位置,彻底避免卡入方块的问题
  • 跳跃条件优化:用玩家高度计算地面位置,替换硬编码数值,适配不同尺寸的玩家角色

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:01:56