仅使用一种方法从AS3中的阶段中删除不同类型的对象

时间:2013-01-04 16:44:19

标签: actionscript-3 syntax removechild

我在ActionScript3中制作了一种太空入侵者类型的游戏,我创建了一种从舞台上移除子弹的方法:

private function removeBullet(bb:Bullet = null):void {

    var leng:uint = bulletVector.length;
    if (bb)
    {
        for (var i:uint = 0; i < leng; i++)
        {
            if (bulletVector[i] == bb) 
            {
                bulletVector.splice(i, 1);
                break;
            }                   
        }

        // Remove bullet from the Display List
        removeChild(bb);

        // Return the bullet to its object pool
        bulletPool.returnObject(bb);    

    } else {

        // Remove all existing bullets currently on screen
        for (var j:uint = 0; j < leng; j++)
        {
            var bullet:Bullet = bulletVector[j];
            removeChild(bullet);
            bulletPool.returnObject(bullet);
        }
        bulletVector.splice(0, leng);   
    }
}

bulletVector 是一个Vector,其中包含当前显示的所有项目符号, bulletPool 是一个对象池类,用于在项目未在舞台上使用时返回项目符号池了。如果没有参数传递给方法,该方法将删除屏幕上的所有项目符号。

现在,我有一个相同的方法从屏幕上删除敌人:

private function removeEnemy(ee:Enemy = null):void {

    var leng:uint = enemyVector.length;
    if (ee)
    {
        for (var i:uint = 0; i < leng; i++)
        {
            if (enemyVector[i] == ee) 
            {
                enemyVector.splice(i, 1);
                break;
            }               
        }

        // Remove enemy from the Display List
        removeChild(ee);

        // Return the enemy to its object pool
        enemyPool.returnObject(ee); 

    } else {

        // Remove all existing enemies currently on screen
        for (var j:uint = 0; j < leng; j++)
        {
            var enemy:Enemy = enemyVector[j];
            removeChild(enemy);
            enemyPool.returnObject(enemy);
        }
        enemyVector.splice(0, leng);    
    }
}

“子弹”和“敌人”都是扩展Sprite类的类。我的问题是:是否有可能将这两种方法合并为一个处理子弹和敌人的方法,具体取决于哪一个作为参数传递?

[编辑] 我的想法是这样的:(伪代码)

if (ee is Bullet) 
{ 
    var s:String = "bullet" 
} else if (ee is Enemy) 
{ 
    var s:String = "enemy" 
} 

eval[s+"Vector"].splice(i, 1); 
eval[s+"Pool"].returnObject(ee);

[/编辑]

换句话说,是否有一种语法允许访问Vector和/或Classes(对象池)而不必将其名称硬编码到方法中?

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:3)

这样的事可能对你有用......

private function removeItem(ee:* = null):void {

if (ee) {
//ee has a value

if (ee is Bullet) {
//remove bullet

} else if (ee is Enemy) {
//remove Enemy

}

} else {

//ee is null so remove all bullets and emenies

}
}

答案 1 :(得分:1)

简答:使用Array代替Vector来获取敌人和子弹列表。

创建一个带有3个参数的方法:list:Array和item:Sprite和pool:Array然后从指定的Array中删除该项,而不是“硬编码”实例,最后用两个相同的方法。

/**
 * Removes item from specified list
 * @param   list
 * @param   item
 */
public function removeItem( list:Array, item:Sprite, pool:Array ):void
{
    // implement here
}

长答案:

这很棘手,因为你正在使用向量。

我的第一个冲动是创建一个带有2个参数,列表和项目的泛型函数:(暂时让我们忽略池)

/**
 * Removes item from specified list
 * @param   list
 * @param   item
 */
public function removeItem( list:Vector.<Sprite>, item:Sprite ):void
{
    // implement here
}

但我猜你的子弹列表是Vector类型。你的列表敌人属于Vector。,对吧?

所以即使Bullet和Enemy都扩展了Sprite,如果你使用Vector的实例调用这个方法,例如:

var list:Vector.<Bullet>;
var item:Bullet; // extends Sprite
removeItem( list, item );

这不会编译。你会得到:

Error: Implicit coercion of a value of type __AS3__.vec:Vector.<Bullet> to an unrelated type __AS3__.vec:Vector.<flash.display:Sprite>.

单独注意

你的removeItem方法似乎做了两件事。删除指定的项目和/或删除所有项目。为了安全和清晰,我会将这些分开。每种方法只应执行一项操作。

此外,使用此设置,如果在运行时您对项目的引用意外为空,则最终将从列表中删除所有项目。可能不是你想要的。

我会声明两个函数:

function removeItem(...)

function removeAllItems(...)

答案 2 :(得分:0)

第二个想法,我现在更喜欢使用Arrays进行软打字,因为它不会强迫你更改应用程序的其余部分(例如,你可以保留你的向量)

public function removeItem(list:*, pool:ObjectPool, item:Sprite):void
{
    // remove item from specified list
    var indx:int = list.indexOf(item);
    if (indx >= 0) 
    {
        list.splice(indx, 1);
    }
    // remove display object from display list
    if (this.contains(item))
    {
        this.removeChild(item);
    }           
    // return itemitem to specified pool
    pool.returnObject(item);
}

请注意,您不需要迭代Vector以找出要删除的索引(拼接)。您可以改用indexOf方法。