0

ファンシー向けのゲームを作成していて、調べたり読んだりしてほとんどの問題を解決しましたが、今は行き詰まっています。

ゲームの簡単な説明: 2 つのクライアントがサーバーに接続し、ゲームが開始されます。サーバーはすべての計算を実行し、シリアル化された GameState オブジェクトをクライアントにサイクルごとに送信します。GameState は、プレイヤーの位置といくつかのゲッター/セッターを示す一連の変数にすぎません。これはうまくいきます。しかし、今は gamestate で Missiles の arrayList を作成しました。Missiles は別のオブジェクトで、シリアル化も可能です。クライアントとサーバーの両方に、GameState クラスと Missile クラスの同一のコピーがあります。

クライアントがスペースを押すとミサイルが追加され、これはサーバーによって登録されます。サーバー版のゲームステートでミサイルの数をサーバーに出力させました。クライアント側でミサイルの数を出力すると、常にゼロになります。関連するものだけを入れようとしたコードを次に示します。

オブジェクトをプレーヤーに送信するサーバー、player.objectout は objectoutputstream にオブジェクトを書き込むだけです。

public void updatePlayerOutput(){
    GameState send = new GameState(gameState);
    leftPlayer.playerObjectOut(send);
    rightPlayer.playerObjectOut(send);
}

GameState の主要部分 (getter と setter を省略)。左と右 = プレイヤー 1 とプレイヤー 2

public class GameState implements Serializable {

private double leftX;
private double leftY;
private double rightX;
private double rightY;
private ArrayList<Missile> missiles;

public GameState(){
    missiles = new ArrayList<Missile>();
}

public GameState(GameState game){
    leftX = game.getLeftX();
    leftY = game.getLeftY();
    rightX = game.getRightX();
    rightY = game.getRightY();
    missiles = game.getMissiles();
}

ミサイルクラス

  public class Missile implements Serializable {

private double x;
private double y;

private double dX;

public Missile(double inX, double inY, double inDX){
    x = inX;
    y = inY;
    dX = inDX;
}

public Missile(Missile inMissile){
    x = inMissile.getX();
    y = inMissile.getY();
    dX = inMissile.getDX();
}

最後に、クライアントが読み取る場所。panel は JPanel であり、gamestate を使用して画像を描画する場所を取得します

while(true){
    gameState = (GameState)(ois.readObject());
    panel.setGameState(gameState);
    panel.repaint();
    updateOutput();
    }

また、関連するメモ (おそらく私の主な質問の理由) では、リンクしたコードの最初のセクションで、送信する完全に新しい GameState オブジェクトを作成する必要があります。どうしてこれなの?gameState 変数をそのまま送信しようとすると、情報が保持されません。ありがとう :)

4

1 に答える 1

1

したがって、私の理解が正しければ、サーバーにはゲームの状態があり、それをシリアル化し、プレイヤーに送信します。その後、プレイヤーは受け取ったゲーム ステートの内容を変更しますが、サーバー上のゲーム ステートに更新が含まれていないことに驚かされます。

それは予想されます。シリアル化は、オブジェクトへのリモート参照を送信しません。オブジェクトを一連のバイトに変換し、この一連のバイトを送信すると、オブジェクトは受信者によって一連のバイトから再構築されます。

例えると、シリアライゼーションを使用してオブジェクトを送信することは、紙の文書を取り出して FAX で送信するようなものです。受信者が受信した FAX に書いた内容が魔法のように元のドキュメントに表示されることはありません。

サーバーに変更を認識させたい場合は、クライアントがサーバーに更新を送信する必要があります。

質問の最後の部分について、私が正しく理解していれば、同じ ObjectOutputStream に同じオブジェクトを複数回送信しようとしましたが、受信者は最初のオブジェクトの状態と後続の状態の違いを認識しませんでした。これも想定内です。同じオブジェクトを 2 回送信すると、以前に送信されたオブジェクトへの参照のみが送信されます。これは、同じオブジェクトが複数回参照されるオブジェクトのグラフをサポートするために必要です。を呼び出しreset()て、ストリームをリセットし、既に送信されたオブジェクトの新しい状態を送信できるようにする必要があります。

于 2013-08-22T10:31:27.890 に答える