我正在制作一个游戏,遇到了一个我一直无法弄清楚的问题。玩家是一艘船,船可以投下地雷(通过空格键)。我在 init() 中创建了一个 Mine() 数组:
function initGame():void
{
level = 1;
player = new Player();
//Create an enemies array
enemies = new Array();
//Create a plane array
planes = new Array();
crates = new Array();
explosions = new Array();
mines = new Array();
var tempMine:MovieClip;
for(var i:Number = 1; i < 4; i++){
tempMine = new Mine();
mines.push(tempMine);
minesTxt.text = String(mines.length);
}
gameState = STATE_START_PLAYER;
rightKeyIsDown = false;
leftKeyIsDown = false;
upKeyIsDown = false;
downKeyIsDown = false;
trace(gameState);
}
我有一个名为 releaseKey() 的函数来处理键盘事件,地雷被添加到这里的屏幕中:
function releaseKey(event:KeyboardEvent):void
{
var thisKey:uint = event.keyCode;
if (thisKey == Keyboard.RIGHT)
{
rightKeyIsDown = false;
}
if (thisKey == Keyboard.LEFT)
{
leftKeyIsDown = false;
}
if (thisKey == Keyboard.UP)
{
upKeyIsDown = false;
}
if(thisKey == Keyboard.SPACE){
var tempMine:MovieClip;
if(mines.length > 0){
tempMine = new Mine();
tempMine.y = player.y;
tempMine.x = player.x;
addChild(tempMine);
mines.length--;
minesTxt.text = String(mines.length);
}else if(mines.length == 0){
minesTxt.text = String(0);
}
}
}
问题出在我的碰撞检查功能上。我收到类型错误:错误 #2007:参数命中测试对象必须为非空。我想我创建地雷并将它们添加到数组的方式存在问题,但我看不到问题出在哪里。
function testCollisions():void
{
var tempEnemy:MovieClip;
var tempCrate:MovieClip;
var tempMine:MovieClip;
enemy:for (var i:int=enemies.length-1; i>=0; i--)
{
tempEnemy = enemies[i];
for (var j:int=crates.length-1; j>=0; j--)
{
tempCrate = crates[j];
if (tempEnemy.hitTestObject(tempCrate))
{
if (crates[j].parent)
{
crates[j].parent.removeChild(crates[j]);
}
break enemy;
}
if (tempEnemy.hitTestObject(player))
{
if (player.parent)
{
trace("Hit!!!!!!!!!!!!!!!!!!!!");
makeExplosion(player.x, player.y);
player.parent.removeChild(player);
}
break enemy;
}
tempMine=mines[i];
if (tempEnemy.hitTestObject(tempMine))
{
if (tempEnemy.parent)
{
trace("BOOM!!!!!!!!!!!!!!!!!!!!");
makeExplosion(tempEnemy.x, tempEnemy.y);
player.parent.removeChild(tempEnemy);
}
break enemy;
}
if (player.hitTestObject(tempCrate))
{
if (crates[j].parent)
{
crates[j].parent.removeChild(crates[j]);
}
}
}
}
}
只是想在处理也在单独数组中维护的显示对象时给出一条建议。
我可以看到:- 你正在使用你制作的数组来解析对象(板条箱或敌人)。- 将它们从各自的显示列表中删除,但不从数组中删除它们。
您应该建立一种机制,也将它们从数组中删除,除非有将它们保留在那里的目的。例如,像这样的函数:
function RemoveCrate(index) : void
{
crates[index].parent.removeChild(crates[index]); /// remove from display list
crates.splice(index, 1); /// remove reference from the array;
}
而且我没有像你故意那样检查父级,因为我认为它应该有一个父级,如果没有,我想抛出一个错误,因为这意味着我的其余代码有问题。
此外,如果您正在解析数组并删除元素而不破坏删除迭代,您还应该像这样减少迭代器:
for(var i:int = 0; i < crates.length; i++)
{
[....]
RemoveCrate(i);
i --; // not doing this after deletion will skip one element in the next iteration
[....]
}
拼接数组可能不是最优化的解决方案(链表应该更好),但对于小数组(数十个,甚至数百个)来说,这无关紧要。
最后一件事...不从数组中删除对象将保留对它们的引用,这将使垃圾回收器跳过它们
希望对您有所帮助。
--米赫内亚