1

私と何人かの友人はJavaでトップダウンのシューティングゲームを作っており、それをオンラインにしたいと思っていました。正常に機能するUDPソケット接続を設定しましたが、クライアントから受け取ったデータを保存する方法がわかりません。

現在、データを保存するためにいくつかのハッシュマップを使用しています。たとえば、プレーヤーの追跡、ゲーム情報(プレーヤーの数など)、弾丸(弾丸の位置、発射した人など)の3つのハッシュマップがあります。

しかし、ハッシュマップ以外にこのデータを保存するためのより安全な方法があるはずですが、何が必要かはわかりません。

thx-Philippを編集してください(申し訳ありませんが、半分まともな質問に時間がかかりました)

このデータを格納するためにハッシュマップを使用することについての私の懸念は、それらに入れるデータが非常に多いことです。現在、オブジェクトのすべてのデータを格納するために単一の行を使用しています。たとえば、プレーヤーのハッシュマップの行にはプレーヤーが含まれます。キーとしてのid、「hp、xloc、yloc」などの他のものを格納するための文字列値。次に、これを分割して使用します。私が考えることができないのは、データを保存および取得するための最も効率的な方法です。

それでも意味がない場合は申し訳ありません。

私の本当の質問は、より効率的な代替手段があるかどうか、またはハッシュマップが最善の方法であるかどうかということだと思います。

ありがとう

4

3 に答える 3

1

インメモリは問題ありません。データを永続化する必要がない限り、心配する必要はありません

ただし、「分割して使用する」ではダメです。これは、実際には遅くなり効率が低下するマイクロ「最適化」です。このルートには、痛みと失われた時間しかありません。

あなたの特定の設定はわかりませんが、これを考慮してください:

class Player {
   public Player (int playerId) {
      this.playerId = playerId;
   }

   // ID during game - not permanent; for link-back to Hash key
   public final int playerId;

   // Add methods and fields as appropriate
   String name;
   int health;
   // position, armour color, fairy dust, etc.
}

// How ids are "connected" to players:
//   playerId -> Player
Map<Integer,Player> players = new HashMap..;

// When a player "connects"
int playerId = getUniqueIdForGameInstance();
Player player = new Player(playerId); // setup other information as required
players.add(player.playerId, player);

// On attack ..
int attackerId = getAttackerFromClient();
int targetId = getTargetFromClient();

Player attacker = players.get(attackerId);
Player target = players.get(targetId);
target.getWumped(attacker.wumpStength());

ゲーム内の他のエンティティにも同じことが適用できます。Map は特定の ID が与えられたプレーヤーを見つけるために使用されますが、Player クラスのインスタンスはプレーヤーに関する情報を保持することに注意してください。

ネットワーク全体のシリアル化については、 ProtocolBuffersを参照してください。

于 2013-03-21T21:38:38.557 に答える
1

お気づきのように、ゲーム内の各エンティティに関するデータを文字列に格納することはお勧めできません。

文字列に関する情報が必要なときはいつでも文字列を解析する必要があります。文字列の解析はそれほど高速ではなく、各エンティティに関するデータがより複雑になると、かなり複雑になる可能性があります。

これを行うより良い方法は、一連のクラス変数を使用してエンティティ タイプごとにクラスを作成し、これを使用して各エンティティに関するデータを格納することです。

class Player {
    public: 
         int positionX;
         int positionY;
         int lifes;
         String name;
         //...
}

(ちなみに、経験豊富なオブジェクト指向プログラマーは、これらの変数をプライベートとして宣言し、getter および setter メソッドを使用してそれらを変更しますが、今はそこまでは行きません)

ハッシュ マップは、このクラスのインスタンスを格納します。

 HashMap<Integer, Player> players;

これらの設定は簡単です:

 Player p = new Player();
 p.positionX = 200;
 p.positionY = 400;
 p.lifes = 3;
 p.name = "Ford Prefect";
 players.put(42, p);

(ちなみに、経験豊富な OOP プログラマーはコンストラクターを使用します)

ハッシュ マップにアクセスすることで、各プレーヤーの変数を設定および取得できます。

 players.get(42).positionX += 10; // move player 42 10 pixels to the right
于 2013-03-21T21:30:10.170 に答える
0

ハッシュマップは問題のないソリューションです。スレッドセーフであるため、Web サイトに一度に 10,000 人のユーザーがアクセスしていないと仮定すると、うまく機能するはずです。

ただし、現在、すべてのデータはメモリに保存されています。これは、プログラムが終了した場合に問題になります。

私ができる最も簡単な推奨事項は、HashMaps をファイルに書き込むことです。これは、クラス宣言にインターフェースを追加することによって Java で行われますがSerializable、HashMap はすでにシリアライズ可能であるため、これを行う必要はありません。(これは、HashMap に格納されている作成済みのクラスに対してのみ行う必要があります。)

次に、次を main() メソッドに追加します (ファイルから読み取るため)。

try {
  FileInputStream fis = new FileInputStream("Game.sav");
  ObjectInputStream ois = new ObjectInputStream(fis);
  HashMap<K,V> loadedGame = (HashMap<K,V>) ois.readObject();
} catch (Exception e) {
       // Create new hash maps (no HashMap files found)
}

そして、これをあなたの裁量で呼び出すことができる saveGame() メソッドに

try {
  FileOutputStream fos = new FileOutputStream("Game.sav");
  ObjectOutputStream oos = new ObjectOutputStream(fos);
  o.writeObject(hashmapGameVariable);
  o.close();
} catch (IOException ioe) {
  ioe.printStackTrace(); // something went wrong, you may not have write premissions
}
于 2013-03-21T21:26:21.827 に答える