Estou tentando fazer um jogo multiplayer simples de tanque implementando chat. O jogo e o chat estão tudo ok! Porém, eu não consigo fazer com que 2 Clientes visualizem o mesmo objeto: Arena. No caso, cada cliente que ingressar cria um tanque na arena. Porém, sempre que tento executar, ele cria uma arena diferente para cada jogador.
public class Arena extends JComponent implements MouseListener, ActionListener, KeyListener { private Tanque apontado; private int largura, altura; private HashSet<Tanque> tanques; private Tiro tiro; private Timer contador; private long agora; public Arena(int largura, int altura) { this.largura = largura; this.altura = altura; tanques = new HashSet<Tanque>(); tiro = new Tiro(-40, -10, 0, null, -1); addMouseListener(this); addKeyListener(this); setFocusable(true); contador = new Timer(40, this); contador.start(); agora = 1; } public void adicionaTanque(Tanque t) { tanques.add(t); } public Dimension getMaximumSize() { return getPreferredSize(); } public Dimension getMinimumSize() { return getPreferredSize(); } public Dimension getPreferredSize() { return new Dimension(largura, altura); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setColor(new Color(245, 245, 255)); g2d.fillRect(0, 0, largura, altura); g2d.setColor(new Color(220, 220, 220)); for (int _largura = 0; _largura <= largura; _largura += 20) g2d.drawLine(_largura, 0, _largura, altura); for (int _altura = 0; _altura <= altura; _altura += 20) g2d.drawLine(0, _altura, largura, _altura); // Desenhamos todos os tanques for (Tanque t : tanques) { t.draw(g2d); } tiro.draw(g2d); } public void mouseClicked(MouseEvent e) { for (Tanque t : tanques) t.setEstaAtivo(false); for (Tanque t : tanques) { boolean clicado = t.getRectEnvolvente().contains(e.getX(), e.getY()); if (clicado) { t.setEstaAtivo(true); apontado = t; } } repaint(); } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void actionPerformed(ActionEvent e) { for (Tanque t : tanques) { t.mover(); t.calculaTempo(); } colisao(); tiro.mover(); repaint(); } public void colisao() { if (tiro.estaAtivo) { for (Tanque t : tanques) { if (t.getId() != tiro.getId()) { double dist = Math.sqrt(Math.pow(tiro.x - t.x, 2) + Math.pow(tiro.y - t.y, 2)); if (dist <= 20) {/* Distancia de acerto */ tiro.x = -10; tiro.y = -10; tanques.remove(t); tiro.estaAtivo = false; break; } /* Tanque detecta o míssil e tenta se esquivar */ if (dist < 100) { t.setTempo(System.currentTimeMillis()); if (agora % 2 == 0) t.girarAntiHorario(7); else t.girarHorario(7); t.velocidade = 6; } } } } for (Tanque t : tanques) { autoColisao(t); } } public void autoColisao(Tanque tanque) { for (Tanque t : tanques) {/* verifica a distancia para checar colisão entre os tanques */ if (tanque.getId() != t.getId()) { double dist = Math.sqrt(Math.pow(tanque.x - t.x, 2) + Math.pow(tanque.y - t.y, 2)); if (dist <= 30) { /* Colisão entre tanques */ if (t.velocidade > 0) { t.velocidade *= -1; t.girarAntiHorario(7); } else { t.velocidade = 2; t.girarHorario(7); } } if (dist < 80 && tanque.estaAtivo) {/* tanque inimigo tenta fugir */ t.setTempo(System.currentTimeMillis()); if (agora % 2 == 0) t.girarAntiHorario(5); else t.girarHorario(5); t.velocidade = 6; } } } } public void keyPressed(KeyEvent e) { for (Tanque t : tanques) { t.setEstaAtivo(false); if (t == apontado) { t.setEstaAtivo(true); switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: t.girarAntiHorario(3); break; case KeyEvent.VK_UP: t.aumentarVelocidade(); break; case KeyEvent.VK_DOWN: t.diminuirVelocidade(); break; case KeyEvent.VK_RIGHT: t.girarHorario(3); break; case KeyEvent.VK_SPACE: { atirar(t.getId()); agora = System.currentTimeMillis(); } break; } break; } repaint(); } } @Override public void keyReleased(KeyEvent e) { } @Override public void keyTyped(KeyEvent e) { } public void atirar(int id) { for (Tanque t : tanques) { if (t.estaAtivo) { if (!tiro.estaAtivo) { tiro.x = t.x; tiro.y = t.y; tiro.angulo = t.angulo; tiro.cor = Color.RED; tiro.setId(t.getId()); tiro.estaAtivo = true; } } } }
——————-CÓDIGO SERVIDOR————————–
public class Servidor extends Thread { /* Aqui vou criar um Array list para armazenar o BufferedWiter de cada * jogador que se conecta no site. * O restante das variaveis tem nomes sugestivos */ private static ArrayList<BufferedWriter> clientes; private static ServerSocket servidor; private String nickname; /*essa variavel vai servir para armeznar o nome do jogador cliente que o servidor recebe*/ private Socket conexao; private InputStream entrada; private InputStreamReader leitura_entrada; private BufferedReader buffer; Arena arena = new Arena(640, 480); JFrame janela = new JFrame("JTank"); public Servidor(Socket conexao) { this.conexao= conexao; try { entrada = conexao.getInputStream(); leitura_entrada = new InputStreamReader(entrada); buffer = new BufferedReader(leitura_entrada); } catch (IOException e) { e.printStackTrace(); } } public void run(){ janela.getContentPane().add(arena); janela.setResizable(false); janela.pack(); janela.setVisible(true); arena.adicionaTanque(new Tanque(500, 50, 180, Color.BLUE, 1)); try{ String mensagem; OutputStream ou = this.conexao.getOutputStream(); Writer ouw = new OutputStreamWriter(ou); BufferedWriter bfw = new BufferedWriter(ouw); clientes.add(bfw); nickname = mensagem = buffer.readLine(); while(!"Sair".equalsIgnoreCase(mensagem) && mensagem != null) { mensagem = buffer.readLine(); sendToAll(bfw, mensagem); System.out.println(mensagem); } }catch (Exception e) { e.printStackTrace(); } } public void sendToAll(BufferedWriter bwSaida, String msg) throws IOException { BufferedWriter bwS; for(BufferedWriter bw : clientes){ bwS = (BufferedWriter)bw; if(!(bwSaida == bwS)){ bw.write(nickname + " -> " + msg+"\r\n"); bw.flush(); } } } public void chama_arena() { } public static void main(String []args) { try{ JLabel lblMessage = new JLabel("Porta do Servidor:"); JTextField txtPorta = new JTextField("12345"); Object[] texts = {lblMessage, txtPorta }; JOptionPane.showMessageDialog(null, texts); servidor = new ServerSocket(Integer.parseInt(txtPorta.getText())); clientes = new ArrayList<BufferedWriter>(); JOptionPane.showMessageDialog(null,"Servidor ativo na porta: "+ txtPorta.getText()); while(true){ System.out.println("Aguardando conexão..."); Socket conexao = servidor.accept(); System.out.println("Cliente conectado..."); Thread t = new Servidor(conexao); t.start(); } }catch (Exception e) { e.printStackTrace(); } } }
——————-CÓDIGO CLIENTE————————–
public class Cliente extends JFrame implements ActionListener, KeyListener { private static final long serialVersionUID = 1L; private JTextArea texto; private JTextField txtMsg; private JButton btnEnviar; private JButton btnSair; private JLabel lblHistorico; private JLabel lblMsg; private JPanel pnlContent; private Socket socket; private OutputStream ou; private Writer ouw; private BufferedWriter bfw; private JTextField txtIP; private JTextField txtPorta; private JTextField txtNome; public Cliente() throws IOException { JLabel lblMessage = new JLabel("Verificar!"); txtIP = new JTextField("127.0.0.1"); txtPorta = new JTextField("12345"); txtNome = new JTextField("Cliente"); Object[] texts = { lblMessage, txtIP, txtPorta, txtNome }; JOptionPane.showMessageDialog(null, texts); pnlContent = new JPanel(); texto = new JTextArea(10, 20); texto.setEditable(false); texto.setBackground(new Color(240, 240, 240)); txtMsg = new JTextField(20); lblHistorico = new JLabel("Histórico"); lblMsg = new JLabel("Mensagem"); btnEnviar = new JButton("Enviar"); btnEnviar.setToolTipText("Enviar Mensagem"); btnSair = new JButton("Sair"); btnSair.setToolTipText("Sair do Chat"); btnEnviar.addActionListener(this); btnSair.addActionListener(this); btnEnviar.addKeyListener(this); txtMsg.addKeyListener(this); JScrollPane scroll = new JScrollPane(texto); texto.setLineWrap(true); pnlContent.add(lblHistorico); pnlContent.add(scroll); pnlContent.add(lblMsg); pnlContent.add(txtMsg); pnlContent.add(btnSair); pnlContent.add(btnEnviar); pnlContent.setBackground(Color.LIGHT_GRAY); texto.setBorder(BorderFactory.createEtchedBorder(Color.BLUE, Color.BLUE)); txtMsg.setBorder(BorderFactory.createEtchedBorder(Color.BLUE, Color.BLUE)); setTitle(txtNome.getText()); setContentPane(pnlContent); setLocationRelativeTo(null); setResizable(false); setSize(250, 300); setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); } /* Vou criar aqui um método chamado conectar.. Se conecta ao servidor */ public void conectar() throws IOException { socket = new Socket(txtIP.getText(), Integer.parseInt(txtPorta.getText())); ou = socket.getOutputStream(); ouw = new OutputStreamWriter(ou); bfw = new BufferedWriter(ouw); bfw.write(txtNome.getText() + "\r\n"); bfw.flush(); } /* * metodo Enviar mensagem é responsável pela troca de mensagens dentro do servidor */ public void enviarMensagem(String msg) throws IOException { if (msg.equals("Sair")) { bfw.write("Desconectado \r\n"); texto.append("Desconectado \r\n"); } else { bfw.write(msg + "\r\n"); texto.append(txtNome.getText() + " diz -> " + txtMsg.getText() + "\r\n"); } bfw.flush(); txtMsg.setText(""); } /* * Método para ler as mensagens recebidas pelo servidor */ public void escutar() throws IOException { InputStream in = socket.getInputStream(); InputStreamReader inr = new InputStreamReader(in); BufferedReader bfr = new BufferedReader(inr); String msg = ""; while (!"Sair".equalsIgnoreCase(msg)) if (bfr.ready()) { msg = bfr.readLine(); if (msg.equals("Sair")) texto.append("Servidor caiu! \r\n"); else texto.append(msg + "\r\n"); } } /* * Método usado quando o usuário clica em sair */ public void sair() throws IOException { enviarMensagem("Sair"); bfw.close(); ouw.close(); ou.close(); socket.close(); } @Override public void actionPerformed(ActionEvent e) { try { if (e.getActionCommand().equals(btnEnviar.getActionCommand())) enviarMensagem(txtMsg.getText()); else if (e.getActionCommand().equals(btnSair.getActionCommand())) sair(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { try { enviarMensagem(txtMsg.getText()); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } } @Override public void keyReleased(KeyEvent arg0) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent arg0) { // TODO Auto-generated method stub } public static void main(String[] args) throws IOException { Cliente app = new Cliente(); app.conectar(); app.escutar(); }
}