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);    
    }
}

'bullets'と'enemies'はどちらも、Spriteクラスを拡張するクラスです。私の質問は、これら2つのメソッドを、どちらが引数として渡されるかに応じて、弾丸と敵の両方を処理するメソッドにマージすることは可能ですか?

[編集]私が考えているのは次のようなものです:(擬似コード)

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

簡単な答え:敵と弾丸のリストには、Vectorの代わりにArrayを使用してください。

3つの引数を取るメソッドを作成します:list:Arrayとitem:Sprite、およびpool:Arrayは、インスタンスを「ハードコーディング」して2つの同一のメソッドを作成する代わりに、指定された配列からアイテムを削除します。

/**
 * 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型ですよね?

したがって、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メソッドは2つのことをしているようです。指定されたアイテムの削除および/またはすべてのアイテムの削除。安全性と明確さのために、これらを別々に保ちます。各メソッドは1つのことだけを実行する必要があります。

また、この設定では、実行時にアイテムへの参照が誤ってnullになった場合、リストからすべてのアイテムが削除されることになります。おそらくあなたが望んでいたものではありません。

私は2つの関数を宣言します:

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 に答える