Posición del círculo
Como mencionamos antes cada vez que pintamos debemos definir la posición (x,y) donde dibujaremos en este caso el círculo. Para que el círculo se mueva debemos modificar la posición (x,y) cada cierto tiempo y volver a pintar el círculo en la nueva posición.En nuestro ejemplo mantendremos en dos propiedades llamadas "x" e "y", la posición actual de nuestro círculo. También creamos un método moveBall() que incrementará en 1 tanto a "x" como a "y" cada vez que es llamado. En el método paint dibujamos un circulo de 30 pixeles de diámetro en la posición (x,y) dada por las propiedades antes mencionadas "g2d.fillOval(x, y, 30, 30);".
Game loop
Al final del método main iniciamos un ciclo infinito "while (true)" donde repetidamente llamamos a moveBall() para cambiar la posición del circulo y luego llamamos a repaint() que fuerza al motor AWT a llamar al método paint para repintar el lienzo.Este ciclo o repetición se conoce como "Game loop" y se caracteriza por realizar dos operaciones:
- Actualización (Update): actualización de la física de nuestro mundo. En nuestro caso nuestra actualización esta dada tan solo por el método moveBall() que incrementa las propiedades "x" e "y" en 1.
- Renderizado (Render): aquí se dibuja según el estado actual de nuestro mundo reflejando los cambios realizados en el paso anterior. En nuestro ejemplo este renderizado esta dado por la llamada a repaint() y la subsecuente llamada a paint realizada por el motor AWT o más específicamente por el Hilo de cola de eventos.
package com.edu4java.minitennis2; 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; private void moveBall() { x = x + 1; y = y + 1; } @Override public void paint(Graphics g) { super.paint(g); Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.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); } } }Al ejecutar el código anterior obtendremos:
Analizando nuestro método paint
Como mencionamos en el tutorial anterior este método se ejecuta cada vez que el sistema operativo le indica a Motor AWT que es necesario pintar el lienzo. Si ejecutamos el método repaint() de un objeto JPanel lo que estamos haciendo es decirle al Motor AWT que ejecute el método paint tan pronto como pueda. La llamada a paint la realizará el Hilo de cola de eventos. Llamando a repaint() logramos que se repinte el lienzo y así poder reflejar el cambio en la posición del circulo.@Override public void paint(Graphics g) { super.paint(g); Graphics2D g2d = (Graphics2D) g; g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.fillOval(x, y, 30, 30); }La llamada a "super.paint(g)" limpia la pantalla, si comentamos esta línea podemos ver el siguiente efecto:
La instrucción "g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)" suaviza los bordes de las figuras como se puede ver en el siguiente gráfico. El círculo de la izquierda es sin aplicar ANTIALIAS y el de la derecha aplicando ANTIALIAS.
No hay comentarios:
Publicar un comentario