我遇到了一个非常具有挑战性的问题,我很乐意得到一些支持。 这是场景:
主Game类实例为Level1 Class负责通过嵌套的For循环产生敌人并将它们推送到数组。 然后检查Bullet和Enemy之间的冲突,如果发现碰撞,它会调用Enemy类中的一个方法,该方法从数组中删除removeChild和Splice本身。
事情是它适用于前几个敌人,然后它将挑选错误的敌人来摧毁,并完全停止运作。 我尝试使用indexOf来确保我指的是正确的对象,但无济于事。 我认为Pslice和removeChild指向不同的对象。
当我将removeChild和splice从Game Class移动到Enmy类时,这个混乱局面出现了
链接到正在进行的工作:https://dl.dropboxusercontent.com/s/69hcmzygnkx7h1e/space_shooter.swf
我想在这方面提供一些帮助。 谢谢!!!
主要课程:Game.AS
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.text.*;
import flash.geom.Point;
public class Game extends MovieClip
{
public var _instance : Game;
public var player:Player;
public static var level1:Level1;
public var bullet:Bullet;
private var bullets_arr:Array;
var fire_on : Boolean;
var fire_counter : int;
public function Game()
{
level1=new Level1(this.stage);
player = new Player ;
addChild(player);
player.y = 600;
bullets_arr = [];
addEventListener(Event.ENTER_FRAME,Main);
stage.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP,mouseUpHandler);
}
function mouseDownHandler($e:MouseEvent):void
{
fire_on = true;
}
function mouseUpHandler($e:MouseEvent):void
{
fire_on = false;
fire_counter = 0;
}
function fire():void
{
bullet = new Bullet ;
addChild(bullet);
bullet.x = player.x;
bullet.y = player.y - 32;
bullets_arr.push(bullet);
}
public function Main(e: Event):void
{
player.x = mouseX;
if (bullets_arr)
{
for (var m:int = 0; m < bullets_arr.length; m++)
{
bullets_arr[m].y -= 20;
if(Game.level1.enemies_arr)
{
for (var n:int = 0; n < Game.level1.enemies_arr.length; n++)
{
if (Game.level1.enemies_arr[n].hitTestObject(bullets_arr[m]))
{
if(bullets_arr[m].parent)
{
bullets_arr[m].parent.removeChild(bullets_arr[m]);
bullets_arr.splice(bullets_arr[m],1);
Game.level1.enemies_arr[n].Damage(10, Game.level1.enemies_arr[n]);
}
}
}
}
}
}
if(fire_on)
{
fire_counter++;
if(fire_counter == 01)
{
fire();
}
else if(fire_counter >2)
{
fire_counter =0;
}
}
}
}
}
Level1.as生成敌人并将其推送到阵列。
package
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
public class Level1 extends MovieClip
{
var i:int;
var j:int;
var frame :int;
public var enemy:Enemy;
public var enemies_arr:Array;
public function Level1(target:Stage)
{
frame = 0;
enemies_arr = [];
for (var i:int = 0; i < 5; i++)
{
for (var j:int = 0; j < 3; j++)
{
enemy = new Enemy;
enemy.x = j*100 + 260;
enemy.y = i*40 - 150;
target.addChild(enemy);
enemies_arr.push(enemy);
trace(enemy.parent);
}
}
}
}
}
Enemy class Enemy.AS
package
{
import flash.display.MovieClip;
public class Enemy extends MovieClip
{
var Health : int;
function Enemy()
{
Health =2;
}
public function Damage(Damage:int, enemyHit:Enemy)
{
Health -= Damage;
if (Health <1)
{
Die(enemyHit);
}
}
private function Die(enemyHit:Enemy)
{
if(enemyHit.parent)
{
this.parent.removeChild(this);
Game.level1.enemies_arr.splice(Game.level1.enemies_arr.indexOf(enemyHit,1));
}
}
}
}
答案 0 :(得分:0)
您应该向后遍历Game.level1.enemies_arr
和bullets_arr
。重点是,splice()
缩短了数组,将位于比拼接位置更大位置的元素转移到较小的索引,并且不会自动调整循环计数器。错误很常见,但经常被忽视。此外,使用bullets_arr
,如果bullets_arr
中的最后一颗子弹击中敌人,你可以离开阵列导致1009错误。
一个小的挑剔:你正在循环中检查数组的存在,并且在输入帧监听器中检查另一个数组的存在。事实上,在将事件监听器添加到new Array()
对象之前,或者在分配给它的任何地方,您应该至少使用[]
或Main
初始化它们,或者检查if (!bullets_arr) bullets_arr=new Array();
并保留它,因此需要检查数组是否存在。
public function Main(e: Event):void
{
player.x = mouseX;
if (!bullets_arr) bullets_arr=new Array();
if (!Game.level1.enemies_arr) throw new Error('Hey programmer, initialize your arrays!');
// ^ bad practice to throw exceptions in listeners, but if you get one, you've coded something wrongly.
for (var m:int=bullets_arr.length-1;m>=0;m--) {
var bm:Bullet=bullets_arr[m]; // TODO fix type
// the local variable is a cleaner and faster approach
bm.y-=20;
for (var n:int=Game.level1.enemies_arr.length-1;n>=0;n--) {
if (!bm) break; // bullet was destroyed, why checking more enemies vs that?
if (Game.level1.enemies_arr[n].hitTestObject(bm)) {
bm.parent.removeChild(bm);
bullets_arr.splice(m,1); // splice is done by index, not by object
bm=null; // oops, missed this. The bullet hit something and is now lost
// so we null the local var, so we can break out the loop.
Game.level1.enemies_arr[n].Damage(10, Game.level1.enemies_arr[n]);
}
}
}
// rest of your code follows here
}
答案 1 :(得分:0)
我终于找到了问题,这对我来说非常愚蠢: 我只是错误地输入了Enemy类中的Die函数:
我写过:splice(Game.level1.enemies_arr.indexOf(enemyHit,1))而不是splice(Game.level1.enemies_arr.indexOf(enemyHit),1)
无论如何,通过尝试修复此错误,我学到了很多想法。 谢谢