Actualizando el 03/05/2012… Agregue el código fuente que ya desapareció de la web aquí
Bueno después de 1 semana, regreso con el jueguito, la semana pasada me mandaron a hacer un msn y bueno que cuando lo termine lo publicare, osea a finales de diciembre, es un trabajo de la u y si lo publico antes me lo copian XD
Capitulo 12
Bueno en este nuevo capitulo se toca un tema muy importante que son los FPS (frames por segundo), en resumidas cuentas los fps te indican que tan rápido y mejor ira tu juego, y esto es debido a la velocidad en que la pantalla refrescara, Entre mas objetos tengamos en pantalla mas demorara en refrescar, aun así hay juegos como el NFS: Carbon aun jugando lo a 20 FPS todavía es jugable, en cambio FEAR no.
Aun así el numero que ponen (50 FPS) no es correcto, dicen que el ojo humano no distingue framerates por encima de los 30 FPS, pero esto tampoco no es de lo mas verdadero, en realidad podemos ver y reconocer mas 70 FPS, si no me creen hagan algo, pongan su monitor a 60 HZ, queden mirando y de seguro se darán cuenta como el monitor va refrescando, como si fuera una salpicadera, es por eso que los monitores salen a 72HZ como velocidad por default. Ahora entonces ¿cual es el framerate que se necesita? la verdad es que si quieren conseguir una ilusión de realidad (Juegos de Shooter) los FPS no deben bajar de los 60 FPS ni subir los 72 FPS, 30 FPS esta bien pero la ilusión de realidad solo se llega con 72 FPS.
Los cambios en el código son estos:
g.setColor(Color.white);// cambiamos el color a blanco, para las letras de pantalla if (usedTime > 0)// si hubo alguna demora en milisegundos en las funciones calcula el fps g.drawString(String.valueOf(1000/usedTime)+" fps",0,HEIGHT-50); else // si no hubo ninguna demora g.drawString("--- fps",0,HEIGHT-50); usedTime=1000;// no sirve para nada este valor while (isVisible()) { long startTime = System.currentTimeMillis(); //currentTimeMillis nos devuelve el tiempo en milisegundos por ejemplo ahorita son las 8pm con 28 min y 30 segundos con 12 milisegundos usedTime = System.currentTimeMillis()-startTime;// Resta el tiempo actual al anterior, para saber cuanto se demonro despues d pasar por las funciones updateWorld() y paintWorld()
Capitulo 13:
Este capitulo la verdad es que es muy interesante porque nos enseña realmente algo, digo esto porque la reorganización del código, nos lleva a la reutilizacion del código y al uso de patrones, esto es muy importante en Java porque es, de lejos, el lenguaje que mas código tienes que desarrollar y es una muy buena practica recomendada por todos los programadores porque mejora no solo el aspecto de tu programa (organización de clases) sino también la eficiencia y ademas te será más facil encontrar errores, tiene demasiados pros a favor y su único en contra es que puede ser un poco tedioso al inicio. Ademas con esto estamos dando pase a un motor de juego (<- Esto lo explicaré mas adelante) ya que ese código lo podrás reutilizar en otros juegos, no solo en gráficos y sonidos sino también en la inteligencia artificial y el manejo de dispositivos de entrada
Primero se crea la clase SpriteCache, nada interesante de eso aunque no olviden cambiar la función public BufferedImage loadImage(String nombre)
Luego se crea la interfaz Stage
public SpriteCache getSpriteCache();//retorna el constructor, por decirlo de alguna manera
La clase Actor es una clase que es capaz de encapsular prácticamente cualquier cosa “activa” o “viva” sobre el escenario (como lo dice el capitulo).
public Actor(Stage stage) {//constructor this.stage = stage; spriteCache = stage.getSpriteCache();//Retorna la clase a traves de la interfaz } public void paint(Graphics2D g){//graficamos el monstrito dentro de la pantalla g.drawImage( spriteCache.getSprite(spriteName), x,y, stage ); } public void setSpriteName(String nombre) { spriteName = nombre; BufferedImage image = spriteCache.getSprite(spriteName);//almacena la imagen height = image.getHeight();//x las puras width = image.getWidth();//x las puras }
La clase Monster
public Monster(Stage stage) { super(stage);//Recibimos el stage de actor setSpriteName("bicho.gif");// le damos el nombre del archivo }
La clase Invaders
public void initWorld() { actors = new ArrayList();//inicializa los actores for (int i = 0; i < 10; i++){ Monster m = new Monster(this);//inicializamos el nuevo monstrito //Le damos sus caracteristicas (Posicion en la pantalla) m.setX( (int)(Math.random()*Stage.WIDTH) ); m.setY( i*20 ); m.setVx( (int)(Math.random()*20-10) ); actors.add(m);//agregamos un monstrito } } public void updateWorld() { for (int i = 0; i < actors.size(); i++) { Actor m = (Actor)actors.get(i); m.act();//Hacemos que cada monstrito actue } } public void game() { usedTime=1000; initWorld();// nueva clase inicializadora
Solo para que sepan Stage actúa como un Observer, que es un patrón muy común en Java, ya que el sabe cuando hay un cambio en la construcción de las imágenes
Capitulo 14
Ingresamos a los fotogramas, le daremos vida nuestros monstruos (En parte)
La clase Actor:
protected String[] spriteNames;// nuevo array protected int currentFrame;// lugar de la imagen en el array currentFrame = 0;// imagen 0 g.drawImage( spriteCache.getSprite(spriteNames[currentFrame]), x,y, stage );// graficamos cada frame public void setSpriteNames(String[] names) { for (int i = 0; i < names.length; i++ ) { BufferedImage image = spriteCache.getSprite(spriteNames[i]); height = Math.max(height,image.getHeight());//adivinen... por las puras width = Math.max(width,image.getWidth());//adivinen... por las puras } } currentFrame = (currentFrame + 1) % spriteNames.length;// no entiendo bien su funcionamiento
Y listo nos vemos luego
Buena Suerte!