0

私は今、OOP と as3 の専門家ではありません。私はこれを処理する在庫システムを作成しています:
*プレイヤーが「アイテム」と衝突すると、それを取得して在庫配列に送信するなど...

アイテムのインスタンス名を手動で書いていることがわかるように、ここに Player クラスのコンストラクターがあり
ます: "silver_key"

public function Player(player:MovieClip,loot:MovieClip,place:MovieClip)
    {
        // constructor code
        _player = player;
        silver_key = loot;//the item

        _inventory = new InventorySystem(place);//InventorySystem Class

        _player.addEventListener(Event.ENTER_FRAME,on_enter_frame);

        addEventListener(EventDemo.EVENT_DEFAULT,onEvent);//custom event listener

    }

これに関連する関数は次のとおりです。

private function on_enter_frame(e:Event):void
if (_player.hitTestObject(silver_key))//check collision between player and item
        {
            dispatchEvent(new EventDemo(EventDemo.EVENT_DEFAULT));

        }

private function onEvent(e:EventDemo)
    {
        _inventory.getitem(_loot);//function use in InventorySystem for array.push
        removeEventListener(EventDemo.EVENT_DEFAULT,onEvent);//removes the listener when the item was sent to array
    }

今私の質問は、インスタンス名を手動で記述せずに多くのアイテムを作成するにはどうすればよいかということです。ありがとう。
ps: それでもわからない場合はコメントしてください。

4

1 に答える 1

1

簡単に言えば:

object["string_name"] = value

より完全な説明については、以下をお読みください...


各アイテムに明示的な名前が必要ですが、それが何であるかを知らなくても、それらのアイテムを動的に定義したいと考えています。これはさまざまな方法で保存できますが、基本的な配列またはオブジェクトは正常に機能するはずです。

プレーヤーを表すムービークリップを作成していたようです。クラスとして、プレーヤー クラスのインスタンス化自体がそのムービークリップになる可能性がありますが、ムービークリップは多くのタイムライン バゲージを運ぶため、作業が遅くなる可能性があることに注意してください。より簡潔で軽量なプレーヤー クラスを作成するには、Sprite を拡張し、独自のプロパティ/メソッドを記述します。

たとえば、Silver Key オブジェクトが次のようになっているとします。

item:Object = {
    "name":"Silver Key",
    "count":1,
    "weight":3,
    "icon":"silver_key.jpg"
}

1 つのオブジェクトで、name プロパティを、そのアイテムのタイプを表す任意のものとして定義できます。また、そのアイテムを説明するその他の関連プロパティも定義できます。あとは、プレーヤー クラス自体に保存されたアイテムのリストを保持するだけです。

プレイヤークラス

package {   
    public dynamic class Player extends Sprite {
        import flash.events.*;
        import flash.display.*;

        public var inventory:Object = {};

        public function Player() {
            addEventListener(Event.ENTER_FRAME, tick);
        }

        public function tick(e:Event):void {
            // ENTER_FRAME stuff
        }

        public function loot(item:Object) {
            if (inventory.hasOwnProperty(item.name)) {
                inventory.item.count++
                trace("You now have " + inventory.item.count + " " + item.name + "'s!");
            } else {
                inventory[item.name] = item;
                trace("You have picked up a " + item.name)
            }
        }

        public function drop(item:Object) {
            if (inventory.hasOwnProperty(item.name)) {
                inventory.item.count--
                if (inventory.item.count == 0) {
                    trace("You no longer have " + item.name);
                    delete(inventory[item.name]);
                } else {
                    trace("You now have one less " + item.name + ".");
                }
            }
        }
    }
}

実装例

var player:Player = new Player();
player.loot(item);
// traces "You picked up a Silver Key"
player.drop(item);
// traces "You no longer have Silver Key"

これは簡単な方法であり、正直なところ、独自のアイテムと在庫クラス、および破損した在庫を防ぐためのデータのサニタイズ/チェックで拡張することをお勧めします。


更新: 「おそらく、各アイテムのプロトタイプを作成します。」

これがどのように見えるかです。

package {   
    public class ItemDefinition extends Object {
        public var name:String = "Unnamed Item";
        public var count:int = 1;
        public var weight:int = 0;
        public var icon:String = "unnamed.jpg";

        public function ItemDefinition(Properties:Object) {
            // By passing in an object, we can define only the properties we want to change.
            for (var Name:String in Properties) {
                // Only property names that match will overwrite the defaults.
                if (this.hasOwnProperty(Name)) {
                    this[Name] = Properties[Name]
                }
            }
        }
    }
}

これの優れている点は、後で混乱する可能性のある偽の値を追加することを恐れずに、任意の数のプロパティを任意の順序で定義できることです。さらに、Item を定義するものに新しいプロパティを追加する場合は、上部に public var として追加するだけです。

次に、新しい ItemDefinition オブジェクトを使用して、ドキュメントの先頭で一度にすべてのアイテムを定義します。

var itemDefinitions:Object = {
    'Silver Key':new Item({name:"Silver Key", icon:"silver_key.jpg", weight:3}),
    'Gold Key':new Item({weight:10, name:"Gold Key", icon:"gold_key.jpg"}),
    'Iron Key':new Item({icon:"iron_key.jpg", weight:2, name:"Iron Key"})
}

function populateItems(itemName:String, count:int = 20) {
    if (itemDefinitions.hasOwnProperty(itemName)) {
        for (var i:int = 0; i < count; i++) {
            var item:MovieClip = new MovieClip();
            item.x = randomNumber(0, this.loaderInfo.width);
            item.y = randomNumber(0, this.loaderInfo.height);
            item["itemDefinition"] = itemName;
        }
    } else {
        trace(itemName + " is an invalid item.");
    }
}

function randomNumber(low:Number=0, high:Number=1):Number {
    /* Returns a random number between the low and high values given. */
    return Math.floor(Math.random() * (1+high-low)) + low;
}

ご覧のとおり、余分なアイテムを画面上に (ランダムに) 吐き出すヘルパー関数をいくつか追加しました。明らかに、addChild とイメージの読み込みが必要ですが、それは実際に実装する必要があるものです。

最後に、戦利品の呼び出しを修正して、itemDefinition を渡すようにします...

player.loot(itemDefinitions[item.itemDefinition]);
removeChild(item);

可能性の世界。ゲームのニーズに対応するより堅牢なものを作成する可能性が高いため、これはそのための 1 つの方法にすぎません。

于 2013-07-22T19:16:14.553 に答える