Problemas con Thread - Graphics

Iniciado por S_Code, 5 Enero 2016, 12:12 PM

0 Miembros y 1 Visitante están viendo este tema.

S_Code

Buenos días a tod@!

Me presento, soy estudiante de un FP de informática y tengo que realizar una "copia" lo más parecida a esta versión de Asteroid: http://www.juegomaniac.com/jugar.php?id=51&ancho=740&alto=510

A base de manuales y explicaciones he conseguido ir haciendo poco a poco. El problema es que tengo algunos problemas y no consigo solucionar por más pruebas que realizo. Hay parte de código desactivada porque al quitar el funcionamiento del Thread, funciona.

Aquí os expongo una explicación de uno de los problemas que tengo. Gracias de antemano por molestarse en el leer el post.

Los thread de Asteroid, Disparo y Enemigo:

- Con el Asteroid el problema que tengo es cuando disparo a uno de ellos a la hora de dividirse se queda parado, entiendo que es porque esos nuevos asteroides creados no se ponen en marcha, pero he intentado todas las formas que he creído que deberían de funcionar para que funcionen, pero algo hago mal. Y además en ocasiones no detectan las colisiones. Esta puesto en start porque en el método de Acciones, no funcionaba.

- Con el de Enemigo, el problema es que no detecta las colisiones al poner el Thread, sin él, funciona correctamente. Esta puesto en el método de acciones porque en start no funcionaba.

- El disparo, directamente no funciona, se muestra el disparo, y ya esta, no se mueve.

Os pongo todo el código para que entendáis como lo tengo a ver si alguien sabe dónde esta el fallo.

EspacioFrame - Arranca el juego

Código (java) [Seleccionar]

package asteroides;

//Importamos las librerias necesarias
import java.awt.BorderLayout;
import javax.swing.JFrame;
 
/**
* Clase del juego que contiene Jframe con la parte del Canvas y se inicia el juego
*/

public class EspacioFrame extends JFrame {
   public EspacioFrame() {
       //Iniciamos un espacio que contiene el canvas
       EspacioCanvas jc = new EspacioCanvas ();
       //Lo añadimos
       this.add(jc, BorderLayout.CENTER);
       //Le damos el tamaño que tiene
       this.setSize((int)jc.ancho, (int)jc.alto);
       //Le decimos como debe cerrarse
       this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       //Centramos la ventana
       this.setLocationRelativeTo(null);
       //Le ponemos un titulo a la ventana
       this.setTitle("Asteroid by Sandra Ibañez");  
       //Lo hacemos visible
       this. setVisible (true);
       //Creamos dos bufferstrategy para el paint
       jc.createBufferStrategy(2);
       //Iniciamos el juego que conriene el canvas
       jc.start();
   }

   public static void main(String[] args) {
       //Iniciamos el juego
       EspacioFrame j1 = new EspacioFrame();  
       j1.repaint();
   }
}


EspacioCanvas: Parte gráfica del juego y acciones del juego

Código (java) [Seleccionar]

package asteroides;

//Importamos librerias
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Point2D;
import java.awt.image.BufferStrategy;
import java.util.ArrayList;
import javax.swing.JOptionPane;

/**
* Clase del juego que contiene el canvas, y keylistener para las teclas del teclado
* OBJETIVO; Copiar la versión del juego Asteroid: http://www.juegomaniac.com/jugar.php?id=51&ancho=740&alto=510
* ESPACIO: DISPARA
* ARRIBA: ACELERA
* IRQUIERDA: GIRA IRQUIERDA
* DERECHA: GIRA DERECHA
* SHIFT: DESAPARECE DE LA POSICIÓN Y APARECE EN OTRA POSICIÓN ALEATORIA
*/
public class EspacioCanvas extends Canvas implements KeyListener, Runnable {
   //Tamaño de la ventana del juego
   double ancho;
   double alto;
   //Variables de tiempo
   long refrescar;
   long inicio;
   long fin;
   //Variables de jugador
   int vidas;
   long puntos;
   String nombre;
   //Nave
   Nave nave;
   //Booleans para saber si hay colisión
   boolean colisionNave;
   //ArrayList de disparos
   ArrayList<Disparo> disparos;
   //Variables del disparo
   final double tiempoDisparo = 10;
   double tiempoFinalDisparo;
   //ArrayList de los asteroid
   ArrayList <Asteroid> asteroides;
   //Número de asteroides con los que se inicia el juego
   int numeroAsteroides = 4;
   //ArrayList de asteroides eliminados
   ArrayList<Asteroid> asteroidEliminado;
   ArrayList<Enemigo> ovni;
   //Threads para arranque (tiempo para iniciar), espera (tiempo para actualizar), naveFuera (tiempo que la nave desaparece, cuando choca o se mueve a otro sitio)
   Thread arranque;
   Thread espera;
   //Dimension de la ventana
   Dimension dim;
   //Booleans para el paint, y mostrar nave o no (por colisión)
   boolean repintar = false;
   boolean mostrarNave = false;
   boolean ovn = false;
   int contador;
   int vidaOvni = 1;
   long contSalirOvni;
   /**
    * Constructor de la clase.
    */
   public EspacioCanvas () {
       //Configuraciones de la ventana
       setIgnoreRepaint (false);
       resize (740, 510);
       dim = getSize ();
       ancho = dim.width;
       alto = dim.height;
       //Tiempo de actualización
       refrescar = 25;
       //Cogemos las acciones del teclado
       addKeyListener(this);
       setFocusable(true);
       //Creamos una nave nueva en el centro
       nave = new Nave(ancho/2, alto/2, 30, 0.10, 0.5, 0.90);
       //Boolean relacionado con la nave, falsos
       colisionNave = false;
       //Número de vidas
       vidas = 3;
       //Declaramos los arrayList
       asteroides = new ArrayList<Asteroid>();
       asteroidEliminado = new ArrayList <Asteroid>();
       disparos = new ArrayList<Disparo>();
       ovni = new ArrayList <Enemigo>();
   }
   /**
    * Get de las vidas de la nave - jugador
    * @return
    */
   public int getVidas() {
       return vidas;
   }
   /**
    * Método de dibujar, mediante bufferstrategy se guardan los elementos y se van actualizando según las acciones
    * @param g
    */
   @Override
   public void paint (Graphics g) {
       //Si el boolean es cierto, sigue
       if (repintar)
           return;
       repintar = true;
       //Creamos una dimensión nueva con la anterior
       Dimension dNueva = dim;
       dNueva = getSize();
       //Cogemos el bufferstrategy
       BufferStrategy buffer = getBufferStrategy();
       //Le pasamos al graphics el dibujo
       Graphics imagen = buffer.getDrawGraphics();
       //Y la clase le pasamos el resultado
       super.paint(imagen);
       Graphics2D g2d = (Graphics2D) imagen;
       g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
       //Le ponemos fondo negro
       setBackground(Color.BLACK);
       //Pinta relleno de todo el juego
       g2d.fillRect(0, 0, (int) ancho, (int) alto);
       //Cogemos el color blanco
       g2d.setColor(Color.WHITE);
       //Dibujamos un string dónde se muestra la puntuación
       g2d.drawString(""+puntos, 30, 30);
       //Recorremos el array de los asteroides y los pintamos
       for (int cont = 0; cont < asteroides.size(); cont ++) {
           asteroides.get(cont).pintar(g2d);
       }
       //Recorremos el array de los asteroides eliminados, cuando son disparados
       for (int cont = 0; cont < asteroidEliminado.size() ; cont ++) {
           asteroidEliminado.get(cont).pintarExplosion(g2d);
       }
       //Pintamos disparos cuando se realizan
       for (int cont = 0; cont < disparos.size(); cont ++) {
           disparos.get(cont).pintar(g2d);
       }
       //Si se debe mostrar el ovni, se muestra
       if (ovn) {
           for (int cont = 0; cont < ovni.size(); cont ++) {
               ovni.get(cont).pintar(g2d);
           }
       }
       //Si el boolean de mostrar la nave esta activado, la dibujamos
       if (mostrarNave) {
           nave.pintar(g2d);
       }
       //Si la nave ha chocado
       while (colisionNave) {
           colocarNave();
       }
       //Posición
       g2d.translate(40, 45);
       //Tamaño
       g2d.scale(0.50, 0.50);
       //Recorremos las vidas
       for (int cont = 0; cont < this.getVidas(); cont ++) {
           //Mostramos los dibujos en pequeño de la nave para las vidas
           g2d.setColor(Color.white);
           int [] posicionInicialHorizontal = {-8, 0, -6, 6, 8, 0};
           int [] posicionInicialVertical = {10, -10, 6, 6, 10, -10};
           g2d.drawPolygon(posicionInicialHorizontal, posicionInicialVertical, posicionInicialHorizontal.length);
           g2d.translate(30, 0);
       }
       //Si graphics es diferentre de null
       if (imagen != null) {
           imagen.dispose();
       }
       //Cerramos el buffer
       buffer.show();
       Toolkit.getDefaultToolkit().sync();
       //False el repintar
       repintar = false;
   }
   @Override
   public void update (Graphics g) {
       paint(g);
   }
   
   public void colocarNave () {
       //Restamos vidas
       vidas--;
       //Colocamos la nave al centro
       nave.setHorizontal(ancho / 2);
       nave.setVertical(alto / 2);
       //Volvemos a mostrar la nave
       mostrarNave = true;
       colisionNave = false;
   }
   @Override
   public void keyTyped(KeyEvent e) {}
   /**
    * Método que para cuando se pulsan las teclas
    * @param e
    */
   @Override
   public void keyPressed(KeyEvent e) {
       //Cogemos el código de la tecla presionada para saber que acción hace
       int tecla = e.getKeyCode();
       //Si la tecla es el espacio, dispara
       if (tecla == KeyEvent.VK_SPACE) {
           nave.disparo = true;
           if (tiempoFinalDisparo <= 0) {
               disparos.add(nave.disparo());
               tiempoFinalDisparo = tiempoDisparo;
           }
       }
       //Si la tecla es la de arriba, aumenta velocidad
       if (tecla == KeyEvent.VK_UP) {
           nave.acelerador = true;
       }
       //Si es la de derecha, va a la derecha
       if (tecla == KeyEvent.VK_RIGHT) {
           nave.derecha = true;
       }
       //Si es la de la irquierda, va a la irquierda
       if (tecla == KeyEvent.VK_LEFT) {
           nave.irzquierda = true;
       }
       //Si se pulsa la tecla shift, la nave desaparece de donde esta y aparece en otra posición
       if (tecla == KeyEvent.VK_SHIFT) {
           mostrarNave = false;
           double h = (Math.random() * ancho) + 1;
           double v = (Math.random() * alto) + 1;
           nave.setHorizontal(h);
           nave.setVertical(v);
           mostrarNave = true;
       }
   }
   /**
    * Método que se activa cuando las teclas se sueltam
    * @param e
    */
   @Override
   public void keyReleased(KeyEvent e) {
       //Cogemos el código
       int tecla = e.getKeyCode();
       //Y desactivamos la opción de cada tecla
       if (tecla == KeyEvent.VK_SPACE) {
           nave.disparo = false;
       }
       if (tecla == KeyEvent.VK_UP) {
           nave.acelerador = false;
       }
       if (tecla == KeyEvent.VK_RIGHT) {
           nave.derecha = false;
       }
       if (tecla == KeyEvent.VK_LEFT) {
           nave.irzquierda = false;
       }
   }
   /**
    * Método para añadir más asteroides al juego según se van pasando pantallas.
    */
   public synchronized void masAsteroides() {
       //Damos el valor del numero de asteroides
       int numAsteroides = numeroAsteroides;
       //Tamaño del asteroide
       int tamaño;
       //Recorremos hasta encotrar el número de asteorides necesarios, según el nivel
       for (int cont = 0; cont < numeroAsteroides; cont ++) {
           //Escogemos posiciones aleatorias
           double asteroidHorizontal = (Math.random() * ancho) + 1;
           double asteroidVertical = (Math.random() * alto) + 1;
           //Escogemos una velocidad aleatoria de cada posición
           double velocidadHorizontal = Math.random() + 1;
           double velocidadVertical = Math.random() + 1;
           //Escogemos la dirección
           double direccionHorizontal = (Math.random() * 2);
           double direccionVertical =  (Math.random() * 2);
           //Si la dirección es igual a 1
           if (direccionHorizontal == 1) {
               //A la velocidad le damos la vuelta
               velocidadHorizontal *= (-1);
           }  
           if (direccionVertical == 1) {
               velocidadVertical *= (-1);
           }
           tamaño = 2;
           //Añadimos el nuevo asteroide con los datos obtenidos
           Asteroid ast = new Asteroid(asteroidHorizontal, asteroidVertical, 0, .1, velocidadHorizontal, velocidadVertical, tamaño);
           asteroides.add(ast);
           //Restamos el número por poner
           numAsteroides --;
           //Cogemos el centro del asteroide y la nave
           Point2D asteroidCenter = asteroides.get(cont).getCentro();
           Point2D naveCenter = nave.getCentro();
           //Calculamos la distancia
           double distancia = asteroidCenter.distance(naveCenter);
           ///Si la distancia entre el asteroide y la nave es menor de 80, no se crea
           if (distancia <= 80) {
               asteroides.remove(cont);
               cont --;
               numAsteroides ++;
           }
       }
   }
   /**
    * Método que comprueba las acciones y colisiones relacionadas con los Asteroid y el ovni.
    */
   public synchronized void compruebaAccionesColisiones() {
      accionesAsteroid ();
      accionesOvni ();
   }
   /**
    * Método que determina las acciones del asteroid en función de su movimiento y choques
    * COLISIÓN CON LA NAVE
    * COLISIÓN CON LOS DISPAROS DE LA NAVE
    * COLISIÓN CON LOS DISPAROS DEL OVNI.
    */
   public synchronized void accionesAsteroid(){
       //Recorremos los asteroides y los ponemos en movimiento
       for (int contA = 0; contA < asteroides.size(); contA ++) {
//            asteroides.get(contA).start();
//            asteroides.get(contA).mover(ancho, alto);
           try {
               //Comprueba si chocan con la nave
               if (asteroides.get(contA).colisionNave(nave)) {
                   //Los añadimos a los eliminados y explotamos
                   asteroidEliminado.add(asteroides.get(contA).explota());
                   //Los dividimos
                   divisionAsteroides(contA);
                   //si a la nave se le acaban las vidas
                   if (vidas <= 0 && !colisionNave) {
                       colisionNave = true;
                       mostrarNave = false;
                   }
                   //Si aún le quedan vidas
                   if (vidas > 0) {
                       colisionNave = true;
                       mostrarNave = false;
                       nave.setHorizontal(ancho/2);
                       nave.setVertical(alto/2);
                       nave.getRotAngulo();
                   }
                   //Restamos vida a la nave
                   vidas --;
               }
               //Comprueban si chocan con un disparo de la nave
               for (int contD = 0; contD < disparos.size(); contD ++) {
                   if (asteroides.get(contA).colisionDisparo(disparos.get(contD))) {
                       disparos.get(contD).limite = 0;
                       //Se le quita tiempo de vida
                       asteroides.get(contA).vidaAsteroide --;
                       if (asteroides.get(contA).vidaAsteroide > 0) {
                           Asteroid a = asteroides.get(contA);
                           //Según el radio del asteroid se da una puntuación o otra
                           if (a.getRadioAsteroid() >= 60) {
                               //Añadiomos los asteroides en el array
                               for (int contAE = 0; contAE < 3; contAE++) {
                                   asteroidEliminado.add(a.explota());
                               }
                               //Los dividimos el dos
                               divisionAsteroides(contA);
                               //Sumamos los puntos correspondientes
                               puntos += 20;
                           }
                           else if (a.getRadioAsteroid() >= 30) {
                               for (int contAE = 0; contAE < 3; contAE++) {
                                   asteroidEliminado.add(a.explota());
                               }
                               divisionAsteroides(contA);
                               puntos += 50;
                           }
                           else {
                               for (int contAE = 0; contAE < 3; contAE++) {
                                   asteroidEliminado.add(a.explota());
                               }
                               //Llegado a este punto, se eliminan
                               asteroides.remove(contA);
                               puntos += 100;
                           }
                       }
                       //Vamos eliminando los disparos
                       disparos.remove(contD);
                   }
               }
               //Comprueba si choca con los disparos del ovni, recorre los arraylist de ovni y el de disparos
               for (int contO = 0; contO < ovni.size(); contO ++) {
                   for (int contD = 0; contD <  ovni.get(contO).disparosOvni.size(); contD++ ) {
                       if (asteroides.get(contA).colisionDisparo(ovni.get(contO).disparosOvni.get(contD))) {
                           asteroides.get(contA).vidaAsteroide --;
                           ovni.get(contO).disparosOvni.get(contD).limite = 0;
                           if (asteroides.get(contA).vidaAsteroide > 0) {
                               Asteroid a = asteroides.get(contA);
                               asteroidEliminado.add(a.explota());
                               divisionAsteroides(contA);
                               asteroides.remove(contA);
                           }
                           if (asteroides.get(contA).vidaAsteroide <= 0) {
                               asteroides.remove(contA);
                           }
                       }
                   }
                   ovni.get(contO).disparosOvni.remove(this);
               }
           }
           catch (NullPointerException e) {}
       }
   }
   /**
    * Acciones que se realizan en función del movimiento y choques del ovni
    * COLISIÓN CON LOS DISPAROS DE LA NAVE
    * COLISIÓN CON LOS ASTEROID
    * COLISIÓN CON LA NAVE
    * COLISIÓN DE LA NAVE CON LOS DISPAROS DEL OVNI.
    */
   public synchronized void accionesOvni() {
       //Determinamos de forma aleatoria, cuando sale
       int aleatorio = (int) (Math.random() * 1000);
       if (contSalirOvni > 700) {
           //Si el número aleatorio es menor que el número de asteroides, sale
           if (aleatorio < asteroides.size()) {
               ovn = true;
           }
           //Le añadimos un ovni, si no hay ninguno
           if (ovn && ovni.size() < 1) {
               ovni.add(new Enemigo(-10, Math.random() * alto));
           }
       }
       try {
           //Recorremos y los vamos moviendo
           for (int contO = 0; contO < ovni.size(); contO ++) {
               ovni.get(contO).start();
//                ovni.get(contO).mover(ancho, alto);
               //Si el ovni se queda si vida, no sale
               if (vidaOvni == 0) {
                   ovn = false;
               }
               //Busca otro numero aleatorio, si es menor a número de asteroides, se le da vida.
               if (aleatorio < asteroides.size()) {
                   vidaOvni = 1;
               }
               //Comrpueba si le da un disparo de la nave
               for (int contD = 0; contD < disparos.size(); contD ++) {
                   if (ovni.get(contO).colisionDisparo(disparos.get(contD))) {
                       //Se le quita la vida al ovni
                       ovni.get(contO).vida --;
                       vidaOvni --;
                       disparos.get(contD).limite = 0;
                       //Y puntuación
                       puntos += 120;
                   }
               }
               //Recorremos los asteroides para comprobar si se choca con alguno
               for (int contA = 0; contA < asteroides.size(); contA ++) {
                   if (ovni.get(contO).colisionAsteroid(asteroides.get(contA))) {
                       ovni.get(contO).vida --;
                       vidaOvni --;
                       asteroidEliminado.add(asteroides.get(contA).explota());
                       divisionAsteroides(contA);
                       asteroides.remove(contA);
                   }
               }
               //Comprueba si colisiona con la nave
               if (ovni.get(contO).colisionNave(nave)) {
                   //Si la nave aún tiene vida
                   if(vidas > 0 && !colisionNave){
                       nave.setHorizontal(ancho/2);
                       nave.setVertical(alto/2);
                       colisionNave = true;
                       mostrarNave = false;
                   }
                   ovni.get(contO).vida --;
                   vidaOvni --;
                   //Si no tiene vidas
                   if (vidas <= 0) {
                       mostrarNave = false;
                       colisionNave = true;
                   }
                   vidas --;
               }
               //Comprueba si la nave es colisionada con un disparo del ovni
               if (nave.colisionDisparo(ovni.get(contO).disparosOvni) && !colisionNave) { //pregunta si lan ave colisiona con los disparos del ovni
                   //Si la nave no tiene vidas
                   if (nave.vida <= 0) {
                       mostrarNave = false;
                       colisionNave = true;
                   }
                   //Si le quedan
                   if (nave.vida > 0) {
                       mostrarNave = false;
                       nave.setHorizontal(ancho/2);
                       nave.setVertical(alto/2);
                       nave.getRotAngulo();
                       colisionNave = true;
                   }
                   vidas --;
               }
               ovni.get(contO).disparosOvni.remove(this);
           }
       }
       catch (Exception e) {}
       //Recorremos el array list y si no tiene vidas ni el ovni o la nave, se eliminan.
       for (int cont = 0; cont < ovni.size(); cont ++) {
           if (ovni.get(cont).vida <= 0 || nave.vida <= 0) {
               ovni.remove(cont);
           }
       }
   }
   /**
    * Método de la division de los asteroides.
    * @param num
    */
   public synchronized void divisionAsteroides (int num) {
       //Seleccionamos el asteroide que se ha disparado
       Asteroid a = asteroides.get(num);
       //Cogemos las posiciones
       double asteroideHorizontal = a.getHorizontal();
       double asteroideVertical = a.getVertical();
       //Y dividimos el tamaño original en dos
       int tamaño = (a.getTamaño() / 2);
       //Recorremos los dos asteorides nuevos para determinar velocidad y dirección
       for (int cont = 0; cont < 2; cont++) {
           double velocidadHorizontal = Math.random() + 1;
           double velocidadVertical = Math.random() + 1;
           double direccionHorizontal = (Math.random() * 2);
           double direccionVertical =  (Math.random() * 2);
           //Si la dirección es igual 1, giramos la velocidad
           if (direccionHorizontal == 1) {
               velocidadHorizontal *= (-1);
           }
           if (direccionVertical == 1) {
               velocidadVertical *= (-1);
           }
           //Añadimos los nuevos asteroides
           asteroides.add(new Asteroid(asteroideHorizontal, asteroideVertical, 0, .1, velocidadHorizontal, velocidadVertical, tamaño));
       }
       //Eliminamos el asteoride del array
       asteroides.remove(num);
   }
   /**
    * Método de inicio - FALLAN LOS THREAD.
    */
   public void start () {
       if (arranque == null) {
           arranque = new Thread(this);
           arranque.start();
       }
       while (true) {
           for (int contO = 0; contO < asteroides.size(); contO ++) {
               asteroides.get(contO).start();
               
           }
           for (int contO = 0; contO < disparos.size(); contO ++) {
               disparos.get(contO).start();
           }
       }
   }
   /**
    * Método de arranque.
    */
   @Override
   public void run() {
       //Esperamos tres segundos antes de mostrar los elementos
       try {
           arranque.sleep(3000);
       }
       catch (InterruptedException ex) { }
       //Mientras sea cierto
       while (true) {
           //Mostramos la nave
           mostrarNave = true;
           //Ponemos los asteroides
           masAsteroides();
           //Mientras las vidas sean mayores que cero
           while (vidas >= 0) {
               //Iniciamos un contador de tiempo
               inicio = System.currentTimeMillis();
               //Damos movimiento a nave, asteroides y disparos
               nave.mover(ancho, alto);
               for (int cont = 0; cont < asteroidEliminado.size(); cont ++) {
                   asteroidEliminado.get(cont).moverExplosion();
                   if (asteroidEliminado.get(cont).getVidaAsteroide() <= 0) {
                       asteroidEliminado.remove(cont);
                   }
               }
               for (int cont = 0; cont < disparos.size(); cont++) {
                   disparos.get(cont).mover(ancho, alto);
                   if (!disparos.get(cont).getActivado()) {
                       disparos.remove(cont);
                   }
               }
               //Restamos tiempo de disparo
               tiempoFinalDisparo --;
               //Comprobamos las colisones
               compruebaAccionesColisiones();
               //Repintamos
               repaint();
               //Si terminamos los asteroides y con el ovni aumentamos los asteroides.
               if (asteroides.isEmpty() && !ovn) {
                   //Aumentamos el número de asteroides
                   numeroAsteroides ++;
                   //Añadimos asteroides
                   masAsteroides();
                   //Damos true a que puede salir
                   ovn = true;
                   contSalirOvni = 0;
               }
               //Hacer
               try {
                   //Asignamos un nuevo contador de tiempo al final
                   fin = System.currentTimeMillis();
                   //Si la diferencia de refrescar entre la diferencia de fin e inicio es mayor a 0
                   if (refrescar - (fin - inicio) > 0) {
                       //Tiempo de espera es refrescar menos la diferencia
                       Thread.sleep(refrescar - (fin - inicio));
                   }
               }
               catch (InterruptedException e) {}
               contSalirOvni ++;
           }
           stop();
       }
   }
   /**
    * Método de finalización del juego.
    */
   public void stop () {
       if (arranque != null) {
           arranque = null;
           System.exit(0);  
       }
   }
}


Primera parte del código.

S_Code

#1
Segundo mensaje, que en el primero no entraba todo el código.

Clase Asteroid - Dibuja y mueve los asteroid, además de método para comprobar coliones.

Código (java) [Seleccionar]

package asteroides;

//Importamos bibliotecas necesarias
import java.awt.*;
import java.awt.geom.Point2D;

/**
* Clase Asteroid - FALLA THREAD
*/

public class Asteroid extends Thread {
   EspacioCanvas j1;
   //Tamaño del asteroide
   int tamaño;
   //Posiciones de asteroide
   double horizontal;
   double vertical;
   //Rotación de asteroide
   double angulo;
   double rotAngulo;
   //Direcciones del asteroide (velocidad)
   double dirHorizontal;
   double dirVertical;
   //Saber si esta activado
   boolean activado;
   //Poligono del asteroid con las posiciones
   Polygon asteroid;
   //Posiciones iniciales de los puntos del asteroide
   double [] posicionInicialHorizontal;
   double [] posicionInicialVertical;
   //Posiciones del asteroide explotado
   final double posicionHorizontalExplosion[] = {-2, 2};
   final double posicionVerticalExplosion[] = {-2, 2};
   //Radio del asteroide
   double radioAsteroid = 30;
   //Vida (la explosión)
   double vidaAsteroide;
   //Array para colocar los puntos de los movimientos
   int [] horizontalPts;
   int [] verticalPts;
   int [] horizontalExplosion;
   int [] verticalExplosion;
   /**
    * Constructor del asteroid
    * @param horizontal
    * @param vertical
    * @param angulo
    * @param rotAngulo
    * @param dirHorizontal
    * @param dirVertical
    * @param tamaño
    */
   public Asteroid(double horizontal, double vertical, double angulo, double rotAngulo, double dirHorizontal, double dirVertical, int tamaño) {
       this.horizontal = horizontal;
       this.vertical = vertical;
       this.angulo = angulo;
       this.rotAngulo = rotAngulo;
       this.dirHorizontal = dirHorizontal;
       this.dirVertical = dirVertical;
       this.tamaño = tamaño;
       activado = true;
       vidaAsteroide = 70;
       j1 = new EspacioCanvas ();
       //Determinamos el tipo de asteroide;
       int numTipo = ((int) (Math.random() * 4) + 1);
       tipoAsteroid(numTipo);
       /**
        * Le damos tres tamaños al asteroide, según estos, tendran un radio, una velocidad y una rotación diferente.
        */
       if (tamaño == 2) {
           for (int cont = 0; cont < posicionInicialHorizontal.length; cont ++) {
               posicionInicialHorizontal[cont] *= 2;
               posicionInicialVertical[cont] *= 2;
           }
           radioAsteroid *= 2;
           this.dirHorizontal /= 2.5;
           this.dirVertical /= 2.5;
           this.rotAngulo /= 2.5;
       }
       else if (tamaño == 1) {
           for (int cont = 0; cont < posicionInicialHorizontal.length; cont ++) {
               posicionInicialHorizontal[cont] *= 1;
               posicionInicialVertical[cont] *= 1;
           }
           radioAsteroid *= 1;
           this.dirHorizontal /= 2;
           this.dirVertical /= 2;
           this.rotAngulo /= 2;
       }
       else if (tamaño < 1) {
           for (int cont = 0; cont < posicionInicialHorizontal.length; cont ++) {
               posicionInicialHorizontal[cont] /= 2;
               posicionInicialVertical[cont] /= 2;
           }
           radioAsteroid /= 2;
           this.dirHorizontal /= 1.5;
           this.dirVertical /= 1.5;
           this.rotAngulo /= 1.5;
       }
       //Creamos las longitudes en los array simples creados para ello
       horizontalPts = new int[posicionInicialHorizontal.length];
       verticalPts = new int[posicionInicialVertical.length];
       horizontalExplosion = new int[posicionHorizontalExplosion.length];
       verticalExplosion = new int[posicionVerticalExplosion.length];
   }
   //Gets y Sets de la clase Asteroide
   public void setActivado(boolean activado) {
       this.activado = activado;
   }
   public Point2D getCentro() {
       return new Point2D.Double(horizontal, vertical);
   }
   public double getRadioAsteroid() {
       return radioAsteroid;
   }
   public int getTamaño() {
       return tamaño;
   }
   public double getHorizontal() {
       return horizontal;
   }
   public double getVertical() {
       return vertical;
   }
   public double getVidaAsteroide() {
       return vidaAsteroide;
   }
   /**
    * Método que determina el tipo de asteroid
    * @param tipo
    */
   public void  tipoAsteroid (int tipo){
       //Posiciones de los diferentes tipos de asteroid
       double [] tipo1Horizontal = {-16, -8, 0, 8, 16, 12, 16, 4, -8, -16, -16};
       double [] tipo1Vertical = {-8, -16, -8, -16, -8, 0, 8, 16, 16, 8, -8};
       double [] tipo2Horizontal = {-12, -16, -8, 0, 8, 16, 8, 16, 8, -4, -8, -16, -12};
       double [] tipo2Vertical = {0, -8, -16, -12, -16, -8, -4, 4, 16, 12, 16, 8, 0};
       double [] tipo3Horizontal = {-8, -16, -4, 8, 16, 16, 8, 0, 0, -8, -16, -8};
       double [] tipo3Vertical = {0, -4, -16, -16, -4, 4, 16, 16, 4, 16, 4, 0};
       double [] tipo4Horizontal = {-4, -8, 4, 16, 16, 4, 16, 8, 4, -8, -16, -16, -4};
       double [] tipo4Vertical = {-8, -16, -16, -8, -4, 0, 8, 16, 12, 16, 4, -8, -8};
       //Según el tipo aleatorio que haya salido, le damos unos valores u otros.      
       if (tipo == 1) {
           posicionInicialHorizontal = tipo1Horizontal;
           posicionInicialVertical = tipo1Vertical;
       }
       else if (tipo == 2) {
           posicionInicialHorizontal = tipo2Horizontal;
           posicionInicialVertical = tipo2Vertical;
       }
       else if (tipo == 3) {
           posicionInicialHorizontal = tipo3Horizontal;
           posicionInicialVertical = tipo3Vertical;
       }
       else if (tipo == 4) {
           posicionInicialHorizontal = tipo4Horizontal;
           posicionInicialVertical = tipo4Vertical;
       }
   }      
   /**
    * Método de dibujar asteroide normal
    * @param g
    */
   public void pintar (Graphics2D g) {
       if (activado) {
           for (int cont = 0; cont < horizontalPts.length; cont ++) {
               horizontalPts[cont] = (int) (posicionInicialHorizontal[cont] * Math.cos(angulo) - posicionInicialVertical[cont] * Math.sin(angulo) + horizontal + 0.5);
               verticalPts[cont] = (int) (posicionInicialHorizontal[cont] * Math.sin(angulo) + posicionInicialVertical[cont] * Math.cos(angulo) + vertical + 0.5);
           }
           g.setColor(Color.WHITE);
           asteroid = new Polygon(this.horizontalPts,this.verticalPts, this.horizontalPts.length);
           g.drawPolygon(asteroid);
       }
   }
   /**
    * Método de dibujar la explosión
    * @param g
    */
   public void pintarExplosion (Graphics g) {
       for (int cont = 0; cont < horizontalExplosion.length; cont ++) {
           horizontalExplosion[cont] = (int) (posicionHorizontalExplosion[cont] * Math.cos(angulo) - posicionVerticalExplosion[cont] * Math.sin(angulo) + horizontal + 0.5);
           verticalExplosion[cont] = (int) (posicionHorizontalExplosion[cont] * Math.sin(angulo) + posicionVerticalExplosion[cont] * Math.cos(angulo) + vertical + 0.5);
       }
       g.setColor(Color.WHITE);
       g.drawPolygon(horizontalExplosion, verticalExplosion, horizontalExplosion.length);
   }
   /**
    * Método de mover el asteroide.
    * @param tamañoAncho
    * @param tamañoAlto
    */
   public synchronized void mover (double tamañoAncho, double tamañoAlto) {
       if (activado) {
           angulo += rotAngulo;
           horizontal += dirHorizontal;
           vertical += dirVertical;
       }
       if (horizontal < (0 - (radioAsteroid))) {
           horizontal += tamañoAncho + (radioAsteroid);
       }
       else if (horizontal > (tamañoAncho + (radioAsteroid))) {
           horizontal -= tamañoAncho + (radioAsteroid);
       }
       if (vertical < (0 - (radioAsteroid))) {
           vertical += tamañoAlto + (radioAsteroid);
       }
       else if (vertical > (tamañoAlto + (radioAsteroid))) {
          vertical -= tamañoAlto + (radioAsteroid);
       }
   }
   /**
    * Método de movimiento del asteroide explotado.
    */
   public synchronized void moverExplosion () {
       angulo += rotAngulo;
       horizontal += dirHorizontal;
       vertical += dirVertical;
       vidaAsteroide --;
   }
   /**
    * Método de la explosión del asteroid
    * @return
    */
   public synchronized Asteroid explota() {
       double horizontalVel = Math.random();
       double verticalVel = Math.random();
       double horizontalDir =  (Math.random() * 2);
       double verticalDir = (Math.random() * 2);
       if (horizontalDir == 1) {
           horizontalVel *= -1;
       }
       if (verticalDir == 1) {
           verticalVel *= -1;
       }
       return new Asteroid (horizontal, vertical, 0, .1, horizontalVel, verticalVel, 0);
   }
   /**
    * Método que comprueba si al asteroide le ha dado un disparo
    * @param disparo
    * @return
    */
     public synchronized boolean colisionDisparo (Disparo disparo){
       if (asteroid.contains(disparo.horizontal, disparo.vertical));
       return asteroid.contains(disparo.horizontal, disparo.vertical);
   }
   /**
    * Método que comprueba si una asteroide choca con una nave
    * @param jugador
    * @return
    */
   public synchronized boolean colisionNave (Nave jugador){
       if (asteroid.intersects(jugador.nave.getBounds2D()));
       return asteroid.intersects(jugador.nave.getBounds2D());
   }
   /** Método del Thread del asteroide
    * NO FUNCIONA: SI SE PONE AQUÍ EL MOVIMIENTO, EN EL MÉTODO DE ACCIONES ASTEROID DE ESPACIOCANVAS NO DEBE IR.
    */
   @Override
   public void run () {
        while (true) {    
           try {
               mover (j1.ancho, j1.alto);
               moverExplosion ();
               Thread.sleep(40);
               j1.repaint();
           }
           catch (InterruptedException ex) { }
       }
   }
}


Clase Enemigo - Ovni: Movimiento y dibujo. Incorpora sus dibujos

Código (java) [Seleccionar]

package asteroides;

//Importar librerias necesarias
import java.awt.*;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Random;

/**
* Clase Nave - Enemigo - FALLA EL THREAD
* EL MOVIMIENTO DEL THREAD FUNCIONA, PERO NO DETECTA LAS COLISONES
*/

public class Enemigo extends Thread {
   EspacioCanvas j1;
   //Vidas del ovni
   int vida;
   //Posición del ovni
   double horizontal;
   double vertical;
   //Angulo del platilla
   double angulo;
   //Poligono del ovni
   Polygon ovni;
   //Eje del ovni
   final double eje = -3.1588;
   //Direcciones del ovni
   double dirHorizontal;
   double dirVertical;
   //Variables para el disparo
   int contador;
   int tiempoDisparo;
   //Posiciones del ovni
   double [] posicionInicialHorizontal;
   double [] posicionInicialVertical;
   int [] puntosHorizontal;
   int [] puntosVertical;
   //ArrayList de los disparos del ovni
   ArrayList <Disparo> disparosOvni;
   /**
    * Constructor del ovni
    * @param horizontal
    * @param vertical
    */
   public Enemigo(double horizontal, double vertical) {
       this.horizontal = horizontal;
       this.vertical = vertical;
       this.angulo = eje;
       contador = 0;
       vida = 1;
       //Determinamos el tipo de asteroide;
       int numTipo = ((int) (Math.random() * 2) + 1);
       tipoEnemigo (numTipo);
       //Creamos los array
       puntosHorizontal = new int[posicionInicialHorizontal.length];
       puntosVertical = new int[posicionInicialVertical.length];
       disparosOvni = new ArrayList <Disparo>();
       j1 = new EspacioCanvas ();
   }
   //GETS Y SETS
   public Disparo disparo (Enemigo ovni) {
       return new Disparo (ovni);
   }
   public Point2D getCentro() {
       return new Point2D.Double(horizontal, vertical);
   }
   public int getVida() {
       return vida;
   }
   public double getHorizontal() {
       return horizontal;
   }
   public double getVertical() {
       return vertical;
   }
   public void setHorizontal(double horizontal) {
       this.horizontal = horizontal;
   }
   public void setVertical (double vertical) {
       this.vertical = vertical;
   }
   
   public void tipoEnemigo (int enemigo) {
       double [] posicionInicialHorizontal1 = {8, 12, -12, 14, 20, -20, 20, 14, -14, -20, -14, -12, -8};
       double [] posicionInicialVertical1 = {12, 6, 6, 6, 0, 0, 0, -6, -6, 0, 6, 6, 12};
       double [] posicionInicialHorizontalPeque = {4, 6, -6, 7, 10, 10, 10, 7, -7, -10, -7, -6, -4};
       double [] posicionInicialVerticalPeque = {6, 3, 3, 3, 0, 0, 0, -3, -3, 0, 3, 3, 6};
       if (enemigo == 1) {
           posicionInicialHorizontal = posicionInicialHorizontal1;
           posicionInicialVertical = posicionInicialVertical1;
       }
       else if (enemigo == 2) {
           posicionInicialHorizontal = posicionInicialHorizontalPeque;
           posicionInicialVertical = posicionInicialVerticalPeque;
       }
   }
   /**
    * Método de dibujar el ovni
    * @param g
    */
   public void pintar(Graphics2D g) {
       //Para la figura del ovni
       for (int cont = 0; cont < puntosHorizontal.length; cont ++) {
           //Calculamos las posiciones de la posicion
           puntosHorizontal[cont] = (int) (posicionInicialHorizontal[cont] * Math.cos(angulo) - posicionInicialVertical[cont] * Math.sin(angulo) + horizontal + 0.5);
           puntosVertical[cont] = (int) (posicionInicialHorizontal[cont] * Math.sin(angulo) + posicionInicialVertical[cont] * Math.cos(angulo) + vertical + 0.5);
       }
       //Para dibujar los disparos del ovni
       ovni = new Polygon (this.puntosHorizontal, this.puntosVertical, this.puntosHorizontal.length);
       for (int cont = 0; cont < disparosOvni.size(); cont ++) {
           disparosOvni.get(cont).pintar(g);
       }
       //Color del ovni
       g.setColor(Color.WHITE);
       g.drawPolygon(ovni);
   }
   /**
    * Método de mover el ovni
    * @param tamañoAncho
    * @param tamañoAlto
    */
   public synchronized void mover(double tamañoAncho, double tamañoAlto) {
       //Movimientos aleatorios del platillo
       Random r = new Random();
       if (contador == 0 || contador %150 == 0) {
           dirHorizontal = Math.random()*3*((r.nextInt(2)==0?-1:1)*1);
           dirVertical = Math.random()*3*((r.nextInt(2)==0?-1:1)*1);
       }
       //Le añadimos las direcciones
       horizontal += dirHorizontal;
       vertical += dirVertical;
       //Si llega a los bordes, vuelve por el otro extremo
       if (horizontal < 0) {
           horizontal += tamañoAncho;
       }
       if (horizontal > tamañoAncho) {
           horizontal -= tamañoAncho;
       }
       if (vertical < 0) {
           vertical += tamañoAlto;
       }
       if (vertical > tamañoAlto) {
           vertical -= tamañoAlto;
       }
       contador ++;
       //Añadimos los disparos, según el calculos a los valores del contador
       if (this.tiempoDisparo == 0 || this.tiempoDisparo %45 == 0) {
               this.disparosOvni.add(disparo(this));
       }
       this.tiempoDisparo ++;
       //Vamos moviendo los disparos
       for (int cont = 0; cont < disparosOvni.size(); cont ++) {
           disparosOvni.get(cont).mover(tamañoAncho, tamañoAlto);
           //Comprobamos si han llegado a su limite
           if (disparosOvni.get(cont).limite <= 0) {
               disparosOvni.remove(cont);
           }
       }
   }
   /**
    * Método que comprueba si choca con un asteroide
    * @param asteroide
    * @return
    */
   public synchronized boolean colisionAsteroid (Asteroid asteroide){
       if(ovni.intersects(asteroide.asteroid.getBounds()));
       return ovni.intersects(asteroide.asteroid.getBounds());
   }
   /**
    * Método que comprueba si choca con la nave
    * @param nave
    * @return
    */
   public synchronized boolean colisionNave (Nave nave){
       if (ovni.intersects(nave.nave.getBounds2D()));
       return ovni.intersects(nave.nave.getBounds2D());
   }
   /**
    * Método que comprobar si le da ha dado un disparo.
    * @param disparo
    * @return
    */
   public synchronized boolean colisionDisparo (Disparo disparo){
       if (ovni.contains(disparo.horizontal, disparo.vertical));
       return ovni.contains(disparo.horizontal, disparo.vertical);
   }
   /** Método del Thread del ovni
    * NO FUNCIONA: SI SE PONE AQUÍ EL MOVIMIENTO, EN EL MÉTODO DE ACCIONES DE ESPACIO CANVAS NO DEBE IR.
   */
   @Override
   public void run () {
       while (true) {      
           try {
               mover (j1.ancho, j1.alto);
               Thread.sleep (60);
               j1.repaint();
           }
           catch (InterruptedException ex) { }
       }
   }
}


Clase Disparo - Movimiento y pintar. Relacionado con la nave y el ovni

Código (java) [Seleccionar]

package asteroides;

//Importamos bibliotecas necesarias
import java.awt.*;
import java.awt.geom.Point2D;

/** CLASE DISPARO - Lo usa la nave y el enemigo - FALLA EL THREAD
*/

public class Disparo extends Thread {
   EspacioCanvas j1;
   //Velocidad del disparo
   final double velocidadDisparo = 12;
   //Posiciones y angulo del disparo
   double horizontal;
   double vertical;
   double angulo;
   //Direcciones del disparo
   double dirHorizontal;
   double dirVertical;
   //Limite del disparo
   int limite;
   //Boolean para ver si se ha activado el disparo
   boolean activado;
   //Radio del disparo
   double radioDisparo = 0.5;
//    int [] puntosHorizontal, puntosVertical;
   /**
    * Constructor del disparo de la Nave
    * @param horizontal
    * @param vertical
    * @param angulo
    * @param velEnvioH
    * @param velEnvioV
    * @param limite
    */
   public Disparo(double horizontal, double vertical, double angulo, double velEnvioH, double velEnvioV, int limite) {
       this.horizontal = horizontal;
       this.vertical = vertical;
       this.angulo = angulo;
       dirHorizontal = velocidadDisparo * Math.cos(angulo) + velEnvioH;
       dirVertical = velocidadDisparo * Math.sin(angulo) + velEnvioV;
       this.limite = 35;
       activado = true;
       j1 = new EspacioCanvas ();
   }
   /**
    * Constructor disparo para Ovni
    * @param ovni
    */
   public Disparo (Enemigo ovni){
       this.limite = 60;
       this.angulo = ovni.angulo;
       this.horizontal = ovni.horizontal;
       this.vertical = ovni.vertical;
       this.dirHorizontal = ovni.dirHorizontal;
       this.dirVertical = ovni.dirVertical;
   }
   //Gets del disparo
   public boolean getActivado() {
       return activado;
   }
   public Point2D getCentro() {
       return new Point2D.Double(horizontal, vertical);
   }
   public double getRadioDisparo() {
       return radioDisparo;
   }
   /**
    * Método de dibujar el disparo cuando se activa
    * @param g
    */
   public void pintar(Graphics2D g){
//        Graphics2D g = g0;
       g.setColor(Color.WHITE);
       g.fillOval((int)horizontal, (int)vertical, 3, 3);
   }  
   /**
    * Método de movimiento del disparo una vez activado
    * @param tamañoAncho
    * @param tamañoAlto
    */
   public synchronized void mover (double tamañoAncho, double tamañoAlto) {
       //Si se ha activado el disparo
       if (activado) {
           //A horizontal y vertical le sumamos la dirección
           horizontal += dirHorizontal;
           vertical += dirVertical;
       }
       //Si el disparo supera los limites de los lados, vuelve por el otro extremo
       if (horizontal < 0) {                    
           horizontal += tamañoAncho;
       }
       else if (horizontal > tamañoAncho) {
           horizontal -= tamañoAncho;
       }
       if (vertical < 0) {
           vertical += tamañoAlto;
       }
       else if (vertical > tamañoAlto) {
           vertical -= tamañoAlto;
       }
       //Se resta tiempo
       limite --;
       //Si no queda tiempo, el disparo se desactiva
       if (limite == 0) {
           activado = false;
       }
   }
   /** Método del Thread del disparo
    * NO FUNCIONA: SI SE PONE AQUÍ EL MOVIMIENTO, EN EL RUN DE ESPACIOCANVAS NO DEBE IR.
    */
   @Override
   public void run () {
       while (true) {      
           try {
               mover (j1.ancho, j1.alto);
               Thread.sleep (10);
               j1.repaint();
           }
           catch (InterruptedException ex) { }
       }
   }
}


Clase Nave: Movimiento y dibujo, el KeyListener esta en el Espacio Canvas

Código (java) [Seleccionar]

package asteroides;

//Importar librerias necesarias
import java.awt.*;
import java.awt.geom.Point2D;
import java.util.ArrayList;

/**
* Clase Nave - Jugador
*/
public class Nave  {
   EspacioCanvas j1;
   //Poligono de la nave
   Polygon nave;
   //Atributos del movimiento de la nave
   double aceleracion;
   double arrastre;
   //Radio de la nave
   double radio = 12;
   //Posición de la nave
   double horizontal;
   double vertical;
   //Rotación de la nave
   double angulo;
   double rotAngulo;
   //Direcciones de la nave
   double dirHorizontal;
   double dirVertical;
   //Booleans del movimiento y disparo
   boolean acelerador;
   boolean irzquierda;
   boolean derecha;
   boolean disparo;
   //Posiciones de la nave
   final int [] posicionInicialHorizontal = {-12, 12, -12, -5, -5};
   final int [] posicionInicialVertical = {8, 0, -8, -5, 5};
   //Posiciones del acelerador
   final double [] posicionEmpujeInicialHorizontal = {-4, - 12, - 4};
   final double [] posicionEmpujeInicialVertical = {-3, 0 , 3};
   int vida;
   int [] puntosHorizontal;
   int [] puntosVertical;
   int [] inicioEmpujeHorizontal;
   int [] inicioEmpujeVertical;
   /**
    * Constructor de la nave
    * @param horizontal
    * @param vertical
    * @param angulo
    * @param rotAngulo
    * @param aceleracion
    * @param arrastre
    */
   public Nave(double horizontal, double vertical, double angulo, double rotAngulo, double aceleracion, double arrastre) {
       this.horizontal = horizontal;
       this.vertical = vertical;
       this.angulo = angulo;
       this.rotAngulo = rotAngulo;
       this.aceleracion = aceleracion;;
       this.arrastre = arrastre;
       acelerador = false;
       irzquierda = false;
       derecha = false;
       vida = 3;
       //Creamos los array
       puntosHorizontal = new int[posicionInicialHorizontal.length];
       puntosVertical = new int[posicionInicialVertical.length];
       inicioEmpujeHorizontal = new int[posicionEmpujeInicialHorizontal.length];
       inicioEmpujeVertical = new int[posicionEmpujeInicialVertical.length];
   }
   //GETS Y SETS
   public Disparo disparo () {
       return new Disparo (horizontal, vertical, angulo, dirHorizontal, dirVertical, 50);
   }
   public void setAcelerador(boolean acelerador) {
       this.acelerador = acelerador;
   }
   public void setIrzquierda(boolean irzquierda) {
       this.irzquierda = irzquierda;
   }
   public void setDerecha(boolean derecha) {
       this.derecha = derecha;
   }
   public Point2D getCentro() {
       return new Point2D.Double(horizontal, vertical);
   }
   public double getRadio() {
       return radio;
   }
   public double getRotAngulo () {
       return rotAngulo;
   }
   public double getHorizontal() {
       return horizontal;
   }
   public double getVertical() {
       return vertical;
   }
   public void setHorizontal(double horizontal) {
       this.horizontal = horizontal;
   }
   public void setVertical (double vertical) {
       this.vertical = vertical;
   }
   /**
    * Método de dibujar la nave.
    * @param g
    */
   public void pintar(Graphics2D g) {
       //Si esta pulsado el acelerador
       if (acelerador) {
           //Recorremos para calcular los delanteros
           for (int cont = 0; cont < inicioEmpujeHorizontal.length; cont ++) {
               //Calculamos el movimiento                
               inicioEmpujeHorizontal[cont] = (int) (posicionEmpujeInicialHorizontal[cont] * Math.cos(angulo) - posicionEmpujeInicialVertical[cont] * Math.sin(angulo) + horizontal + 0.5);
               inicioEmpujeVertical[cont] = (int) (posicionEmpujeInicialHorizontal[cont] * Math.sin(angulo) + posicionEmpujeInicialVertical[cont] * Math.cos(angulo) + vertical + 0.5);
           }
           //Color de la nave
           g.setColor(Color.WHITE);
           //Señalamos los puntos del acelerador
           g.drawPolyline(inicioEmpujeHorizontal, inicioEmpujeVertical, inicioEmpujeHorizontal.length);
       }
       //Para el movimiento de la nave, recorremos
       for (int cont = 0; cont < puntosHorizontal.length; cont ++) {
           //Calculamos las posiciones de la posicion
           puntosHorizontal[cont] = (int) (posicionInicialHorizontal[cont] * Math.cos(angulo) - posicionInicialVertical[cont] * Math.sin(angulo) + horizontal + 0.5);
           puntosVertical[cont] = (int) (posicionInicialHorizontal[cont] * Math.sin(angulo) + posicionInicialVertical[cont] * Math.cos(angulo) + vertical + 0.5);
       }
       //Color de la nave
       g.setColor(Color.WHITE);
       nave = new Polygon (puntosHorizontal, puntosVertical, puntosHorizontal.length);
       //Señalamos los puntos de la nave
       g.drawPolygon(nave);
   }
   /**
    * Método de mover la nave
    * @param tamañoAncho
    * @param tamañoAlto
    */
   public synchronized void mover(double tamañoAncho, double tamañoAlto) {
       //Comprobamos hacia donde va la nave, ségun la tecla pulsada
       
       if (irzquierda) {
           angulo -= rotAngulo;
       }
       if (acelerador) {
           dirHorizontal += aceleracion * Math.cos(angulo);
           dirVertical += aceleracion * Math.sin(angulo);
       }
       if (derecha) {
           angulo += rotAngulo;
       }
       //Le añadimos las direcciones
       horizontal += dirHorizontal;
       vertical += dirVertical;
       //Múltiplamos el arrastre a la dirección
       dirHorizontal *= arrastre;
       dirVertical *= arrastre;
       //Si llega a los bordes, vuelve por el otro extremo
       if (horizontal < 0) {
           horizontal += tamañoAncho;
       }
       else if (horizontal > tamañoAncho) {
           horizontal -= tamañoAncho;
       }
       if (vertical < 0) {
           vertical += tamañoAlto;
       }
       else if (vertical > tamañoAlto) {
           vertical -= tamañoAlto;
       }
   }
   /**
    * Método que comprueba si le da un disparo suyo o no
    * @param disparos
    * @return
    */
   public synchronized boolean colisionDisparo (ArrayList <Disparo> disparos){
       for (int cont = 0; cont < j1.disparos.size(); cont ++) {
           if (nave.contains(j1.disparos.get(cont).horizontal, j1.disparos.get(cont).vertical)){
               return true;
           }
       }
       return false;
   }
}


Gracias de antemano por vuestro tiempo.