import java.awt.*; import sun.awt.image.URLImageSource; import java.applet.Applet; class Objeto { // Atributos //static int width, height; static int width, height; int incrementoX, incrementoY, cantidad; double actualX, actualY; boolean VerificarDesborde, activo; // Verifica que no se sobrepase del Applet Image ImagenFuente[]; public Objeto() { this.actualX = 0.0; this.actualY = 0.0; this.VerificarDesborde = false; this.incrementoX = 0; this.incrementoY = 0; } public void avanzar() { if (this.VerificarDesborde) { // El objeto aparece del lado opuesto if (this.actualX > width) this.actualX = 0; if (this.actualX < 0) this.actualX = width; if (this.actualY > height) this.actualY = 0; if (this.actualY < 0) this.actualY = height; } else { // El objeto se mantiene en el borde if (this.actualX < 0) this.actualX = 0; if (this.actualX > width-24) this.actualX = width-24; if (this.actualY < 0) this.actualY = 0; if (this.actualY > height-23) this.actualY = height-23; } } } public class Imagen7 extends Applet implements Runnable { // Variables de control de thread´s Thread ProcesoCarga; Thread ProcesoBucle; // Constantes static final int RETRASO = 50; static final int MAX_ESTRELLAS = 50; static final int MAX_ENEMIGOS = 10; static final int MAX_IMAGENES = 10; static final int MAX_DISPAROS = 1000; int incremento_tecla = 0; boolean semaforo; // Define los objetos enemigos Objeto[] enemigo = new Objeto[MAX_ENEMIGOS]; // Defino el objeto principal nave Objeto nave = new Objeto(); // Defino el objeto disparo Objeto[] disparos = new Objeto[MAX_DISPAROS]; int[] contadorDisparos = new int[MAX_DISPAROS]; // Contador de tiempo para vida de un disparo int indiceDisparos; // Indice al siguiente disparo // Banderas (flags) de tecla boolean izquierda = false; boolean derecha = false; boolean arriba = false; boolean abajo = false; boolean cargado = false; boolean pausado; boolean jugando = false; // Valores de la imagen "offscreen" Dimension d; Graphics gContext; Image buffer; MediaTracker imageTracker; // used to track images // Estrellas de fondo Point[] estrellas; Point[] TamEstrellas; // Datos sobre font tipográfica Font font = new Font("Arial", Font.BOLD, 12); FontMetrics fm; int fontWidth; int fontHeight; public void init() { d = size(); pausado = false; jugando = false; int auxiliar = 0; for (int i = 0; i < MAX_ENEMIGOS; i++) { enemigo[i] = new Objeto(); enemigo[i].width = d.width; enemigo[i].height = d.height; enemigo[i].ImagenFuente = new Image[ MAX_IMAGENES ]; imageTracker = new MediaTracker( this ); for ( int j = 0; j < enemigo[i].ImagenFuente.length; j++ ) { enemigo[i].ImagenFuente[j] = getImage( getDocumentBase(), "enemigo.gif" ); // track loading image imageTracker.addImage( enemigo[i].ImagenFuente[j], j ); } enemigo[i].actualX = ( (int) aleatorio(d.width) ); enemigo[i].actualY = 0.0; enemigo[i].VerificarDesborde = true; auxiliar = ( (int) aleatorio( 15 ) ); // Verifica que las naves enemigas vayan mas rapido que las estrellas; if ( auxiliar < 2 ) enemigo[i].incrementoY = 2; else enemigo[i].incrementoY = auxiliar; } buffer = createImage( d.width, d.height ); // create image buffer gContext = buffer.getGraphics(); // get graphics context gContext.setColor( Color.black ); gContext.fillRect( 0, 0, d.width, d.height ); InicializarFuente( gContext ); GenerarEstrellas(); InicializarNave(); InicializarDisparos(); try { imageTracker.waitForID( 0 ); } catch( InterruptedException e ) { showStatus( e.toString() ); } } public void start() { for (int i = 0; i < MAX_ENEMIGOS; i++) gContext.drawImage( enemigo[i].ImagenFuente[0], (int) enemigo[i].actualX, (int) enemigo[i].actualY++, this ); if (ProcesoBucle == null) { ProcesoBucle = new Thread(this); ProcesoBucle.start(); } if (!cargado && ProcesoCarga == null) { ProcesoCarga = new Thread(this); ProcesoCarga.start(); } } public void stop() { if (ProcesoBucle != null) { ProcesoBucle.stop(); ProcesoBucle = null; } if (ProcesoCarga != null) { ProcesoCarga.stop(); ProcesoCarga = null; } } public void run() { long startTime; // Baja la prioridad de este proceso al mínimo y toma la hora actual Thread.currentThread().setPriority(Thread.MIN_PRIORITY); startTime = System.currentTimeMillis(); // Este es el bucle principal while (Thread.currentThread() == ProcesoBucle) { if (!pausado) { if (!jugando) MostrarCreditos( gContext ); ActualizarNave(); ActualizarDisparos(); gContext.setColor(Color.black); gContext.fillRect( 0, 0, d.width, d.height ); // draw new image in buffer gContext.setColor(Color.white); for (int i = 0; i < MAX_ESTRELLAS; i++) { estrellas[i].y++; if (estrellas[i].y > d.height) estrellas[i].y = 0; if (estrellas[i].y < 0) estrellas[i].y = d.height; gContext.fillOval( estrellas[i].x, estrellas[i].y, TamEstrellas[i].x, TamEstrellas[i].y ); } //gContext.drawString ("Tecla: " + semaforo, 200, 200); gContext.setColor(Color.black); //gContext.drawImage( nave.ImagenFuente[0], (int) (nave.actualX), (int) (nave.actualY), this ); for (int i = 0; i < MAX_ENEMIGOS; i++) { enemigo[i].actualY += enemigo[i].incrementoY; gContext.drawImage(enemigo[i].ImagenFuente[0], (int) enemigo[i].actualX, (int) enemigo[i].actualY, this ); enemigo[i].avanzar(); } for (int i = 0; i < indiceDisparos; i++) { disparos[i].actualY -= disparos[i].incrementoY; gContext.drawImage(disparos[i].ImagenFuente[0], (int) disparos[i].actualX+9, (int) disparos[i].actualY, this ); //disparos[i].avanzar(); } gContext.drawImage( nave.ImagenFuente[0], (int) (nave.actualX), (int) (nave.actualY), this ); } else { gContext.setColor(Color.white); gContext.drawString("PAUSADO", (d.width - fm.stringWidth("PAUSADO")) / 2, d.height / 2); } // Actualizar la pantalla y establecer el contador para el siguiente bucle // según el retraso establecido por la constante repaint(); try { startTime += RETRASO; Thread.sleep(Math.max(0, startTime - System.currentTimeMillis())); } catch (InterruptedException e) { showStatus( e.toString() ); break; } } } public void paint( Graphics g ) { g.drawImage( buffer, 0, 0, this ); } public void update(Graphics g) { paint( g ); } public void GenerarEstrellas() { Graphics g; Dimension d; d = size(); // Generar fondo de estrellas estrellas = new Point[MAX_ESTRELLAS]; TamEstrellas = new Point[MAX_ESTRELLAS]; for (int i = 0; i < MAX_ESTRELLAS; i++) { estrellas[i] = new Point((int) (Math.random() * d.width), (int) (Math.random() * d.height)); TamEstrellas[i] = new Point( (int) aleatorio(6), (int) aleatorio(6) ); } } public void InicializarFuente( Graphics g) { // Establecer datos de font tipográfica g.setFont(font); fm = g.getFontMetrics(); fontWidth = fm.getMaxAdvance(); fontHeight = fm.getHeight(); } public void MostrarCreditos( Graphics g) { String s; s = " S P A C E N A V "; g.setColor(Color.white); g.drawString(s, (d.width - fm.stringWidth(s)) / 2, d.height / 2); } public void InicializarNave() { Dimension d; d = size(); nave.width = d.width; nave.height = d.height; nave.ImagenFuente = new Image[ 1 ]; nave.ImagenFuente[0] = getImage( getDocumentBase(),"spacenav.gif" ); nave.actualX = (d.width / 2.0) - 10; nave.actualY = d.height - 30.0; nave.VerificarDesborde = false; } public void InicializarDisparos() { for (int i = 0; i < MAX_DISPAROS; i++) { disparos[i] = new Objeto(); disparos[i].ImagenFuente = new Image[ 1 ]; disparos[i].ImagenFuente[0] = getImage( getDocumentBase(),"disparo.gif" ); disparos[i].cantidad = 0; disparos[i].incrementoY = 5; //disparos[i].actualX = nave.actualX+15; //disparos.actualY = nave.actualY-15; //disparos.VerificarDesborde = true; //disparo.activo = false; contadorDisparos[i] = 0; } indiceDisparos = 0; } public void ActualizarNave() { // Pinta la nave if ( !semaforo ) incremento_tecla = 3; else incremento_tecla = 1; if (izquierda) nave.actualX -= incremento_tecla; if (derecha) nave.actualX += incremento_tecla; if (arriba) nave.actualY -= incremento_tecla; if (abajo) nave.actualY += incremento_tecla; nave.avanzar(); } public void ActualizarDisparos() { // Mover los disparos activos. Parar cuando el contador haya expirado for (int i = 0; i < MAX_DISPAROS; i++) if (disparos[i].activo) { //disparos[i].avanzar(); if (--contadorDisparos[i] < 0) disparos[i].activo = false; } } public boolean keyDown(Event e, int key) { // Comprobar si se ha pulsado alguna tecla y establecer banderas (flags) semaforo = false; if (key == Event.LEFT) izquierda = true; if (key == Event.RIGHT) derecha = true; if (key == Event.UP) arriba = true; if (key == Event.DOWN) abajo = true; if (key == 32) { disparos[indiceDisparos].activo = true; disparos[indiceDisparos].actualX = nave.actualX; disparos[indiceDisparos].actualY = nave.actualY; //disparos[indiceDisparos].incrementoY = MIN_TAMANIO_ROCA * Math.cos(nave.angulo); contadorDisparos[indiceDisparos] = Math.min(Objeto.width, Objeto.height) / 2; indiceDisparos++; if (indiceDisparos >= MAX_DISPAROS) indiceDisparos = 0; } if (key == 112) // Tecla 'P': activa o desactiva la pausa pausado = !pausado; return true; } public boolean keyUp(Event e, int key) { // Comprueba si se ha soltado alguna tecla y establece las banderas apropiadas. semaforo = true; if (key == Event.LEFT) izquierda = false; if (key == Event.RIGHT) derecha = false; if (key == Event.UP) arriba = false; if (key == Event.DOWN) abajo = false; return true; } private int aleatorio( int rango ) { double retornoMath; retornoMath = Math.random(); return( (int)( retornoMath * rango ) ); } }