[Pong] IV: Tortipapas de poder +1

La red social me parece un invento magnífico. Gracias a los enlaces que publico de este blog en ellas hacen que esto sea algo más que un desierto donde me da por escribir cosas de frikis. De hecho, según las estadísticas han llegado visitas de toda España y EEUU (un saludo queridos seguidores yankees! :-D). Aprovecho para invitaros también a compartir toda actualización de este cuaderno de bitácora que os guste.

Pues bien, hace ya unos días, cuando me atasqué con las raquetas ofrecí una tortilla de patatas para aquel que consiguiese resolver el problema. Las ideas que se me habían pasado por la cabeza eran o cambiar el método de control del juego, algo que no me gustaba pero contemplaba como última opción o, lo que yo consideraba mejor, trabajar con un hilo independiente para cada una de las raquetas, algo que, simplemente: no se hacer.

Así fue como el señor Eduardo Martinez (a.k.a Master Java) apareció cual personaje de ficción atravesando una nube de humo y ofreciéndome la pastilla roja. Y es que, no solo resolvió el problema, si no que además lo hizo sin utilizar hilos, de una manera muy sencilla a la par que ingeniosa. Es por ello que lo suyo no será una simple tortilla de patatas, se ha ganado una tortipapas de poder +1. Y aquí va la prueba de ello.

Como la única clase que tiene que ser modificada para esto es la clase Raqueta, voy a tomarme la libertad en esta ocasión de explicar solo el código de esta (si alguien llega de nuevas puede ver el resto del código y explicación en la anterior entrada). Voy a hacerlo tal cual yo lo he interpretado, pero así mismo animo a Edu a que se pase por aquí y comente el mismo su idea, por eso de que al César lo que es del César.

El problema que tenía antes era que los eventos de las raquetas chocaban uno con el otro lo que no permitía el movimiento de una de ellas mientras se movía la otra. Esto es lo que en argot informático se llama: joder la marrana.

La solución que ha traído Edu se basa en añadir a la clase Raqueta dos variables booleanas, a las que damos el nombre de subiendo y bajando. Alteraremos sus valores a false, cada vez que nuestra acción de teclado sea un evento keyReleased() y a true cuando se trate de un keyPressed(). Es decir, analizaremos la tecla que estamos pulsando o levantando y le daremos un valor a la variable en función de la misma.

Así, al método mover() le exigiremos también que contemple que el valor de subiendo o bajando sea verdadero antes de realizar la acción del movimiento, de manera que ahora, aunque los eventos choquen, la raqueta seguirá avanzando mientras el valor de la variable no sea false. Aquí va el código:

package Grafico;

import Configuracion.Configuracion;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;

/**
 * Clase Raqueta que definirá las pautas para poder crear los dos objetos de
 * este tipo.
 * @author Phil Spectrum
 */
public class Raqueta
{
    private int x;
    private int y;
    private int ya;
    private int arriba;
    private int abajo;
    private Configuracion config;
    private boolean subiendo, bajando;

    /**
     * En su constructor pedimos los valores para los atributos que necesitaremos
     * En el caso de "x", "y", "arriba" y "abajo" serán diferentes para cada jugador
     * Iniciamos también en false los atributos subiendo y bajando
     * @param x la posición x que ocupará la raqueta en el frame
     * @param y la posición y que ocupará la raqueta en el frame
     * @param arriba el código de la tecla que hará que la raqueta se mueva hacia arriba
     * @param abajo el código de la tecla que hará que la raqueta se mueva hacia abajo
     * @param config llamada a la clase Configuración donde se define el tamaño
     */
    public Raqueta(int x, int y, int arriba, int abajo, Configuracion config)
    {
        this.ya = 1;
        this.subiendo = false;
        this.bajando = false;
        this.x = x;
        this.y = y;
        this.arriba = arriba;
        this.abajo = abajo;
        this.config = config;
    }

    /**
     * Método que controla el movimiento de la raqueta
     * Permite sumar o restar el valor del atributo "ya" al de "y" siempre y cuando
     * la raqueta no haya pasado de los límites del frame y los atributos
     * "bajando" o "subiendo" tengan valor verdadero.
     */
    public void mover()
    {
        //Aquí resto 28 pixels igual que los 25 de la clase pelota
        if (((y + ya >= 0) & (y - ya < (config.getY() - 28) - config.getLARGO_RAQUETA()) & bajando))
        {
            y = y + ya;
        }
        else if (((y + ya) > 0) && ((y - ya) <= ((config.getY() - 28) - config.getLARGO_RAQUETA())) && subiendo)
        {
            y = y - ya;
        }
    }

    /**
     * Método para dibujar la raqueta
     * @param g le envia los gráficos
     */
    public void dibujarRaqueta(Graphics2D g)
    {
        g.setColor(Color.GRAY);
        g.fillRect(x, y, config.getANCHO_RAQUETA(), config.getLARGO_RAQUETA());
    }

    /**
     * Con este método, cuando el usuario levanta la tecla el movimiento se para
     * ya que a la variable que lo controla se le da el valor de false
     * @param e captura un evento de teclado
     */
    public void keyReleased(KeyEvent e)
    {
        if (e.getKeyCode() == arriba)
        {
            subiendo = false;
        }
        else if (e.getKeyCode() == abajo)
        {
            bajando = false;
        }
    }

    /**
     * Con keyPressed indicamos lo que queremos hacer cuando se pulsa una tecla
     * En este caso, las teclas irán definidas por los atributos "arriba" y "abajo"
     */
    public void keyPressed(KeyEvent e)
    {
        if (e.getKeyCode() == arriba)
        {
            subiendo = true;
        }
        else if (e.getKeyCode() == abajo)
        {
            bajando = true;
        }
    }

    public int getX()
    {
        return x;
    }

    public int getY()
    {
        return y;
    }

    /**
     * Con este método crearemos un rectángulo alrededor de la raqueta que podremos usar
     * para comprobar las colisiones
     * @return el rectángulo
     */
    public Rectangle getBounds()
    {
        return new Rectangle(x, y, config.getANCHO_RAQUETA(), config.getLARGO_RAQUETA());
    }

}

Así es que, señor Eduardo, es usted bienvenido a reclamar su premio y echarnos unas partidas de Pong cuando guste :-].

En la siguiente entrada pondré ya algunos sonidos al juego y le daré algunos retoques extra, como la puntuación y todo eso. ¿Qué os parece? ^_^

Anuncios
Esta entrada fue publicada en Happy Coding y etiquetada , , , , , . Guarda el enlace permanente.

11 respuestas a [Pong] IV: Tortipapas de poder +1

  1. Carlos Nieto dijo:

    Me gusta la solución de Eduardo, el concepto de la que estaba escribiendo yo es…

    boolean player1FlagArr,player1FlagAba, player2FlagArr, player2FlagAba <–declarar como boleanos jugardir1flechaarriba,etc…

    y luego…

    // Aqui declaramos el evento apretar tecla
    public void keyPressed(KeyEvent evt)
    {
    switch(evt.getKeyCode())
    {
    // Mover jug1
    case KeyEvent.VK_W :
    player1FlagArr = true;
    break;
    case KeyEvent.VK_S :
    player1FlagAba = true;
    break;

    // Mover jug2
    case KeyEvent.VK_UP:
    player2FlagArr=true;
    break;
    case KeyEvent.VK_DOWN:
    player2FlagAba=true;
    break;
    }
    }

    // aqui declaramos el evento soltar tecla
    public void keyReleased(KeyEvent evt)
    {
    switch(evt.getKeyCode())
    {
    // Mover jug11
    case KeyEvent.VK_W :
    player1FlagArr = false;
    break;
    case KeyEvent.VK_S :
    player1FlagAba = false;
    break;

    // Mover jug 2
    case KeyEvent.VK_UP:
    player2FlagArr=false;
    break;
    case KeyEvent.VK_DOWN:
    player2FlagAba=false;
    break;
    }
    }

    Mas o menos…. está sin revisar :S

    • Por cierto, esto es una prueba, no se si funcionará también en los comentarios:

      System.out.println("Hola majete!");
      

      A ver… ^_^

      • Cojonudo, si encierras tu código entre las etiquetas “code language=”java”” metiendo el código en medio y cerrando con “/code” (cambiando las comillas por corchetes []) te pone el código más legible como puedes ver ^_^

  2. Carlos Nieto dijo:

    Obviamente tendrias que reescribir la clase mover 🙂

    • Entiendo la idea y me parece que está bien también, pero creo que lo complica más. Ahí estás escribiendo código para cada raqueta, limitando el movimiento únicamente a las teclas de dirección y a la “W” y “S”. Lo bueno (creo) de como lo he ido haciendo aquí es que al programa no le importan las teclas que pulses, solamente le importa si el código de tecla que le has mandado al constructor de la raqueta que quieres mover coincide con el código de la tecla que estás pulsando. Con ello te evitas crear un código específico para cada objeto, todo funciona a través de los mismos métodos genéricos.

      O eso o yo he entendido mal tus malvados planes 😀

      Un saludito!

  3. Edu dijo:

    ¡¡ Me alegro que te haya gustado !! Doy por reclamada mi tortila 🙂

  4. Pingback: [Pong] V: El que mete saca | The Phil Spectrum Project

  5. JooseLuis dijo:

    Tienes comentado el problema de “los 25 px” en fp-informatica.
    PD: Como sea eso quiero mi tortilla de papas ehh

    • JooseLuis, muchas gracias! no he tenido tiempo de mirarlo (estoy a un par de días ya de mis exámenes de septiembre), pero te prometo que le echaré un concienzudo ojo en cuanto termine 😉

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s