package com.rzg.zombieland.cliente.interfaz; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.KeyEventDispatcher; import java.awt.KeyboardFocusManager; import java.awt.Rectangle; import java.awt.SystemColor; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Timer; import java.util.TimerTask; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.border.EmptyBorder; import javax.swing.border.LineBorder; import javax.swing.table.AbstractTableModel; import javax.swing.table.JTableHeader; import org.jdeferred.DoneCallback; import com.rzg.zombieland.cliente.comunicacion.ServicioCliente; import com.rzg.zombieland.cliente.comunicacion.peticion.PeticionAbandonarPartida; import com.rzg.zombieland.cliente.comunicacion.peticion.PeticionCambiarListoPartida; import com.rzg.zombieland.cliente.comunicacion.peticion.PeticionMovimiento; import com.rzg.zombieland.cliente.meta.Estado; import com.rzg.zombieland.cliente.meta.Estado.EscuchadorEstadoLobby; import com.rzg.zombieland.cliente.meta.Estado.EscuchadorProyeccion; import com.rzg.zombieland.cliente.meta.Estado.EscuchadorPuntaje; import com.rzg.zombieland.cliente.misc.RutaImagen; import com.rzg.zombieland.comunes.comunicacion.Peticion; import com.rzg.zombieland.comunes.comunicacion.ProyeccionTablero; import com.rzg.zombieland.comunes.comunicacion.pojo.POJOPartida; import com.rzg.zombieland.comunes.comunicacion.pojo.POJOResultadoRonda; import com.rzg.zombieland.comunes.comunicacion.respuesta.RespuestaGenerica; import com.rzg.zombieland.comunes.misc.Avatar; import com.rzg.zombieland.comunes.misc.EstadoPartida; import com.rzg.zombieland.comunes.misc.Movimiento.Direccion; import com.rzg.zombieland.comunes.misc.ZombielandException; /** * Interfaz de tablero. * * @author Manuel */ public class InterfazTablero extends JPanel implements EscuchadorProyeccion, EscuchadorEstadoLobby { private static final long serialVersionUID = 1L; private final Timer timer = new Timer(); // Constantes private static final int DIMENSION = 500; // Dimension en pixeles del // tablero private static final int MARGEN_IZQUIERDO = 10; private static final int MARGEN_SUPERIOR = 30; private static final int TAMA�O_FILA = 15; private Map<Avatar, Image> img; // Avatares private ImageIcon fondo; private JButton moveDown; private JButton moveRight; private JButton moveLeft; private JButton moveUp; // Tenemos una referencia al dispatcher de flechas para activarlo solamente cuando se muestra // la pantalla. private DispatcherFlechas dispatcher; private JPanel panelJugadores; private int tiempoProyeccion; private JLabel labelTemporizador; private class DispatcherFlechas implements KeyEventDispatcher { @Override public boolean dispatchKeyEvent(KeyEvent e) { if (e.getID() != KeyEvent.KEY_RELEASED) return false; switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: e.consume(); mover(Direccion.OESTE); return true; case KeyEvent.VK_RIGHT: e.consume(); mover(Direccion.ESTE); return true; case KeyEvent.VK_UP: e.consume(); mover(Direccion.NORTE); return true; case KeyEvent.VK_DOWN: e.consume(); mover(Direccion.SUR); return true; } return false; } } private class ModeloPuntaje extends AbstractTableModel implements EscuchadorPuntaje { private static final long serialVersionUID = -4290128679203618750L; private static final int COLUMNA_JUGADOR = 0; private static final int CANTIDAD_COLUMNAS = 2; private List<Entry<String, Integer>> jugadores; @Override public int getRowCount() { if (jugadores == null) return 0; return jugadores.size(); } @Override public int getColumnCount() { return CANTIDAD_COLUMNAS; } @Override public Object getValueAt(int rowIndex, int columnIndex) { if (jugadores == null) return null; if (columnIndex == COLUMNA_JUGADOR) { return jugadores.get(rowIndex).getKey(); } else { return jugadores.get(rowIndex).getValue(); } } @Override public void recibidoPuntaje(POJOResultadoRonda puntaje) { jugadores = new ArrayList<Entry<String, Integer>>(); for (Entry<String, Integer> entry : puntaje.getPuntajes().entrySet()) jugadores.add(entry); Collections.sort(jugadores, new Comparator<Entry<String, Integer>>() { @Override public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) { return o2.getValue().compareTo(o1.getValue()); } }); Rectangle rect = panelJugadores.getBounds(); Dimension dim = rect.getSize(); dim.setSize(dim.getWidth(), TAMA�O_FILA * (jugadores.size() + 1)); rect.setSize(dim); panelJugadores.setBounds(rect); fireTableDataChanged(); } @Override public String getColumnName(int column) { if (column == COLUMNA_JUGADOR) return "Jugador"; return "Puntaje"; } } public InterfazTablero() { dispatcher = new DispatcherFlechas(); setBorder(new EmptyBorder(5, 5, 5, 5)); setLayout(null); setBounds(100, 100, 800, 600); img = new HashMap<Avatar, Image>(); for (Avatar avatar : Avatar.values()) { img.put(avatar, new ImageIcon(RutaImagen.get("imagenes/Avatares/" + avatar.getSprite())).getImage()); } fondo = new ImageIcon(RutaImagen.get("imagenes/Tablero/pasto.png")); moveUp = new JButton(""); moveUp.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { mover(Direccion.NORTE); } }); moveUp.setIcon(new ImageIcon(RutaImagen .get("imagenes/Tablero/FlechaArriba.png"))); moveUp.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); moveUp.setBounds(640, 377, 45, 45); add(moveUp); moveLeft = new JButton(""); moveLeft.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { mover(Direccion.OESTE); } }); moveLeft.setIcon(new ImageIcon(RutaImagen .get("imagenes/Tablero/FlechaIzquierda.png"))); moveLeft.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); moveLeft.setBounds(587, 423, 45, 45); add(moveLeft); moveRight = new JButton(""); moveRight.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { mover(Direccion.ESTE); } }); moveRight.setIcon(new ImageIcon(RutaImagen .get("imagenes/Tablero/FlechaDerecha.png"))); moveRight.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); moveRight.setBounds(689, 423, 45, 45); add(moveRight); moveDown = new JButton(""); moveDown.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { mover(Direccion.SUR); } }); moveDown.setIcon(new ImageIcon(RutaImagen .get("imagenes/Tablero/FlechaAbajo.png"))); moveDown.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); moveDown.setBounds(640, 471, 45, 45); add(moveDown); JLabel label = new JLabel("RZG - 2015"); label.setForeground(SystemColor.textInactiveText); label.setBounds(700, 515, 63, 14); add(label); labelTemporizador = new JLabel("LALALA"); labelTemporizador.setHorizontalAlignment(SwingConstants.CENTER); labelTemporizador.setBackground(Color.RED); labelTemporizador.setFont(new Font("Tahoma", Font.BOLD, 18)); labelTemporizador.setForeground(Color.RED); labelTemporizador.setBounds(641, 220, 159, 45); add(labelTemporizador); panelJugadores = new JPanel(); panelJugadores.setBounds(561, 34, 193, TAMA�O_FILA); add(panelJugadores); panelJugadores.setLayout(new BorderLayout()); ModeloPuntaje modelo = new ModeloPuntaje(); Estado.getInstancia().setEscuchadorPuntaje(modelo); JTable table = new JTable(); table.setRowSelectionAllowed(false); table.setGridColor(Color.BLACK); table.setRowHeight(TAMA�O_FILA); table.setTableHeader(new JTableHeader(table.getColumnModel()) { private static final long serialVersionUID = 7787996933499011913L; @Override public Dimension getPreferredSize() { Dimension dim = super.getPreferredSize(); dim.height = TAMA�O_FILA; return dim; } }); table.setBorder(new LineBorder(new Color(0, 0, 0))); table.setModel(modelo); table.getColumnModel().getColumn(0).setResizable(false); table.getColumnModel().getColumn(0).setPreferredWidth(120); table.getColumnModel().getColumn(0).setMinWidth(50); table.getColumnModel().getColumn(1).setResizable(false); table.setFocusable(false); table.setBounds(0, 0, 193, 304); panelJugadores.add(table.getTableHeader(), BorderLayout.NORTH); panelJugadores.add(table, BorderLayout.CENTER); JLabel labelFondo = new JLabel(""); labelFondo.setIcon(new ImageIcon(RutaImagen .get("imagenes/Fondos/fondo-tablero.png"))); labelFondo.setBounds(0, 0, 800, 600); add(labelFondo); addComponentListener(new ComponentListener() { final KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); @Override public void componentShown(ComponentEvent e) { TimerTask task = new TimerTask() { @Override public void run() { EventQueue.invokeLater(new Runnable() { @Override public void run() { labelTemporizador.setText(Integer.toString(tic())); } }); } }; // Programo el timer para que act�e cada 1000ms. timer.schedule(task, 0, 1000); if (!Estado.getInstancia().isEspectador()) manager.addKeyEventDispatcher(dispatcher); } @Override public void componentResized(ComponentEvent e) { } @Override public void componentMoved(ComponentEvent e) { } @Override public void componentHidden(ComponentEvent e) { manager.removeKeyEventDispatcher(dispatcher); } }); Estado.getInstancia().addEscuchadorLobby(this); Estado.getInstancia().addEscuchadorProyeccion(this); } public void paint(Graphics g) { super.paint(g); update(g); } public void update (Graphics g) { ProyeccionTablero proyeccion = Estado.getInstancia().getEstadoLobby() .getProyeccion(); proyeccion.paint(g, img, DIMENSION, MARGEN_IZQUIERDO, MARGEN_SUPERIOR, fondo); } /** * Env�a una petici�n de movimiento. * * @param este */ private void mover(Direccion direccion) { PeticionMovimiento peticion = new PeticionMovimiento(direccion); final InterfazTablero this_ = this; try { ServicioCliente.getInstancia().getHiloEscucha() .enviarPeticion(peticion); peticion.getRespuesta().then(new DoneCallback<RespuestaGenerica>() { @Override public void onDone(RespuestaGenerica respuesta) { if (!respuesta.fuePeticionExitosa()) { JOptionPane.showMessageDialog(this_, respuesta.getMensajeError(), "Zombieland tablero", JOptionPane.ERROR_MESSAGE); } } }); } catch (ZombielandException e) { JOptionPane.showMessageDialog(this, e.getMessage(), "Zombieland tablero", JOptionPane.ERROR_MESSAGE); } } /** * Llamado cuando pas� una unidad de tiempo. * @return el tiempo restante al siguiente turno. */ private int tic() { if (tiempoProyeccion == 0) return 0; return tiempoProyeccion--; } @Override public void notificarCambioEstadoEspectador(boolean espectador) { moveDown.setVisible(!espectador); moveUp.setVisible(!espectador); moveRight.setVisible(!espectador); moveLeft.setVisible(!espectador); } @Override public void notificarProyeccionActualizada(ProyeccionTablero proyeccion) { tiempoProyeccion = proyeccion.getTiempoParaElSiguientePaso() / 1000; labelTemporizador.setText(Integer.toString(tiempoProyeccion)); repaint(); } @Override public void notificarLobbyActualizado(POJOPartida pojo) { if (pojo.getEstado() == EstadoPartida.FINALIZADA) { int respuesta = JOptionPane.showConfirmDialog(this, "La partida ha terminado �Desea continuar?", "Partida Zombieland", JOptionPane.YES_NO_OPTION); Peticion<?, RespuestaGenerica> peticion; if (respuesta == JOptionPane.YES_OPTION) { peticion = new PeticionCambiarListoPartida(true); Main.irA(Main.LOBBY); } else { peticion = new PeticionAbandonarPartida(); Main.irA(Main.LISTADO_PARTIDAS); } try { ServicioCliente.enviarPeticion(peticion); peticion.getRespuesta().then(new DoneCallback<RespuestaGenerica>() { @Override public void onDone(RespuestaGenerica respuesta) { if (!respuesta.fuePeticionExitosa()) { JOptionPane.showMessageDialog(getParent(), respuesta.getMensajeError(), "Partida Zombieland", JOptionPane.ERROR_MESSAGE); } } }); } catch (ZombielandException e) { JOptionPane.showMessageDialog(this, e.getMessage(), "Partida Zombieland", JOptionPane.ERROR_MESSAGE); } } } }