为什么我编写的Pygame敌人移动脚本无法正常运行?
问题根因
- 整数坐标截断问题:pygame的
Rect对象的x、y属性默认是整数类型,你设置的移动速度是0.01,每次叠加的位移值小于1时,会被自动截断为整数,导致坐标无实际变化,卡在原地。比如当坐标为0时,叠加小于1的正数后会被强制转换为0,永远无法离开0坐标位置。 - 除零错误问题:当敌人和玩家坐标完全重合时,
dist = math.hypot(dx, dy)的结果为0,此时执行dx / dist会触发除零错误,导致逻辑中断,敌人直接停住。 - 速度值设置不合理:0.01的速度每帧位移极小,正常60帧的情况下每秒仅移动0.6像素,肉眼几乎无法观察到移动效果。
修复方案
修改后的完整代码如下:
import pygame import math ALPHA = (0, 255, 0) path = "data/chr/squid.png" def findDist(coords1, coords2): try: return math.sqrt(pow(coords1[0] - coords2[0], 2) + pow(coords1[1] - coords2[1], 2)) except: print("invalid dist input, ignoring") class Squid(pygame.sprite.Sprite): # 敌人类 def __init__(self, X, Y): pygame.sprite.Sprite.__init__(self) self.speed = 2 # 可根据需求调整移动速度大小 self.images = [] for i in range(1, 5): img = pygame.image.load(path).convert() img.convert_alpha() img.set_colorkey(ALPHA) self.images.append(img) self.image = self.images[0] self.rect = self.image.get_rect() # 新增浮点类型属性存储精确坐标,避免整数截断 self.x = float(X) self.y = float(Y) self.rect.x = X self.rect.y = Y def chasePlayer(self, player): dx = player.rect.x - self.x dy = player.rect.y - self.y dist = math.hypot(dx, dy) # 距离小于单次移动距离时停止,避免除零和碰撞后抖动 if dist < self.speed: # 可在此处添加碰到玩家后的触发逻辑 return dx, dy = dx / dist, dy / dist # 先更新精确浮点坐标 self.x += dx * self.speed self.y += dy * self.speed # 可选:边界判断,避免敌人移出屏幕卡住 screen_width = pygame.display.get_surface().get_width() screen_height = pygame.display.get_surface().get_height() self.x = max(0, min(self.x, screen_width - self.rect.width)) self.y = max(0, min(self.y, screen_height - self.rect.height)) # 同步精确坐标到Rect对象用于渲染和碰撞检测 self.rect.x = int(self.x) self.rect.y = int(self.y)
核心修改点说明:
- 新增
self.x和self.y两个浮点属性存储精确位置,避免直接操作Rect的整数属性导致的精度丢失 - 调整speed到合理的数值范围,可根据实际游戏需求调整大小
- 增加距离判断逻辑,避免除零错误,同时敌人到达玩家位置后不会出现来回抖动的问题
- 可选添加边界判断逻辑,避免敌人移动到屏幕外区域卡住
内容的提问来源于stack exchange,提问作者Turb000
相关产品推荐
相关产品推荐

