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

PyGame中两个类无法交互求助:碰撞检测失效问题排查

碰撞检测失效问题的解决方案

问题根源

你的代码存在两个核心问题导致碰撞检测无法正常工作:

  1. 实例不统一:Rock类的__init__方法中新建了self.player = Player(),这是一个完全独立于主循环中你控制的player的新实例,两者的位置状态毫无关联,所以碰撞检测永远无法匹配。
  2. 移动方向错误:Player类的移动逻辑搞反了方向,按左键时x坐标应该减少,右键时x坐标应该增加,否则人物移动方向和按键操作不符。

修复步骤

  1. 修改Rock类的初始化方法,让它接收外部的Player实例作为参数,不再内部新建Player。
  2. 修正Player类的移动方向逻辑。
  3. 创建Rock对象时,将主循环中控制的player传入。

修改后的完整代码

import pygame
import random
import time 
from pygame.locals import *

vec = pygame.math.Vector2
pygame.init()
FPS = 30
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
WHITE = (255, 255, 255)
GRAY = (127, 127, 127)
BLACK = (0, 0, 0)
BLUEGREEN = (0, 255, 170)
MARRON = (115, 0, 0)
LIME = (180, 255, 100)
PINK = (255, 100, 180)
PURPLE = (240,0,255)
GRAY = (127,127,127)
MAGENTA = (255,0,230)
BROWN = (100,40,0)
FORESTGREEN = (0,50,0)
NAVYBLUE = (0,0,100)
RUST = (210,150,75)
DANYELLOW = (255,200,0)
HIGHLIGHTER = (255,255,100)
SKYBLUE = (0,255,255)
LIGHTGRAY = (200,200,200)
DARKGRAY = (50,50,50)
TAN = (230,220,170)
COFFEEBROWN =(200,190,140)
MOONGLOW = (235,245,255)

HEIGHT = 800
WIDTH = 500
Font = pygame.font.SysFont('timesnewroman', 30)

gamedisplay = pygame.display.set_mode((HEIGHT, WIDTH))
clock = pygame.time.Clock()

class Player():
    def __init__(self):
        # 状态属性
        self.right_image = pygame.Surface((30, 30))
        self.right_image.fill(RED)

        self.left_image = pygame.Surface((30, 30))
        self.left_image.fill(RED)

        self.up_image = pygame.Surface((30, 30))
        self.up_image.fill(RED)

        self.down_image = pygame.Surface((30, 30))
        self.down_image.fill(RED)
        self.health = 100
        self.hunger = 100
        self.thrist = 100
        self.temperature = 100
        # 位置与显示
        self.x = 50
        self.y = 50
        self.plyrimg = pygame.Surface((40, 40))
        self.rect_plyr = self.plyrimg.get_rect()
        # 初始化玩家初始位置
        self.rect_plyr.topleft = (self.x, self.y)
        # 移动属性
        self.width = 40
        self.height = 60
        self.vel = 8

    def player_movement(self):
       keys = pygame.key.get_pressed()
        
       if keys[pygame.K_LEFT]:
                  self.rect_plyr.x -= self.vel

       if keys[pygame.K_RIGHT]:
                  self.rect_plyr.x += self.vel

       if keys[pygame.K_UP]:
                  self.rect_plyr.y -= self.vel

       if keys[pygame.K_DOWN]:
                  self.rect_plyr.y += self.vel

    def interact(self,rct):
     
     if self.rect_plyr.colliderect(rct):
        print('hey')
     else:
         print('h')
         
    def Draw(self, display):
      display.blit(self.plyrimg, self.rect_plyr)

# 地形类
class Rock():
  def __init__(self, player):
    # 状态属性
    self.health = 400
    # 位置与显示
    self.x = 50
    self.y = 50
    self.rckimg = pygame.Surface((40, 40))
    self.rect_rck = self.rckimg.get_rect()
    self.player = player  # 接收外部传入的玩家实例
     # 其他属性
    self.width = 40
    self.height = 60
    self.vel = 5
    self.rect_rck.center = (200 // 2, 200 // 2)

  def Draw(self, display):
    display.blit(self.rckimg, self.rect_rck)

  def Multiply(self):
    self.player.interact(self.rect_rck)

class plant():
  def __init__(self):
    pass

# 主循环相关实例
player = Player()
rock = Rock(player)  # 创建岩石时传入主玩家实例
def Game():
  gamedisplay.fill(GREEN)
  player.player_movement()
  player.Draw(gamedisplay)
  rock.Draw(gamedisplay)
  rock.Multiply()
  
# 菜单类
class menu():
  def __init__(self):
    pass
  
# 主循环
while True:
  clock.tick(FPS)
  
  for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()  # 避免退出后报错
  Game()
 
  pygame.display.update()

额外优化说明

  • 给Player的rect设置了初始位置topleft = (self.x, self.y),确保玩家初始位置符合预期。
  • 在退出pygame后添加了exit(),避免程序崩溃报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 12:37:52