Actualizando el 03/05/2012… Agregue el código fuente que ya desapareció de la web aquí
Capitulo 24
Hasta este punto nuestro juego parecía más un juego de tiro al pato más que un Space Invaders… jajajaja xD
Comenzamos, se daran cuanta que laser.java es casi identico a bullet.java por lo tanto nada que decir
monster.java
protected static final double FIRING_FREQUENCY = 0.01;//variable para la frecuencia con q el monstruo va a disparar if (Math.random() fire();//dispara public void fire() {//como en player Laser m = new Laser(stage); m.setX(x+getWidth()/2); m.setY(y + getHeight()); stage.addActor(m); }
player.java
if (a instanceof Laser ) {//igual que con monster a.remove(); addShields(-10); }
Capitulo 25
un capitulo interesante después de bastante… aunque ni tanto… =P
primero que nada explicar que lo único que se va a hacer es varios cuadrados, que llenen la pantalla y luego esos cuadrados los vamos a mover un poco cada cierto tiempo, y modificaremos, otra vez, invaders.java
ocean = spriteCache.getSprite("oceano.gif"); g.setPaint(new TexturePaint(ocean, new Rectangle(0,t,ocean.getWidth(),ocean.getHeight())));//la clase texturepaint, lo que hace es pintar la imagen arriba a la izquierda y luego repetirla al largo y ancho de la pantalla
Capitulo 26
Nada nuevo, ni interesante, aunque cabe resaltar que para darle mas inteligencia la juego, aunque ni tanta, pero si mas dificultad deberia el monstruo mejorar la velocidad y ademas por lo menos debería aparecer en el mismo lugar para eso tendríamos que hacer esto:
spawn(y,vx);// le paso la altura y la velocidad public void spawn(int a, int b) { Monster m = new Monster(stage); m.setX( (int)(Math.random()*Stage.WIDTH) ); m.setY(a);//recibimos la misma altura m.setVx(b+4);// aumentamos la velocidad stage.addActor(m); }
cabe decir que se hacen demasiado rápidos y aumenta la dificultad, pero después de un momento son tan rápidos que ya no se pueden ver, pero bueno así vamos mejorando =P
Capitulo 27
En juegos por ejemplo como F.E.A.R el sonido es vital, bueno acá se toca ese tema, pero quiero hacer énfasis en algo, al comienzo de este blog, dije que url no se utilizaba, la verdad es que luego de investigar me di cuenta que si, se utiliza para llamar una imagen, pero la verdad es que no pude arreglar ese error y en vista de eso, les voy a pasar el código de como arregle ese error
ResourceCache.java
public abstract class ResourceCache { protected HashMap resources; public ResourceCache() { resources = new HashMap(); } protected Object loadResource(String nombre) { // URL url=null; // url = this.getClass().getResource(name); // return loadResource(url); File file=null; file = new File(nombre); return loadResource(file); } protected Object getResource(String name) { Object res = resources.get(name); if (res == null) { res = loadResource("imagenes/"+name); resources.put(name,res); } return res; } protected abstract Object loadResource(File file);
SpriteCache.java
public class SpriteCache extends ResourceCache { public BufferedImage getSprite(String nombre) { return (BufferedImage)getResource(nombre); } @Override protected Object loadResource(File url) { try { return ImageIO.read(url); } catch (Exception e) { System.out.println("No se pudo cargar la imagen de "+url.getAbsolutePath()); System.out.println("El error fue : "+e.getClass().getName()+" "+e.getMessage()); System.exit(0); return null; } } }
Luego de esto viene soundcache.java, desde mi perspectiva esta clase no debería usar esas librerias que llama, pero primero voy a usar su forma y al final voy a mejorarlo
soundcache.java
URI archivo; @Override protected Object loadResource(File file) { archivo = file.toURI(); try { return Applet.newAudioClip(archivo.toURL()); } catch (MalformedURLException ex) { Logger.getLogger(SoundCache.class.getName()).log(Level.SEVERE, null, ex); return null; } }
y con las demás funciones claro esta
El resto de cambios son implementaciones de las funciones, osea nada interesante
Antes de mejorar el código del capitulo 27, veamos como mejoran su código
Capitulo 28
En este capitulo lo que hace es crear una mejora para su sonido, bueno me imagino que en ese tiempo su computadora seria muy lenta porque en la mia no hay ningún problema aunque el FPS cuando disparo sube, pero no se siente, es que con las maquinas de ahora ¿que puede ser lento?… y los que hacen juegos en C creen que java no tiene futuro en juegos xD, tendríamos que preguntarles a los de assembler que decían lo mismo de ellos…
public void playSound(final String name) { new Thread( new Runnable() { public void run() { getAudioClip(name).play(); } } ).start(); }
Lo único que hace es crear un nuevo hilo para hacerlo parecer como si corriera en paralelo, la verdad esto no creí que sea lo mas prudente, si se dan cuenta en su administrador de tareas, java aumenta unos kilobytes significa que esta usando mas memoria, obvio que en este juego no se va a sentir pero imagínense que avancen las fases y coloquemos mas sonidos, vamos a usar mas memoria del cpu y el juego se va a tornar lento, es por eso que yo creo que deberíamos cambiar de código, primero voy darle el directorio a usar y despues voy cambiar el código de audio
ResourceCache.java
protected Object getResource(String carpeta, String name) { Object res = resources.get(name); if (res == null) { res = loadResource(carpeta+"/"+name); // ahora va a recibir la carpeta resources.put(name,res); } return res; }
SoundCache.java
//bueno antes de comenzar con soundcache otra cuestion, ahora usamos file en vez de url entonces soundcache quedaria asi // quizas el mayor cambio este aqui, donde he cogiod un codigo "prestado" de javacup :P, lo adapte lo mejor que me parecio, cuando lo ejecuten se daran cuenta que el juego deja de hacerse lento y sin necesidad de poner otros hilos public class SoundCache extends ResourceCache{ private static Hashtable sonidos=new Hashtable(); @Override protected Object loadResource(File file) { AudioInputStream audioInputStream; try { audioInputStream = AudioSystem.getAudioInputStream(file); AudioFormat format = audioInputStream.getFormat(); DataLine.Info info = new DataLine.Info(Clip.class, format); Clip m_clip; m_clip = (Clip) AudioSystem.getLine(info); m_clip.open(audioInputStream); sonidos.put(file.getName(), m_clip); } catch (UnsupportedAudioFileException ex) { Logger.getLogger(SoundCache.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(SoundCache.class.getName()).log(Level.SEVERE, null, ex); } catch (LineUnavailableException ex) { Logger.getLogger(SoundCache.class.getName()).log(Level.SEVERE, null, ex); } return null; } public AudioClip getAudioClip(String name) { return (AudioClip)getResource("sonidos",name); } public void playSound(String sNombre) { try { if (!sonidos.containsKey(sNombre)) getAudioClip(sNombre); if (sonidos.containsKey(sNombre)){ Clip m_clip=sonidos.get(sNombre); m_clip.setFramePosition(0); m_clip.start(); } } catch (Exception e) { //e.printStackTrace(); } } public void loopSound(String sNombre) { try { if (!sonidos.containsKey(sNombre)) getAudioClip(sNombre); if (sonidos.containsKey(sNombre)){ Clip m_clip=sonidos.get(sNombre); m_clip.setFramePosition(0); m_clip.loop(m_clip.LOOP_CONTINUOUSLY); } } catch (Exception e) { //e.printStackTrace(); } }}
En resumen mejore el sonido y el código para que no solo pueda buscarse de un solo directorio, sino que la imágenes y los sonidos puedan estar en diferentes directorios
Buena Suerte!