2

1日前にcodereviewで質問しましたが、まだ回答が得られていないので、ここで質問してみます。

私が作ろうとしているものを教えてください:

サーバーまたはクライアントを実行するかどうかをユーザーに尋ねるウィンドウがポップアップ表示されます。サーバーを選択すると、LAN 上のサーバーが起動します。クライアントを選択すると、そのサーバーへの接続が試行されます。サーバーが実行され、クライアントが接続されると、ウィンドウが 2 つの四角形でポップアップ表示されます。サーバー/クライアントの両方が、矢印キーで正方形を移動できます。

これは私が得ているものです:

サーバーの正方形は希望の速度で動きますが、クライアント側では動きが非常に不安定です。一方、正方形のクライアントは、1 秒あたり約 3 ピクセルで移動しているように見えます (遅すぎます)。

これは私が求めているものです:

私の質問はかなり明白だと思います。私がしているのは、インターネット経由で 2 つの整数を送信することだけです。現代のオンライン ゲームはこれよりもはるかに多くのデータを送信し、遅れることはほとんどありません。

サーバー.java:

// server class
public class Server {
    // networking objects
    private ServerSocket serverSocket;
    private Socket clientSocket;
    private DataOutputStream clientOutputStream;
    private DataInputStream clientInputStream;
    // game objects
    private Vec2D serverPos, clientPos;
    private GameManager gameManager;
    // run method
    public void run() {
        // intialization try-catch block 
        try {
            // setup sockets
            serverSocket = new ServerSocket(1111);
            clientSocket = serverSocket.accept();
            // setup I/O streams
            clientOutputStream = new DataOutputStream(clientSocket.getOutputStream());
            clientInputStream = new DataInputStream(clientSocket.getInputStream());
        } catch(IOException e) { Util.err(e); }
        // declare & intialize data exchange thread
        Thread dataExchange = new Thread( 
            new Runnable() {
                // run method
                @Override
                public void run() {
                    // I/O try-catch block
                    try {
                        // exchange-loop
                        while(true) {
                            // write x & y, flush
                            synchronized(gameManager) {
                                clientOutputStream.writeInt(serverPos.x);
                                clientOutputStream.writeInt(serverPos.y);
                                clientOutputStream.flush();
                            }
                            // read x & y
                            clientPos.x = clientInputStream.readInt();
                            clientPos.y = clientInputStream.readInt();
                        }
                    } catch(IOException e) { Util.err(e); }
                }
            }
        );
        // setup game data
        serverPos = new Vec2D(10, 10);
        clientPos = new Vec2D(300, 300);
        gameManager = new GameManager(serverPos, clientPos, serverPos);
        // start data exchange thread
        dataExchange.start();
        // start main loop
        while(true) {
            // get keyboard input
            synchronized(gameManager) {    
                gameManager.update();
            }
            // repaint, sleep
            gameManager.repaint();
            Util.sleep(15);        
        }
    }
}

クライアント.java:

// client class
public class Client {
    // networking objects
    private Socket serverConnection;
    private DataOutputStream serverOutputStream;
    private DataInputStream serverInputStream;
    // game objects
    private Vec2D serverPos, clientPos;
    private GameManager gameManager;
    // run method
    public void run() {
        // intialization try-catch block 
        try {
            // setup socket
            serverConnection = new Socket(InetAddress.getByName("192.168.0.19"), 1111);
            // setup I/O streams
            serverOutputStream = new DataOutputStream(serverConnection.getOutputStream());
            serverInputStream = new DataInputStream(serverConnection.getInputStream());
        } catch(IOException e) { Util.err(e); }
        // declare & intialize data exchange thread
        Thread dataExchange = new Thread( 
            new Runnable() {
                // run method
                @Override
                public void run() {
                    // I/O try-catch block
                    try {
                        // exchange-loop
                        while(true) {
                            // read x & y
                            synchronized(gameManager) {
                                serverPos.x = serverInputStream.readInt();
                                serverPos.y = serverInputStream.readInt();
                            }
                            // write x & y, flush
                            serverOutputStream.writeInt(clientPos.x);
                            serverOutputStream.writeInt(clientPos.y);
                            serverOutputStream.flush();
                        }
                    } catch(IOException e) { Util.err(e); }
                }
            }
        );
        // setup game data
        serverPos = new Vec2D(10, 10);
        clientPos = new Vec2D(300, 300);
        gameManager = new GameManager(serverPos, clientPos, clientPos);
        // start data exchange thread
        dataExchange.start();
        // start main loop
        while(true) {
            // get keyboard input
            synchronized(gameManager) {    
                gameManager.update();
            }
            // repaint, sleep
            gameManager.repaint();
            Util.sleep(15);  
        }
    }
}

私はたくさんのコードを取り除きました - 混乱していないことを願っています。助けてくれてありがとう!

4

3 に答える 3

2

あなたのコードの問題はwhile(true)ループです:

    while(true) {
        // get keyboard input
        synchronized(gameManager) {    
            gameManager.update();
        }
        // repaint, sleep
        gameManager.repaint();
        Util.sleep(15);        
    }

この方法では、送信する更新が多すぎる (誰もキーを押さない場合) か、送信する更新が少なすぎる (何が起こっても常に 15 ミリ秒待機するため) ことになります。キーボード イベントをリッスンし、存在する場合は、それを反対側に伝達することをお勧めします。反対側は、この「変更」イベントへの反応として更新できます。これを実装するにはObserver パターンが役立つ場合があります。

于 2013-04-22T13:27:01.207 に答える