Sprites - Velocidad y dirección
Cada objeto que se mueve en la pantalla tiene características propias como la posición (x,y), la velocidad y la dirección en que se mueve, etc. Todas estas características se pueden aislar en un objeto que llamaremos Sprite.
Velocidad y dirección
En el tutorial anterior logramos que la pelota (el círculo) se moviera hacia abajo y a la derecha a un píxel por vuelta en el Game Loop. Cuando llegaba al limite de la pantalla la pelota seguía su curso desapareciendo del lienzo. Lo que haremos a continuación es que la pelota rebote en los limites del lienzo cambiando su dirección.
package com.edu4java.minitennis3; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import javax.swing.JFrame; import javax.swing.JPanel; @SuppressWarnings("serial") public class Game extends JPanel { int x = 0; int y = 0; int xa = 1; int ya = 1; private void moveBall() { if (x + xa < 0) xa = 1; if (x + xa > getWidth() - 30) xa = -1; if (y + ya < 0) ya = 1; if (y + ya > getHeight() - 30) ya = -1; x = x + xa; y = y + ya; } @Override public void paint(Graphics g) { super.paint(g); Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.fillOval(x, y, 30, 30); } public static void main(String[] args) throws InterruptedException { JFrame frame = new JFrame("Mini Tennis"); Game game = new Game(); frame.add(game); frame.setSize(300, 400); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); while (true) { game.moveBall(); game.repaint(); Thread.sleep(10); } } }
En el código anterior se agregaron dos propiedades "xa" y "ya" que representan la velocidad en que se mueve la pelota. Si xa=1, la pelota se mueve hacia la derecha a un píxel por vuelta del Game Loop y si xa=-1, la pelota se mueve hacia la izquierda. Similarmente ya=1 mueve hacia abajo y ya=-1 mueve hacia arriba. Esto lo logramos con las líneas "x = x + xa" e "y = y + ya" del método moveBall().
Antes de ejecutar las instrucciones anteriores verificamos que la pelota no salga de los márgenes del lienzo. Por ejemplo cuando la pelota alcance el margen derecho o lo que es lo mismo cuando (x + xa > getWidth() - 30) lo que haremos es cambiar la dirección del movimiento sobre el eje x o lo que es lo mismo asignar menos uno a xa "xa = -1".
private void moveBall() { if (x + xa < 0) xa = 1; if (x + xa > getWidth() - 30) xa = -1; if (y + ya < 0) ya = 1; if (y + ya > getHeight() - 30) ya = -1; x = x + xa; y = y + ya; }
Cada sentencia if limita un borde del lienzo.
Crear el Sprite Ball (pelota en inglés)
La idea es crear una clase llamada Ball que aisle todo lo referente a la pelota. En el siguiente código podemos ver como extraemos todo el código referente a la pelota de la clase Game2 y lo incorporamos a nuestra nueva clase Ball.
package com.edu4java.minitennis3; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import javax.swing.JFrame; import javax.swing.JPanel; @SuppressWarnings("serial") public class Game2 extends JPanel { Ball ball = new Ball(this); private void move() { ball.move(); } @Override public void paint(Graphics g) { super.paint(g); Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); ball.paint(g2d); } public static void main(String[] args) throws InterruptedException { JFrame frame = new JFrame("Mini Tennis"); Game2 game = new Game2(); frame.add(game); frame.setSize(300, 400); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); while (true) { game.move(); game.repaint(); Thread.sleep(10); } } }
El Sprite Ball necesita que le envíen una referencia al objeto Game para obtener los limites del lienzo y así saber cuando debe cambiar de dirección. En el método move() de la clase Ball se llama a game.getWidth() y game.getHeight().
package com.edu4java.minitennis3; import java.awt.Graphics2D; public class Ball { int x = 0; int y = 0; int xa = 1; int ya = 1; private Game2 game; public Ball(Game2 game) { this.game= game; } void move() { if (x + xa < 0) xa = 1; if (x + xa > game.getWidth() - 30) xa = -1; if (y + ya < 0) ya = 1; if (y + ya > game.getHeight() - 30) ya = -1; x = x + xa; y = y + ya; } public void paint(Graphics2D g) { g.fillOval(x, y, 30, 30); } }
Si ejecutamos Game2 obtendremos el mismo resultado que si ejecutamos la versión anterior Game. La conveniencia de esta separación del código referente a la pelota en una clase de tipo Sprite se vuelve más obvia cuando incluimos la raqueta mediante un nuevo Sprite en un próximo tutorial.
<< Anterior | Siguiente>> |