AS3如何解决碰撞物体数秒后穿透碰撞体继续下落的问题
问题原因
- 实例属性访问错误:
yVel是Enemy类的实例成员,原代码中Class(Enemy).yVel = 0是对类的静态属性赋值,完全不会修改当前enemy实例的yVel值。重力会持续累加yVel,当数值大到单帧位移超过碰撞修正的阈值时,enemy就会直接穿透ground,这就是2-6秒后才出现异常的核心原因。 - 事件执行顺序冲突:Enemy类内部和主时间轴都绑定了enterFrame事件,两者执行顺序没有固定优先级,如果先执行碰撞修正再执行Enemy的位移逻辑,碰撞修正后的坐标会被直接覆盖。
- 位移逻辑错误:Enemy类的
onEnterFrame中直接写this.x = xVel、this.y = yVel,错误将速度值当做坐标值使用,你在主时间轴设置的初始x=400也会被直接覆盖为0。 - 碰撞修正逻辑冗余:每次碰撞仅将y减少0.1的处理效率极低,yVel过大时根本抵消不了单帧的位移量。
修正代码
主时间轴代码
stop(); // 请将下方赋值替换为你舞台上ground元件的实例名 var ground: MovieClip = stage.getChildByName("ground") as MovieClip; var enemy:Enemy = new Enemy(); stage.addChild(enemy); enemy.x = 400; enemy.y = 150; enemy.rotation = 0; enemy.addEventListener("enterFrame", collisions); function collisions(e: Event): void { var collision: Boolean = ground.hitTestObject(enemy); if (collision) { // 此处默认两个元件的注册点为中心,若注册点在左上角请改为 enemy.y = ground.y - enemy.height enemy.y = ground.y - enemy.height/2; // 直接修改实例的yVel属性 enemy.yVel = 0; } }
Enemy类代码
package { import flash.display.MovieClip; import flash.events.Event; public class Enemy extends MovieClip { // 设为public允许外部访问属性 public var xVel: int = 0; public var yVel: int = 0; public function Enemy() { addEventListener("enterFrame", onEnterFrame); } private function onEnterFrame(e: Event): void { yVel += 2; // 速度叠加到当前坐标,而非直接赋值坐标 this.x += xVel; this.y += yVel; } } }
额外优化建议
如果要彻底避免enterFrame执行顺序的问题,可以直接将碰撞检测逻辑写到Enemy类的onEnterFrame方法中,执行位移后马上做碰撞修正,逻辑会更稳定。
内容的提问来源于stack exchange,提问作者Alex Smart
相关产品推荐
相关产品推荐

