2

これが間違った質問場所である場合はお詫びします。私は非常に新しい趣味のプログラマーです。

私は現在、小さなトップダウンシューティングゲームに取り組んでいます。これは、学び、楽しむための単純な自己主導型プロジェクトにすぎません。フレームワークとしてC#とXNAを使用しており、gameObjectsを取得してインベントリに追加することで、ゲームに少し多様性を追加しようとしています。

現在、私は単一のList<GamePlayObjects>「WorldObjects」を持っており、ObjectManagerすべてのオブジェクトの更新、衝突、描画関数を管理するクラスがあり、これまでのところに満足しています。GamePlayObjectと衝突すると(小惑星が爆発した後の鉄鉱石の小片など)、プライマリリスト「WorldObjects」からオブジェクトを削除し、これを「WorldObjects」という別のリストに追加します。List<GamePlayObjects> inventory

今、私がやりたいのは、アイテムのスプライトと私が収集したそのアイテムの総数で画面上に小さな領域を描くことです。描画の側面は、インベントリの内外へのデータの抽出に関係しているので、私はあまり興味がありません。

HashSetインベントリから一意のアイテムを取得し、から各アイテムの総数を抽出するために使用することについて、いくつかのスレッドを読んだことがありますHashSetが、これを理解するのに苦労しているため、ここにアクセスして支援を求めています。

私のコードの例と私が達成しようとしていること。

すべてのWorldObjectのリストがあります。各worldObjectは、そのworlObjectに関連するすべてのものを保持するクラスです。

private List<GamePlayObject> gameObjects = new List<GamePlayObject>();

あるオブジェクトが、「プレーヤー」が別のオブジェクト「鉄鉱石」と衝突したとしましょう。私は鉄鉱石の世界のオブジェクトを次の場所から削除します。

private List<GamePlayObject> gameObjects = new List<GamePlayObject>();

これをInventoryという新しいリストに追加します

private List<GamePlayObject> playerInventory = new List<GamePlayObject>();

ますます多くのオブジェクトが収集されてインベントリに追加されるので、情報を抽出して、インベントリに関する情報を画面に表示したいと思います。

たとえば、画面の右側に、在庫にあるアイテムのリストと各アイテムの合計金額を表示したいのですが、このデータは在庫リストから取得する必要があります。

したがって、次のようになります。

Iron Ore x 3
Steel x 10
Gold x 18
Uranium x 12
4

4 に答える 4

1

今私がやりたいことは、アイテムのスプライトと収集したそのアイテムの総数を使用して、画面上に小さな領域を描画することです。図面の側面にはあまり興味がありませんが、インベントリの内外でのデータの抽出です。

linq カウントを使いたいようですね。

InventoryObjects.Count(inventoryObject => inventoryObject.Type == ObjectTypes.Asteroid);
WorldObjects.Count(worldObject => worldObject.Type == ObjectTypes.Asteroid);

これはSQLのように考えることができます

SELECT COUNT([dbo].[World Objects].[Object]) WHERE [dbo].[World Objects].[Type]='Asteroid'

ただし、アイテムを抽出して別のリストに追加する場合は、Reed Copsey のアドバイスに従う必要があります。


編集

したがって、クラスがあると仮定するとPlayer、おそらく次のように構造化されます。

Public Class Player {
    public List<GamePlayObject> Inventory {get; set;}
}

クラスもありWorld、おそらく同様のものがあります。

Public Class World {
    public List<GamePlayObject> Objects {get; set;}
}

あなたGamePlayObjectはそう見えるかもしれませんが、

Public Class GamePlayObject {
    public ObjectType Type {get; set;}
}

したがって、ワールドを初期化し、いくつかのオブジェクトがあり、そのワールドから削除したいオブジェクトがわかっていると仮定します。これは確かに、リソースと最適化の点で最良のアプローチではありません (これは、Reed Copsey の回答が役立つ場所です) が、可能性があります...

var targetObject = World.Where(gamePlayObject => (DesiredConditions))
World.Objects.Remove(targetObject);
Player.Inventory.Add(targetObject);

多分どこDesiredConditionsにあるだろうgamePlayObject.IsCollidedWith

これが完了したら、Playerのインベントリを照会できます。

var IronCount = Player.Inventory.Count(gamePlayObject => gamePlayObject.Type == ObjectType.Iron);

これで問題が解決することを願っています。

于 2013-01-25T16:39:42.197 に答える
1

List<T>、および を使用できますList<T>.Remove。ただし、List<T>このようなを使用する場合の問題Removeは、削除するアイテムを見つけるために、リスト全体を一度に 1 つずつ検索する必要があることです。これにより、削除した要素の後の要素を内部配列で下にシフトする必要があるため、大きなコピーも発生します。

ただし、のようなコレクションはHashSet<T>、コピーなしで非常に迅速にアイテムを見つけて削除できます。これにはタイプの実装が必要ですが、GetHashCode常に一意のアイテムが必要な場合はうまく機能します。

両方のコレクションで考えられるオプションの 1 つは、 を使用するDictionary<GamePlayObject, int>ことです。これにより、ワールドとインベントリ内のそのタイプのオブジェクトの数をすばやく検索して変更できます。繰り返しますが、これには、GamePlayObjectクラスが and をオーバーライドobject.GetHashCodeobject.Equals、 を実装する必要がありますIEquatable<GamePlayObject>

于 2013-01-25T16:39:59.137 に答える
0

It sounds to me that you probably should not be using a list. Meaning why iterate to and from one list to the order when what it seems like is you need to keep counts of the different gameplay objects. I am presuming you have a fixed set of game play objects and they are uniquely named. You can have a fixed dictionaryof elements where you add or subtract counts meaning you would probably be doing something like this gameObjects ["ironore"]++ or playerInventory ["ironore"]--. And then you can use to linq to show all keys whose values are greater than zero.

于 2013-01-25T20:23:58.233 に答える
0

linq で解決するのは素晴らしい問題のように思えます。linq を初めて使用する場合は、101 個の linq サンプル: http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811bという優れたリソースを紹介します。

あなたの特定の問題に!List<T>が実装されているためIEnumerable<T>、linq クエリを実行できます。最も興味深いのは、グループ化演算子です。

GamePlayObjectクラスにプロパティがある場合、次のTypeようなことができます。

var items = from o in playerInventory
    group o by o.Type into g
    select new { ItemType = g.Key, Items = g };
foreach (var g in items)
{
    string s = string.Format("{0} x {1}", g.ItemType.ToString(), g.Items.Count());
    //now do whatever you want with the string, which will contain, eg, Iron Ore x 3
}
于 2013-01-25T18:24:57.917 に答える