Autor Tema: Java mover circulo en pantalla Graphics2D según eventos teclado KeyAdapter Timer  (Leído 12805 veces)

caludo

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 33
    • Ver Perfil
Hola! Estoy practicando/aprendiendo en Java y he hecho un pequeño ejercicio que consta de poder mover una bola con el teclado(con las flechas de direccion), si dejo de pulsar las flechas del teclado, la bola sigue su curso, y si llega al borde del panel la bola rebota y cambia de direccion. Hasta aquí todo correcto, de hecho me funciona correctamente.....

.... PERO mi duda es como lo puedo hacer mediante la clase Thread. En este ejercicio uso basicamente la clase Timer  para el movimiento de la pelota y las clases keyReleased y keyPressed para poder cambiar la direccion de la pelota por teclado. Pero mi intensión es hacerlo con Thread en lugar de con Timer y mantener keyReleased y keyPressed para poder dirigir la direccion de la bola.


Además tengo otra duda, tengo entendido que(sobre eventos) la clase ActionListener solo sirve para llevar a cabo una accion en componentes (por ejemplo botones) o sea no podría usarlo para hacer click en la bola( o imagen, o lo que sea que esté dibujado y no sea un componente como un botón) y que esta pudiera "responder" a ese click(por ejemplo al hacer click en la bola, esta cambia de color).¿Qué tipo de eventos puedo usar para esto?Supongo que hacer "click" sobre un dibujo o imagen en movimiento no será muy complicado, pero no se como hacerlo.

El código es:

Código: [Seleccionar]
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.*;

import javax.swing.*;

public class Bola1 extends JFrame{

Panell panel=new Panell();

 public Bola1(){

super("Bola Movimientoo");

setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

add(panel);

setVisible(true);



 }

 public static void main(String[]args){

Bola1 bolita=new Bola1();


 }


}

class Panell extends JPanel implements ActionListener{

BolaMovimientos bolaMov=new BolaMovimientos(this);
Timer timer;

 public Panell(){


setFocusable(true);
addKeyListener(new teclado());
timer=new Timer(15,this);
timer.start();

}



 public void paintComponent(Graphics g){

super.paintComponent(g);

Graphics2D g2=(Graphics2D)g;
g2.setColor(Color.red);
g2.fillOval(bolaMov.getX(), bolaMov.getY(), 30, 30);

 }



@Override
public void actionPerformed(ActionEvent e) {


 bolaMov.mover();
 repaint();


}
private class teclado extends KeyAdapter{

public void keyReleased(KeyEvent e){
bolaMov.keyReleased(e);
}
public void keyPressed(KeyEvent e){
bolaMov.keyPressed(e);
}
}
}




class BolaMovimientos{



Panell panel1;

int x=1;
int y=1;
int dx=0;
int dy=0;

public BolaMovimientos(Panell panelito){

this.panel1=panelito;

}

public void mover(){

x=x+dx;
y=y+dy;

if((x+dx)>panel1.getWidth()-30){
dx=-1;

}else if((x+dx)<0){
dx=1;

}else if((y+dy)>panel1.getHeight()-30){
dy=-1;

}else if((y+dy)<0){
dy=1;
}




}

public void keyPressed(KeyEvent e){

int key=e.getExtendedKeyCode();

if(key==KeyEvent.VK_LEFT){

dx=-1;
dy=0;

}
if(key==KeyEvent.VK_RIGHT){

dx=1;
dy=0;

}
if(key==KeyEvent.VK_UP){

dx=0;
dy=-1;

}
if(key==KeyEvent.VK_DOWN){

dx=0;
dy=1;

}

}

public void keyReleased(KeyEvent e){

int key=e.getExtendedKeyCode();

if(key==KeyEvent.VK_LEFT){



}
if(key==KeyEvent.VK_RIGHT){



}
if(key==KeyEvent.VK_UP){



}
if(key==KeyEvent.VK_DOWN){



}

}


public int getX(){

return x;
}
public int getY(){
return y;

}

}

Espero que se pueda entender el codigo! :P

Muchisimas Gracias por todo y saludos!!
« Última modificación: 25 de Noviembre 2015, 08:31 por Ogramar »

César Krall

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2078
  • No vales por lo que dices, sino por lo que haces
    • Ver Perfil
    • aprenderaprogramar.com
Hola!

Aunque es más complejo que esto, thread a la hora de controlar una animación se usuaría para definida la animación al completo por ejemplo mediante un bucle, detener la ejecución cada cierto intervalo de tiempo de modo que podamos ver cómo evoluciona la situación. Aquí hay un ejemplo con una animación de un cohete en lanzamiento https://www.aprenderaprogramar.com/foros/index.php?topic=1699.0

Los Timers son objetos que se usan para establecer que algo debe ejecutarse una única vez después de cierta demora, o bien para establecer que algo debe ejecutarse repetidamente, aquí una aplicación típica sería actualizar la visualización-estado de un componente periódicamente.

Una regla aproximada que puede seguirse es:

- Usar Timer siempre que se trate de una aplicación con interfaz gráfica (como en este caso) que deba detectar eventos. Si se usa Thread.sleep lo que haríamos sería "detener" el programa por unos instantes, de modo que no se detectaría por ejemplo una pulsación de tecla y parecería que el programa no funciona. Esto con Timer no ocurre.

Para cambiar el color de una figura cuando hagas click sobre ella te puedes guiar por este ejemplo: https://www.aprenderaprogramar.com/foros/index.php?topic=3530.0

Saludos!
Responsable de departamento de producción aprenderaprogramar.com

caludo

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 33
    • Ver Perfil
Hola Cesar!Gracias por la respuesta y por los ejemplos.Creo que lo he entendido perfectamente.
Quería preguntarte un par de cosas para ver si realmente lo he entendido.
O sea, por tu explicacion deduzco que:
-Si yo quiero que las figuras geometricas de tu codigo se muevan y cambien de color al pulsarlas, entonces usaría timer, y no thread.
-Si simplemente creo 2 o mas figuras(por ejemplo un circulo, o una imagen) en movimiento...lo hago usando Thread...si quiero que ocurra algo(como que cambien de color, desaparezcan,etc) al pulsar un botón, también usaría Thread...PERO si quiero que ocurra algo(que cambien de color, desaparezcan,etc) al pulsar sobre la misma figura(y no a traves de un botón) entonces usaría Timer

Es esto correcto? Gracias por todo y saludos!!!

PS. Supongo que las animaciones además de Thread y Timer se puede hacer con otras clases, pero de momento lo desconozco


César Krall

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2078
  • No vales por lo que dices, sino por lo que haces
    • Ver Perfil
    • aprenderaprogramar.com
Hola!

Yo lo que te recomendaría es que uses Timer para desarrollar tus programas, con eso vas a poder resolverlo casi todo y puedes olvidarte de Thread. Sólo deberías usar Thread cuando la ejecución concurrente de eventos genere conflictos y esto haga recomendable mantener dos hilos de ejecución. A veces se usa Thread.sleep con un solo hilo para forzar la detención del programa, digamos que una pausa de ejecución, pero esto realmente no es uso de hilos, sino simplemente pausar el hilo único que está en ejecución.

Saludos!
Responsable de departamento de producción aprenderaprogramar.com

caludo

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 33
    • Ver Perfil
Muchas gracias Cesar!

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".