Estoy empezando a aprender ideas básicas de desarrollo de juegos 2D utilizando Java. Buscando por la red me encontré con varios tutoriales hasta que termine con este que por lo que entiendo está basado en el código del Minicraft de Notch y además es bastante completo, pongo enlace al primero de los videos:
[youtube]http://es.youtube.com/watch?v=VE7ezYCTPe4[/youtube]
La cuestión es que bueno, como digo los videos están bastante bien y el código es bastante legible, pero la barrera del idioma hace que en algunas ocasiones no entienda muy bien como funcionan las cosas que se tratan.
He escrito el código de este primer video y ahora mi intención es ir poco a poco resolviendo las dudas que tengo para ver como funciona y con que objeto. Por ejemplo, una de las cosas que no entiendo son las variables de "ticks" y "frames" que supongo contabilizan algo pero ni idea de por qué ni para qué. A partir de ahí se complican las cosas por los métodos que las utilizan.
Os dejo el código de la clase por aquí, con los comentarios que he dejado a modo de notas sobre lo que no comprendo, por si a alguien más le interesa y no le importa echar un cable 🙂
package com.philspectrum.game;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable
{
private static final long serialVersionUID = 1L;
public static final int WIDTH = 160;
public static final int HEIGHT = WIDTH/12*9;
public static final int SCALE = 3;
public static final String NAME = "Game";
private JFrame frame;
public boolean running = false; //bandera para saber si está lanzado
public int tickCount = 0; //contador de... ¿ticks?
private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); //no se que es este array
public Game()
{
//¿para que sirve cada una?
setMinimumSize(new Dimension(WIDTH*SCALE,HEIGHT*SCALE));
setMaximumSize(new Dimension(WIDTH*SCALE,HEIGHT*SCALE));
setPreferredSize(new Dimension(WIDTH*SCALE,HEIGHT*SCALE));
frame = new JFrame(NAME);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout()); //BorderLayout: North, South, West, East y Center
frame.add(this, BorderLayout.CENTER); //Colocamos esta clase en el centro del Layout
frame.pack(); //método que hace que la ventana tenga el tamaño más pequeño posible permitiendo ver todos los componentes
frame.setResizable(false); //no permitimos que el usuario cambie el tamaño
frame.setLocationRelativeTo(null); //colocamos la ventana en una posición, con "null" en el centro de la pantalla
frame.setVisible(true); //lo hacemos visible
}
//¿que hace cada uno de estos métodos y por qué van sincronizados?
public synchronized void start()
{
running = true;
new Thread(this).start();
}
public synchronized void stop()
{
running = false;
}
public void run()
{
Long lastTime = System.nanoTime();
double nsPerTick = 1000000000D/60D; //no entiendo que significan estos doubles
//a que le llama frames y ticks y para que sirven
int frames = 0;
int ticks = 0;
long lastTimer = System.currentTimeMillis();
double delta = 0; //lo mismo que con los frames y ticks ¿para que sirve?
while(running)
{
long now = System.nanoTime(); //esto es ahora :D
delta +=(now - lastTime) / nsPerTick; //WTF??
lastTime = now; //supongo que quiera darle el valor del tiempo actual a la variable ¿para qué?
boolean shouldRender = true; //bandera para saber si debe o no renderizar (supongo)
while(delta >= 1)//al no entender la variable, no se que hace esto
{
ticks++;
tick();
delta -= 1;
shouldRender = true;
}
try
{
Thread.sleep(2); //no se por qué duerme al hilo principal
}
catch (InterruptedException e)
{
e.printStackTrace();
}
if(shouldRender)//cuando debe renderizar suma un valor a frames (¿por qué?) y llama al método render()
{
frames++;
render();
}
if(System.currentTimeMillis() - lastTimer >= 1000) //Si esto es menor que 1000... ya, pero...
{
lastTimer += 1000;
System.out.println(ticks+" ticks, "+frames+" frames");
frames = 0;
ticks = 0;
}
}
}
public void tick() //el método cuenta ticks ¿que son los ticks? Oh my god...
{
tickCount++;
for(int i = 0; i<pixels.length;i++)//y aquí hace algo con el array de pixels, pero no se para qué
{
pixels[i]=i+tickCount;
}
}
public void render()//no veo claro lo que hace este método, dibuja cosas pero...
{
BufferStrategy bs = getBufferStrategy();
if(bs==null)
{
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
g.dispose();
bs.show();
}
public static void main(String[] args)//esto si lo entiendo: ES EL MAIN :D
{
new Game().start();
}
}