A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Jogos de tabuleiro Multiplayer Marco Antonio. Apresentação Jogos multiplayer fazem uso de threads para gerenciar múltiplas tarefas, além de sockets para.

Apresentações semelhantes


Apresentação em tema: "Jogos de tabuleiro Multiplayer Marco Antonio. Apresentação Jogos multiplayer fazem uso de threads para gerenciar múltiplas tarefas, além de sockets para."— Transcrição da apresentação:

1 Jogos de tabuleiro Multiplayer Marco Antonio

2 Apresentação Jogos multiplayer fazem uso de threads para gerenciar múltiplas tarefas, além de sockets para envio de pacotes entre computadores. Na aplicação a seguir temos vários exemplos de como isso pode ser implementado.

3 DadosDeConexao package com.javagames.tabuleiro; /** * Armazena os dados de conexao da aplicacao * * Porta local - utilizada para o ServerSocket * Porta remota - utilizada para o socket cliente * Servidor - nome/ip da maquina remota * O servidor + porta remota sao utilizados para enviar os dados a cada jogada * Nao e necessario indicar o nome/ip da maquina local * Nome do usuario - utilizado para personalizar sua partida * marcoreis * */ public class DadosDeConexao { private int portaLocal; private int portaRemota; private String servidor; private String nomeDoUsuario; {...Metodos de acesso...} }

4 UtilComunicacao package com.javagames.tabuleiro; import java.io.*; import java.net.*; import java.util.*; /** * Transporta os dados entre duas maquinas utilizando socket * Deve ser atualizada para suportar diferentes tipos de dados * Os metodos tem suporte apenas a Map * marcoreis * */ public class UtilComunicacao { /** * Abre um socket entre o cliente e o servidor * O servidor deve estar esperando (accept) esta requisicao * dadosDeConexao Nome do servidor remoto e porta mapa - dados que serao enviados */ public void enviaDadosParaComputadorRemoto(DadosDeConexao dadosDeConexao, Map mapa) { try { Socket socket = new Socket(dadosDeConexao.getServidor(), dadosDeConexao.getPortaRemota()); OutputStream outSocket = socket.getOutputStream(); ObjectOutputStream saida = new ObjectOutputStream(outSocket); saida.writeObject(mapa); saida.close(); outSocket.close(); } catch (Exception e) { e.printStackTrace(); }

5 UtilComunicacao /** * Sincroniza dois mapas * Por definicao, um mapa nao tem repeticao de chaves (keys) * Isso garante que nao havera posicoes repetidas * mapaRecuperado Mapa sincronizado */ public Map sincronizaMapas(Map mapaRecuperado) { Map mapa = new HashMap(); for (Object o : mapaRecuperado.keySet()) { mapa.put(o.toString(), mapaRecuperado.get(o)); } return mapa; }

6 UtilComunicacao /** * * E o outro lado do metodo enviaDadosParaComputadorRemoto * Enquanto o primeiro esta no cliente, este esta no servidor * Converte os dadso em Map, ou seja, nao suporta outros tipos de dados * socket Conexao aberta entre cliente e servidor Mapa enviado */ public Map extrairMapa(Socket socket) { try { InputStream dados = socket.getInputStream(); ObjectInputStream ois = new ObjectInputStream(dados); Object o = ois.readObject(); Map mapaRecuperado = (Map ) o; return mapaRecuperado; } catch (Exception e) { e.printStackTrace(); return null; }

7 JogoDaVelha package com.javagames.tabuleiro; import java.awt.*; import java.awt.event.*; import java.util.*; import javax.swing.*; import com.javagames.util.*; /** * Jogo da velha multiplayer * Utiliza sockets para comunicar as jogadas entre jogadores * marcoreis * public class JogoDaVelha extends JFrame { private static final int QUANTIDADE_DE_CASAS = 3; private int ALTURA = 350; private int LARGURA = 300; private Map mapaDeCasas; private String jogadorAtual; private Point pontoClicado; private DadosDeConexao dadosDeConexao; private UtilComunicacao utilComunicacao;

8 JogoDaVelha /** * MŽtodo construtor * Inicializacao dos parametros obrigatorios */ public JogoDaVelha() { setSize(LARGURA, ALTURA); setBackground(Color.BLUE); adicionaEventoCliqueDoMouse(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } /** * Chama o construtor padrao dados - Dados de conexao informado pelo usuario */ public JogoDaVelha(DadosDeConexao dados) { this(); this.dadosDeConexao = dados; setTitle("Bem-vindo, " + dados.getNomeDoUsuario()); } /** * Adicionar listener para cliques do mouse */ private void adicionaEventoCliqueDoMouse() { addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { eventoCliqueDoMouse(e); } }); }

9 JogoDaVelha /** * Algoritmo a ser implementado Se o jogador atual ganhou ou nao */ private boolean ganhou() { try { int contador = 0; //Verifica se ganhou na vertical for (int i = 0; i < 3; i++) { //Verifica se as posicoes estao ocupadas pelo jogador atual for (int j = 0; j < 3; j++) { // if (posicao[i][j] != null && posicao[i][j].equals(jogadorAtual)) { // contador++; // } //Caso tenha as tres posicoes ocupadas, retorna true, jogador atual ganhou if (contador == 3) { return true; } //Quando muda de coluna, zera o contador contador = 0; } } catch (Exception e) { } return false; }

10 JogoDaVelha /** * Calcula a celular que deve ser utilizada a partir do ponto clicado na tela pontoClicado */ private void marcaPosicao(Point pontoClicado) { int indiceX = pontoClicado.x / (getTamanhoDaCasaX()); int indiceY = pontoClicado.y / (getTamanhoDaCasaY()); String posicao = indiceX + "," + indiceY; getMapaDeCasas().put(posicao, jogadorAtual); //Envia os dados para a thread do oponente, que esta esperando getUtilComunicacao().enviaDadosParaComputadorRemoto(dadosDeConexao, getMapaDeCasas()); setTitle(dadosDeConexao.getNomeDoUsuario() + ", voce jogou. Aguarde."); } /** * */ private UtilComunicacao getUtilComunicacao() { if (utilComunicacao == null) { utilComunicacao = new UtilComunicacao(); } return utilComunicacao; }

11 JogoDaVelha /** * pontoClicado Coordenadas do clique do usuario Se o quadrante clicado est ou nao ocupado */ private boolean posicaoJahMarcada(Point pontoClicado) { int indiceX = pontoClicado.x / (getTamanhoDaCasaX()); int indiceY = pontoClicado.y / (getTamanhoDaCasaY()); String posicao = indiceX + "," + indiceY; if (getMapaDeCasas().get(posicao) != null) { return true; } return false; } /** * Calculo para definir o tamanho das celulas utilizadas. * Jamais utilize valores fixos, pois isso impede a evolucao do sistema Tamanhos */ private int getTamanhoDaCasaY() { return ALTURA / QUANTIDADE_DE_CASAS; } private int getTamanhoDaCasaX() { return LARGURA / QUANTIDADE_DE_CASAS; }

12 JogoDaVelha /** * Desenha/redesenha a tela a cada clique * Ou, na versao multiplayer, a cada jogada */ public void paint(Graphics g) { super.paint(g); //Vertical g.drawLine((LARGURA / 3), 30, (LARGURA / 3), ALTURA - 10); g.drawLine((LARGURA / 3) * 2, 30, (LARGURA / 3) * 2, ALTURA - 10); //Horizontal g.drawLine(10, ALTURA / 3, LARGURA - 10, ALTURA / 3); g.drawLine(10, (ALTURA / 3) * 2, LARGURA - 10, (ALTURA / 3) * 2); imprimeMapaNoTabuleiro(); // } /** * Imprime o mapa no tabuleiro * A chave (key) do mapa esta no formato 'x,y' * Por isso temos o stringtokenizer que recupera cada valor separado pela ',' * Em seguida le cada posicao marcada do mapa, recuperando o jogador marcado * Por fim, desenha na celula x,y a imagem respectiva * O loop le todos os elementos que compoe o mapa naquele momento * */ public void imprimeMapaNoTabuleiro() { for (Object o : getMapaDeCasas().keySet()) { //o (formato x,y) try { StringTokenizer s = new StringTokenizer(o.toString(), ","); int posicaoX = new Integer(s.nextToken()) * getTamanhoDaCasaX() + 30; int posicaoY = new Integer(s.nextToken()) * getTamanhoDaCasaY() + 50; // String jogador = getMapaDeCasas().get(o); desenhaIcone(posicaoX, posicaoY, jogador); // } catch (Exception e) { System.out.println(e); }

13 JogoDaVelha /** * Desenha a respectiva imagem dada uma posicao e um jogador posicaoX posicaoY jogador */ private void desenhaIcone(int posicaoX, int posicaoY, String jogador) { Graphics g = getGraphics(); if (jogador.equals("X")) { g.drawImage(UtilImagem.getImagem("zero.png"), posicaoX, posicaoY, this); } else { g.drawImage(UtilImagem.getImagem("xis.png"), posicaoX, posicaoY, this); } /** * Armazena todas as jogadas ate o presente instante Mapa atual */ public Map getMapaDeCasas() { if (mapaDeCasas == null) { mapaDeCasas = new HashMap (); } return mapaDeCasas; } public void setMapaDeCasas(Map mapaDeCasas) { this.mapaDeCasas = mapaDeCasas; }

14 JogoDaVelha /** * Efetua todas as operacoes referentes ao evento clique do mouse * A cada jogada do usuario, o jogo deve aplicar todas as regras definidas * Alem de informar se algo nao esta correto e Ponto clicado na tela */ private void eventoCliqueDoMouse(MouseEvent e) { pontoClicado = e.getPoint(); defineJogador(); if (posicaoJahMarcada(pontoClicado)) { JOptionPane.showMessageDialog(null, "Posicao ja ocupada.", "Atencao", JOptionPane.WARNING_MESSAGE); } else { repaint(); marcaPosicao(pontoClicado); } if (ganhou()) { JOptionPane.showMessageDialog(null, "Ganhou"); } /** * Nas duas primeiras jogadas da partida verifica quem e quem * O primeiro jogador sera '0' * O segundo sera 'X' */ private void defineJogador() { if (getMapaDeCasas().keySet().size() == 0 && jogadorAtual == null) { jogadorAtual = "0"; } else if (getMapaDeCasas().keySet().size() == 1 && jogadorAtual == null) { jogadorAtual = "X"; }

15 ThreadJogoDaVelha package com.javagames.tabuleiro; import java.net.*; import java.util.*; public class ThreadJogoDaVelha extends Thread { private DadosDeConexao dadosDeConexao; private JogoDaVelha jogo; private UtilComunicacao utilComunicacao; /** * Metodo construtor que exige os dados de conexao e o seu tabuleiro * * Esta classe gerencia as jogadas do oponente atraves do socket * Observacao: Nao ha controle para bloquear o jogador depois do clique * Isso permite que alguem jogue duas vezes * jogo Tabuleiro do seu jogo dados Informacoes necessarias para conectar os tabuleiros */ public ThreadJogoDaVelha(JogoDaVelha jogo, DadosDeConexao dados) { this.dadosDeConexao = dados; this.jogo = jogo; }

16 ThreadJogoDaVelha /** * A thread fica aguardando ate a jogada do oponente * Apos a jogada, bloqueia a thread (accept) * Assim que o oponente jogar, sincroniza os mapas * public void run() { // while (true) { try { jogo.repaint(); Thread.sleep(1000); //Aguarda jogada do oponente //Bloqueia a thread ServerSocket server = new ServerSocket(dadosDeConexao.getPortaLocal()); Socket socket = server.accept(); //O oponente jogou jogo.setTitle(dadosDeConexao.getNomeDoUsuario() + ", agora Ž sua vez."); //Processa jogada //Recupera o mapa de jogadas do oponente Map mapaRecuperado = getUtilComunicacao().extrairMapa( socket); //Sincroniza o seu tabuleiro Map mapaDeCasas = getUtilComunicacao().sincronizaMapas(mapaRecuperado); jogo.setMapaDeCasas(mapaDeCasas); jogo.imprimeMapaNoTabuleiro(); //Desbloquear os recursos apos sua utilizacao socket.close(); server.close(); // } catch (Exception e) { System.out.print("..."); }

17 ThreadJogoDaVelha private UtilComunicacao getUtilComunicacao() { if (utilComunicacao == null) { utilComunicacao = new UtilComunicacao(); } return utilComunicacao; }

18 Splash Screen No Netbeans, crie uma tela com os componentes indicados. Inicie seu jogo e informe os dados do oponente. O botão de conectar deve iniciar uma thread do JogoDaVelha passando todos os dados necessários (veja o próximo slide).

19 Conexão private void btnConectarActionPerformed(java.awt.event.ActionEvent evt) {//GEN- FIRST:event_btnConectarActionPerformed DadosDeConexao dados = new DadosDeConexao(); dados.setPortaLocal(new Integer(txtPortaLocal.getText())); dados.setPortaRemota(new Integer(txtPortaServidor.getText())); dados.setServidor(txtServidor.getText()); dados.setNomeDoUsuario(txtNome.getText()); JogoDaVelha jogo = new JogoDaVelha(dados); new ThreadJogoDaVelha(jogo, dados).start(); setVisible(false); }//GEN-LAST:event_btnConectarActionPerformed


Carregar ppt "Jogos de tabuleiro Multiplayer Marco Antonio. Apresentação Jogos multiplayer fazem uso de threads para gerenciar múltiplas tarefas, além de sockets para."

Apresentações semelhantes


Anúncios Google