I'm trying to make a simple multiplayer tank game by implementing chat.
The game and the chat are all ok! However, I can not get 2 clients to see the same object Arena
.
In this case, each customer joining creates a tank in the arena. However, whenever I try to run, it creates a different arena for each player.
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;
}
}
}
}
}
Server Code:
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();
}
}
}
Client code:
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();
}
}