FlxRect.getRotatedBounds无法正确获取碰撞盒?Undertale伤害系统问题
问题分析与修复
你的代码核心问题在于旋转碰撞盒时使用了错误的坐标空间和旋转参考点,导致非0角度下碰撞盒偏移。具体问题和修复方案如下:
1. 错误点:碰撞盒初始使用全局坐标定义
你用blaster.x/blaster.y(全局坐标)创建point1和point2,生成的hitbox是全局空间的矩形。当精灵旋转时,这个矩形的旋转参考点(全局中点)和精灵自身的旋转逻辑不匹配,直接导致偏移。
2. 错误点:旋转参考点的坐标空间混淆
blaster.getMidpoint()返回的是精灵的全局中点,但getRotatedBounds处理全局坐标矩形时,旋转中心需要对应精灵的实际旋转原点(默认是精灵左上角,即blaster.x + blaster.origin.x, blaster.y + blaster.origin.y),而非全局中点。
修复代码
步骤1:改用局部坐标定义碰撞盒
基于精灵的局部坐标系(左上角为(0,0))定义碰撞盒,让后续旋转逻辑和精灵自身对齐:
// 局部坐标:从精灵左上角出发计算碰撞盒的两个对角点 var localPoint1:FlxPoint = FlxPoint.weak(0, 104 * blaster.scale.y); var localPoint2:FlxPoint = FlxPoint.weak(blaster.width, blaster.height - 140 * blaster.scale.y); var localHitbox:FlxRect = new FlxRect.fromTwoPoints(localPoint1, localPoint2);
步骤2:设置并获取正确的旋转中心
如果需要让blaster以自身中点旋转,先设置对应的origin(默认origin是(0,0),即左上角):
// 可选:设置精灵以自身中点为旋转原点(未设置过的话需要添加) blaster.origin.setTo(0.5, 0.5);
再获取全局旋转中心:
var rotationCenter:FlxPoint = blaster.getMidpoint();
步骤3:计算旋转后的全局碰撞盒
将局部碰撞盒转换为全局空间,再应用旋转:
// 把局部碰撞盒转换到全局空间 var globalHitbox:FlxRect = localHitbox.copy(); globalHitbox.x += blaster.x; globalHitbox.y += blaster.y; // 生成旋转后的最终碰撞盒 globalHitbox.getRotatedBounds(blaster.angle, rotationCenter, globalHitbox);
完整修复后的代码片段
// 设置blaster以自身中点旋转(按需添加) blaster.origin.setTo(0.5, 0.5); // 局部坐标定义碰撞盒 var localPoint1:FlxPoint = FlxPoint.weak(0, 104 * blaster.scale.y); var localPoint2:FlxPoint = FlxPoint.weak(blaster.width, blaster.height - 140 * blaster.scale.y); var localHitbox:FlxRect = new FlxRect.fromTwoPoints(localPoint1, localPoint2); // 转换为全局坐标 var globalHitbox:FlxRect = localHitbox.copy(); globalHitbox.x += blaster.x; globalHitbox.y += blaster.y; // 计算旋转后的碰撞盒 var rotationCenter:FlxPoint = blaster.getMidpoint(); globalHitbox.getRotatedBounds(blaster.angle, rotationCenter, globalHitbox); // 灵魂碰撞盒保留原逻辑(无问题的话) var soulhit1:FlxPoint = FlxPoint.weak(soul.x, soul.y); var soulhit2:FlxPoint = FlxPoint.weak(soul.x + soul.width, soul.y + soul.height); var hitboxSoul:FlxRect = new FlxRect.fromTwoPoints(soulhit1, soulhit2);
额外说明
- 如果blaster不需要以中点旋转,而是用默认的左上角作为旋转原点,旋转中心应改为
FlxPoint.weak(blaster.x, blaster.y),同时局部碰撞盒的定义要对应调整。 - 尽量避免在
getRotatedBounds中用同一个FlxRect同时作为输入和输出,分开变量会更清晰,减少潜在逻辑问题。
内容的提问来源于stack exchange,提问作者Zbyszeq
相关产品推荐
相关产品推荐

