导弹拦截策略游戏火箭运动优化及敌方移除报错问题咨询
导弹拦截策略游戏开发问题
我正在开发一款导弹拦截策略游戏,尝试移除敌方飞行单位时出现报错,请问是什么原因?
- 火箭的运动逻辑可以如何优化?
- 为何敌方单位无法被正常消除?
以下是我编写的火箭构建相关代码:
stage.addEventListener(MouseEvent.CLICK, letsgoeasy) function letsgoeasy(e: MouseEvent): void { var Rocket: Hawk = new Hawk(); Rocket.x = p.x; Rocket.y = p.y; Rocket.scaleX = 0.2; Rocket.scaleY = 0.2; addChild(Rocket); Rocket.addEventListener(Event.ENTER_FRAME, moveBullet); function moveBullet(e: Event) { } var myTimer: Timer = new Timer(2000); var speedF: Number = 5; var RocketBox: Array = new Array; Rocket.addEventListener(Event.ENTER_FRAME, follow); function follow(e: Event): void { myTimer.start(); if (enemyFleet[h].y > 100) { for (var h: int = 0; h < enemyFleet.length; h++) { Rocket.x -= (Rocket.x - enemyFleet[h].x) / speedF; Rocket.x = Rocket.x + 2; Rocket.y -= (Rocket.y - enemyFleet[h].y) / speedF; Rocket.y = Rocket.y + 3; RocketBox.push(Rocket) } }
//Fire Rocket part
var smoke: smoke_shell = new smoke_shell(); addChild(smoke); smoke.scaleX = 0.1; smoke.scaleY = 0.1; smoke.x = Rocket.x smoke.y = Rocket.y + 10 smoke.rotation = 0 smoke.color = 0xE77471; smoke.blurX = 3; smoke.blurY = 3; smoke.strength = 100; smoke.quality = 3; removeChild(null); }
// collision part
addEventListener(Event.ENTER_FRAME, collCkeck); function collCkeck(e: Event): void { for (var s: int = Rocket.length - 1; s >= 0; s--) { if (Rocket.hitTestObject(enemyFleet[s])) { enemyDeaths(); } function enemyDeaths() { removeChild(Rocket); trace("Rocket"); removeChild(enemyFleet[s]); enemyFleet.splice(s, 1); } } } }
我收到的报错信息如下:
TypeError: Error #2007: Parameter child must be non-null. at
flash.display::DisplayObjectContainer/removeChild() at
Function/TrackermissileRocket190714002_fla:MainTimeline/letsgoeasy/TrackermissileRocket190714002_fla:follow()[TrackermissileRocket190714002_fla.MainTimeline::frame1:101]
我的游戏演示图如下:
问题原因及修复方案
2007报错的直接诱因
你代码中存在一行removeChild(null);,removeChild方法要求传入的参数必须是已经添加到显示列表中的有效显示对象,传入null直接触发了参数非空校验规则,删掉这行无效代码即可解决该报错。
敌方单位无法正常消除的问题
- 遍历对象错误:你写的
Rocket.length中的Rocket是单个Hawk类实例,不是存储所有火箭的数组,你定义的火箭存储数组是RocketBox,应该遍历RocketBox,否则循环根本不会执行,碰撞检测逻辑完全未生效。 - 作用域逻辑错误:你将
enemyDeaths函数定义在循环内部,循环变量s在函数实际执行时已经不是碰撞发生时对应的索引值,会导致移除对象异常。 - 变量引用顺序错误:你先判断
enemyFleet[h].y > 100,此时h变量还未定义,要把这个判断放到for循环内部。
火箭运动逻辑优化方案
- 不要在每帧执行的follow函数中重复调用
myTimer.start(),该方法仅需调用一次,重复调用会重置定时器的计时逻辑。 - 不要在for循环中重复修改单个火箭的坐标,当前逻辑下每帧火箭会遍历所有敌方单位并反复修改坐标,最终只会追踪最后一个遍历到的敌方单位,应该改为每个火箭对应单个追踪目标,或者优先筛选最近的敌方单位进行追踪。
- 不要在for循环中重复往RocketBox里push同一个火箭实例,当前逻辑下每帧每个敌方单位都会触发一次push操作,很快数组就会塞满重复无效数据,应该仅在火箭生成时往数组里push一次。
- 火箭和敌方单位被移除时,同步移除对应的ENTER_FRAME事件监听,避免内存泄漏,也能避免对象已被销毁仍执行逻辑导致的额外报错。
内容的提问来源于stack exchange,提问作者Bayat Bros
相关产品推荐
相关产品推荐

