Jogo Multiplayer de Luta (Socket, Thread)

Estou com um problema, tenho que fazer um jogo multiplayer de Luta. Oque deve ocorrer é ter dois clientes conectados em um servidor, os dois clientes dever ver as mesmas coisas sincronizadas. Eu foz um cliente se conevatr ao servidor mas empaquei em fazer os dois cleinets se conectarem e ver um ao outro nas suas telas.

Tenho essa classe onde basicamente é o cliente>

import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.Icon;

public class KombatMainForm extends javax.swing.JFrame implements Runnable {

/**
 * Creates new form KombatMainForm
 */
public KombatMainForm() {
    initComponents();
}


@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    addWindowListener(new java.awt.event.WindowAdapter() {
        public void windowOpened(java.awt.event.WindowEvent evt) {
            formWindowOpened(evt);
        }
    });
    addKeyListener(new java.awt.event.KeyAdapter() {
        public void keyPressed(java.awt.event.KeyEvent evt) {
            formKeyPressed(evt);
        }
        public void keyReleased(java.awt.event.KeyEvent evt) {
            formKeyReleased(evt);
        }
    });

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 800, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 600, Short.MAX_VALUE)
    );

    pack();
}// </editor-fold>                        

private void formWindowOpened(java.awt.event.WindowEvent evt) {                                  
    // TODO add your handling code here:
    player = new Player();
    player.setup();
    getContentPane().add(player);        
    connect();
    repaint();
    gameFlowThread = new Thread(this);
    gameFlowThread.start();
}                                 

public void connect(){
    try {
        s   = new Socket("localhost",8880);
        in  = new BufferedReader(new InputStreamReader(s.getInputStream()));
        out = new PrintWriter(s.getOutputStream(),true);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void gameFlow() {
    String command;
    try {
        while (true) {
            command = in.readLine();
            String data[] = command.split("\\_");
            player.x = Integer.parseInt(data[0]);
            player.y = Integer.parseInt(data[1]);
            player.move();
            
        }
    } catch (Exception e) {
        e.printStackTrace();
        System.exit(1);
    }
}

private void formKeyPressed(java.awt.event.KeyEvent evt) {                                
    // TODO add your handling code here:
    if (evt.getKeyCode() == KeyEvent.VK_RIGHT) {
        out.println("PR_R");
        player.setIconRight();
    }
        if (evt.getKeyCode()  == KeyEvent.VK_LEFT){
            out.println("PR_L");
            player.setIconLeft();
    }
        
         if (evt.getKeyCode() == KeyEvent.VK_UP) {
        out.println("PR_U");
    }
        if (evt.getKeyCode()  == KeyEvent.VK_DOWN){
            out.println("PR_D");
    }
        
        
}                               

private void formKeyReleased(java.awt.event.KeyEvent evt) {                                 
    // TODO add your handling code here:
    if (evt.getKeyCode() == KeyEvent.VK_RIGHT) {
        key_r = false;
        out.println("RE_R");
    }
    if (evt.getKeyCode() == KeyEvent.VK_LEFT) {
        key_l = false;
        out.println("RE_L");
    }
     if (evt.getKeyCode() == KeyEvent.VK_UP) {
        key_r = false;
        out.println("RE_U");
    }
    if (evt.getKeyCode() == KeyEvent.VK_DOWN) {
        key_l = false;
        out.println("RE_D");
    }
}                                

@Override
public void paint(Graphics g) {
    super.paint(g); //To change body of generated methods, choose Tools | Templates.
}

@Override
public void run() {
    gameFlow();
}

/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
  try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(KombatMainForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(KombatMainForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(KombatMainForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(KombatMainForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new KombatMainForm().setVisible(true);
        }
    });
}

// Variables declaration - do not modify                     
// End of variables declaration                   
Thread gameFlowThread;
Player player;
Socket s;
BufferedReader in;
PrintWriter out;
boolean key_r = false;
boolean key_l = false;

}

e tenho a classe player que é o Jlabel onde fica os icones (sprites) dos personagens

import java.awt.Image;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JLabel;

public class Player extends JLabel{
public int x = 0, y = 0;
ImageIcon walkL;
ImageIcon walkR;
ImageIcon walkU;
ImageIcon walkD;
public void setup(){
setText(" ");
walkR = new ImageIcon(new ImageIcon(getClass().getResource(“walk_r.gif”)).getImage().getScaledInstance(88, 127, Image.SCALE_DEFAULT));
walkL = new ImageIcon(new ImageIcon(getClass().getResource(“walk_l.gif”)).getImage().getScaledInstance(88, 127, Image.SCALE_DEFAULT));
setBounds(x, y, 100, 127);
setIcon(walkR);
}

public void move(){
    setBounds(x, y, 100, 127);
}

public void setIconRight(){
    setIcon(walkR);
}

public void setIconLeft(){
    setIcon(walkL);
}

}

e o Servidor em si, que trata das posição e da conexão dos clientes

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

/*

  • To change this license header, choose License Headers in Project Properties.
  • To change this template file, choose Tools | Templates
  • and open the template in the editor.
    */

/**
*

public class KombatServerExec implements Runnable{

    System.out.println("Starting...");
    KombatServerExec kse = new KombatServerExec();
    kse.waitForPlayer(); 

}

@Override
public void run() {
    try {
        while(true){
            Thread.sleep(30);
            if(btR){
                player.x += SPEED;
                out.println(player.x + "_" + player.y + "_" 
                    + player.w + "" + player.h);
            }
            
            if(btL){
                player.x -= SPEED;
                out.println(player.x + "_" + player.y + "_" 
                    + player.w + "" + player.h);
                
            }
             if(btU){
                player.y -= SPEED;
                out.println(player.x + "_" + player.y + "_" 
                    + player.w + "" + player.h);
            }
            
            if(btD){
                player.y += SPEED;
                out.println(player.x + "_" + player.y + "_" 
                    + player.w + "" + player.h);
                
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void waitForPlayer(){
    try {
        player = new Player();
        ServerSocket ss = new ServerSocket(8880);
        Socket s = ss.accept();
        BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
        out = new PrintWriter(s.getOutputStream(), true);
        
        Thread th = new Thread(this);
        th.start();
        
        String command = "";            
        while(!(command = in.readLine()).equals("exit")){
            if(command.equals("PR_R")){
                btR = true;
            }
               if(command.equals("PR_L")){
                btL = true;
               }
            
            if(command.equals("RE_R")){
                btR = false;
            }   
             if(command.equals("RE_L")){
                btL = false;
            }   
              if(command.equals("PR_U")){
                btU = true;
            }
               if(command.equals("PR_D")){
                btD = true;
               }
            
            if(command.equals("RE_U")){
                btU = false;
            }   
             if(command.equals("RE_D")){
                btD = false;
            }   
        }
    } catch (Exception e) {
        e.printStackTrace();
        System.exit(1);
    }
}
public static final int SPEED = 8;
public Player player;
boolean btR = false, btL = false, btU = false, btD = false;
PrintWriter out; 

}

Mas realmente fiquei perdido no momento em que tenho que fazer dois clientes estarem conectados juntos e um vendo onde o outra está. Alguém tem uma dica do que fazer ou ate oq mudar … Algum rumo a se seguir

A implementação do seu servidor está estranha.

Para cada conexão aceita no server, você deve disparar uma Thread para processar as entradas daquele jogador.

Ficará algo mais ou menos assim:

public class Servidor {

    public static void main(String... args) {
        ServerSocket ss = new ServerSocket(8880);
        while (servidorNoAr) {
            Socket socket = ss.accept();
            Runnable processaJogador = new ProcessadorJogador(socket);
            Thread processo = new Thread(processaJogador);
            processo.start();
        }
    }
}

Já a classe ProcessadorJogador deveria ser algo mais ou menos assim:

class ProcessadorJogador implements Runnable {

    final BufferedReader in;
    final PrintWriter out;
    final Player player;

    ProcessadorJogador(Socket socket) {
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        out = new PrintWriter(socket.getOutputStream(), true);
        player = new Player();
    }

    public void run() {
        while ( jogoEmExecucao ) {
            // aqui você processa as ações do jogador
        }
    }
}
1 curtida