Bueno despues 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
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 rapido 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 asi hay juegos como el NFS: Carbon aun jugandolo a 20 FPS todavia es jugable, en cambio FEAR no.
Aun asi el numero que ponen (50 FPS) no es correcto, dicen que el ojo humano no distringue 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, quedense mirando y de seguro se daran 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 ilusion 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 ilusion de realidad solo se llega con 72 FPS.
Los cambios en el codigo 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()
Este capitulo la verdad es que es muy interesante porque nos enseña realmente algo, digo esto porque la reorganizacion del codigo, nos lleva a la reutilizacion del codigo y al uso de patrones, esto es muy importante en Java porque es, de lejos, el lenguaje que mas codigo tienes que desarrollar y es una muy buena practica recomendada por todos los programadores porque mejora no solo el aspecto de tu programa (organizacion de clases) sino tambien la eficiencia y ademas te será más facil encontrar errores, tiene demasiados pros a favor y su unico en contra es que puede ser un poco tedioso al inicio. Ademas con esto estamos dando pase a un motor de juego (<- Esto lo explicare mas adelante) ya que ese codigo lo podras reutilizar en otros juegos, no solo en graficos y sonidos sino tambien 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 funcion 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 actua como un Observer, que es un patron muy comun en Java, ya que el sabe cuando hay un cambio en la construccion de las imagenes
Ingresamos a los fotogramas, le daremos vida nuestros mosntruos (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 Bytex