Olá, fiz um pequeno framework com base nas dicas fornecidas.
Ele controla por si mesmo o game loop, bufferstrategy, bind de keylistners etc
Para fazer um jogo basta implementar esta interface:
import java.awt.Graphics;
/**
*
* @author root
*/
public interface Game {
/*
* Inicia o game, splashscreen, carregas as imagens etc.
*/
public void initGame();
/*
* Processa tecla pressionada
*/
public void processGameKeyPressed(int key);
/*
* Processa tecla solta
*/
public void processGameKeyReleased(int key);
/*
* Atualiza lógica do game
*/
public void updateGameLogic();
/*
* Renderiza o game utilizando aqui o graphics fornecido pelo framework atravez de bufferstrategy.
* Antes de executar este método, o framework também já limpa o frame anterior.
* A área deste graphis já desconta os Insets do jframe. o framework também da o dispose automaticamente no final do uso.
*/
public void renderGame(Graphics g);
/*
* Finaliza o game, tela de gameover etc.
*/
public void endGame();
/*
* Este método controla a continuidade do game loop, que é controlado pelo framework
*/
public boolean continueGame();
}
e então passar a implementação para o framework:
GameLoader.load(Game game);
Segue um exemplo. Neste jogo podemos movimentar um personagem pela tela, apenas como exemplo. Percebam que o código só tem a lógica do jogo. Toda a parte de controle do loop, bufferstrategy, jframe etc. etc. está encapsulada no framework
import gameframework.Game;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JOptionPane;
/**
*
* @author root
*/
public class Jogo implements Game{
private boolean rodando = true;
private int x = 0;
private int y = 0;
private BufferedImage boneco = null;
@Override
public void initGame() {
try {
boneco = ImageIO.read(new File("/home/gustavo/images/boneco.png"));//coloque aqui a imagem pequena que tiver em seu PC.
} catch (IOException ex) {}
JOptionPane.showMessageDialog(null, "Movimente usando setas do teclado. 'Esc' para sair");//splashscreen
}
@Override
public void processGameKeyPressed(int key) {
if(key == KeyEvent.VK_ESCAPE){
rodando = false;//sai do jogo
}
if(key == KeyEvent.VK_RIGHT){
x = x + 2;
}
if(key == KeyEvent.VK_LEFT){
x = x - 2;
}
if(key == KeyEvent.VK_UP){
y = y - 2;
}
if(key == KeyEvent.VK_DOWN){
y = y + 2;
}
}
@Override
public void processGameKeyReleased(int key) {}
@Override
public void updateGameLogic() {}
@Override
public void renderGame(Graphics g) {
g.drawImage(boneco, x, y, null);
}
@Override
public void endGame() {
JOptionPane.showMessageDialog(null, "Game Over");
}
@Override
public boolean continueGame() {
return rodando;
}
}
E então para iniciar o jogo:
public static void main(String[] args) {
// TODO code application logic here
Jogo jogo = new Jogo();
GameLoader.load(jogo);
}
Naturalmente ele está muito aberto, não define por exemplo interface de sprite e então, recursivamente, atualiza a lógica de cada sprite e o pinta na tela.
Fica para uma próxima versão