0

我正在用 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);

[/编辑]

换句话说,是否有一种语法允许访问向量和/或类(对象池)而无需将它们的名称硬编码到方法中?

提前感谢您的帮助。

4

3 回答 3

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

}
}
于 2013-01-04T17:15:06.670 回答
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(...)
于 2013-01-04T17:24:12.307 回答
0

再想一想,我现在更倾向于使用软类型而不是使用数组,因为它不会强迫您更改应用程序的其余部分(例如,您可以保留向量)

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 方法。

于 2013-01-04T19:08:35.150 回答