0

ソケットを使用して、LAN 経由で 2 人のプレーヤー用の Connect 4 ゲームを作成しています。サーバー プレイヤー (プレイヤー 1) が選択を行うとき、彼には自分の選択は表示されず、他のプレイヤーだけが表示されます。他のプレーヤーが選択を行うと、プレーヤー 1 には自分の最初の選択とユーザーの最初の選択が表示されます。本質的に、プレイヤーは次のターンまで現在の選択を見ることはありません。setIcon 部分を System.out.println に置き換えると、コードに到達したことを意味する行が出力されます。

これはなぜですか、どうすれば修正できますか? コード「yourWait();」を取り出すと、機能しているように見えますが、ユーザーは他のプレイヤーの選択を読みません。助けてくれてありがとう!

    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.*;
    import java.net.*;
    import javax.swing.*;

    public class GameBoard extends JPanel implements ActionListener
    {
        JLabel title;
        boolean isHost;

        public Button[] columnpieces = new Button[7];
        int piecesInColumn[] = {0,0,0,0,0,0,0};
        JLabel[][] pieces = new JLabel[7][6];
        int colorOfPiece = 0;

        final JLabel GRID = new JLabel(new ImageIcon("GRID.gif"));
        final ImageIcon RED = new ImageIcon("RED.jpg");
        final ImageIcon BLACK = new ImageIcon("BLACK.jpg");

        JPanel one, two;

        ServerSocket serverSocket = null;
        Socket clientSocket = null;
        BufferedReader reader;
        PrintWriter writer;

        public GameBoard()
        {
            super();
            setBounds(0,0,1000, 700);
            setBackground(Color.yellow);
            setLayout(null);

            title = new JLabel("Connect 4");
            title.setBounds(0,5, 1000, 90);
            title.setFont(new Font("Georgia", Font.BOLD, 100));
            title.setForeground(Color.blue);
            title.setHorizontalAlignment(JLabel.CENTER);
            add(title);

            GRID.setBounds(200, 150, 600, 500);
            add(GRID);

            for (int a = 0; a < columnpieces.length; a ++)
            {
                columnpieces[a] = new Button("Place");
                columnpieces[a].addActionListener(this);
                columnpieces[a].setBounds(209 + 84 * a, 100, 70, 50);
                columnpieces[a].setBackground(Color.white);
                columnpieces[a].setFont(new Font("Arial", Font.BOLD, 20));
                add(columnpieces[a]);

                for (int b = 0; b < pieces[0].length; b ++)
                {
                    pieces[a][b] = new JLabel();
                    pieces[a][b].setBounds(208 + 83 * a,555 - 77 *b, 75,75);
                    add(pieces[a][b]);
                }
            }
        }

        public void setHost(String name) throws IOException
        {
            isHost = true;
            try {
                System.out.println(InetAddress.getLocalHost().getHostAddress());
            } catch (UnknownHostException e2) {
                // TODO Auto-generated catch block
                e2.printStackTrace();
            }
            try {
                serverSocket=new ServerSocket(706);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            Socket clientSocket = null;
            try {
                clientSocket = serverSocket.accept();
            } catch (IOException e1) {
                System.err.println("Accept failed.");
                System.exit(1);
            }
            try {
                writer=new PrintWriter(clientSocket.getOutputStream(),true);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            try {
                reader=new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            } catch (IOException e1) {
                e1.printStackTrace();
            }     
           yourTurn();
        }

        public void setClient(String name) throws IOException
        {
            isHost = false;
                try {
                    clientSocket=new Socket(JOptionPane.showInputDialog("Enter host address.", "192.168.1.137"),706);
                    writer=new PrintWriter(clientSocket.getOutputStream(),true);
                    reader=new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                } catch (UnknownHostException e) {
                    System.err.println("Don't know about host.");
                    System.exit(1);
                } catch (IOException e) {
                    System.err.println("Couldn't get I/O for the connection");
                    System.exit(1);
            }
            yourWait();
        }

        @Override
        public void actionPerformed(ActionEvent e) 
        {
            if (e.getSource() == columnpieces[0])
                updateFromClick(0);
            if (e.getSource() == columnpieces[1])
                updateFromClick(1);
            if (e.getSource() == columnpieces[2])
                updateFromClick(2);
            if (e.getSource() == columnpieces[3])
                updateFromClick(3);
            if (e.getSource() == columnpieces[4])
                updateFromClick(4);
            if (e.getSource() == columnpieces[5])
                updateFromClick(5);
            if (e.getSource() == columnpieces[6])
                updateFromClick(6);
        }

        void setButtonEnables(boolean enabled)
        {
            for (int a = 0; a < columnpieces.length; a ++)
            {
                if(piecesInColumn[a] == 6 || !enabled)
                    columnpieces[a].setEnabled(false);
                else
                    columnpieces[a].setEnabled(true);
            }
        }

        private void addPiece(int column)
        {
            int b = piecesInColumn[column];

            if(colorOfPiece % 2 == 0)
                pieces[column][b].setIcon(BLACK);
            else if (colorOfPiece % 2 == 1)
                pieces[column][b].setIcon(RED);
        }

        private void updateFromClick(int column)
        {
            addPiece(column);
            colorOfPiece +=1;
            piecesInColumn[column] +=1;
            writer.println(column);
            yourWait();
        }

        private void updateFromRecieved(int column)
        {
            addPiece(column);
            colorOfPiece +=1;
            piecesInColumn[column] +=1;
            yourTurn();
        }

        public void yourTurn()
        {
                setButtonEnables(true);
        }

        public void yourWait()
        {
                setButtonEnables(false);
                try {
                    updateFromRecieved(Integer.parseInt(reader.readLine()));
                } catch (NumberFormatException e) {
                    System.err.println("Message is not Integer.");
                } catch (IOException e) {
                    System.err.println("Message can not be read.");
                }
        }
    }
4

1 に答える 1

0

問題は、UI スレッドでブロックしていることです。

あなたはこれを呼び出すことになります:

updateFromRecieved(Integer.parseInt(reader.readLine()));

あなたのクリックに応じて。reader.readLine()これに関する問題は、UI が完了するまで画面を再描画できないことです。そして、これは明らかに、対戦相手が彼の動きを送るまでではありません.

これを修正するには、スレッド化を利用して、ネットワーク コードを UI スレッドから切り離すことを検討する必要があります。それはほとんど決して良い考えではありません。

于 2013-06-18T11:42:41.443 に答える