So some of you noticed that I am trying to find my way around game development.
I first tried to comprehend game loops deeply enough to write my own. The same goes for the “best” way of active rendering (If there is one).
Like anyone who reads this, you guess that I keep failing and am getting sick and tired of that.
So first of all I wanted to ask a question; How much Java 2D should we know? I did not plan to ask this, but I saw some libgdx tutorials and image drawing was nothing like Java 2D. The other reason of this question is that I am getting tired of Java 2D, not because it’s slow etc., I still get very frustrating errors
Anyway, I have a code snippet to be used as a skeleton (or let’s say a template) for my practices. I figured that if I keep staying on these two topics and don’t go further, I’d get bored. So for now I am going to use this to make something ‘visible’ and I am hoping to learn and understand why there are so many methods to do these things.
But I have some questions regarding the code snippet. It is not written by me. I guess I took it from Killer Game Programming in Java book. It uses active rendering and has a basic game loop.
The first two question is about active rendering. In the book, he does that like this (Comments are written by me to understand what’s going on):
//These are defined in the class
private Graphics dbg; // For double buffering
private Image dbImage = null; // For double buffering as well
//This is one method:
private void gameRender() {
if (dbImage == null) { // second image for double buffer
dbImage = createImage(PWIDTH, PHEIGHT);
dbg = dbImage.getGraphics();
}
// Clear the screen
dbg.setColor(Color.white);
dbg.fillRect(0, 0, PWIDTH, PHEIGHT);
// Draw all other stuff
dbg.drawImage(dbImage, 0,0, this);
}
//Then this:
private void paintScreen(){ //Active rendering -- No need for repaint or paintComponent
Graphics g; // Also considered to be more efficient
try {
g = this.getGraphics(); // It says JVM may clear this, so every time we run this, we
// have to get graphics
if ((g != null) && (dbImage != null))
g.drawImage(dbImage, 0, 0, null);
g.dispose(); //Why do we dispose that?
} catch (Exception e) {
System.out.println("Graphics context error: " + e);
}
}
Game loop goes like this: update method, gameRender, paintScreen and calculations.
Why did he use two methods to do the drawing? Is this correct?
And why do we dispose the g Graphics object?
Second is about game loop. In the book he says this one might cause problems, but this is as good as I can understand, nothing further. But still there is something…
There is a “period” variable (actually I don’t know what it is) and he never defined it anywhere. But he explains it before the code:
[quote]A popular measure of how fast an animation progresses is frames per second (FPS). For GamePanel, a frame corresponds to a single pass through the update-render-sleep loop inside run(). Therefore, the desired 100 FPS imply that each iteration of the loop should take 1000/100 == 10 ms. This iteration time is stored in the periodvariable inGamePanel.
[/quote]
I could not understand what he means. Can anyone please explain it? And how does he plan to use that?
And here is the full code (Not the finished one - he says it is to be improved, but I just couldn’t understand, so that is it )
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.JPanel;
//This will be embedded into a frame or applet
public class GamePanel extends JPanel implements Runnable {
private static final int PWIDTH = 500; // panel dimensions
private static final int PHEIGHT = 400;
private Thread animator; // animation thread
private volatile boolean running = false; // user just shuts the game
private volatile boolean gameOver = false; // game ends as a result of user's fault or level ends
private Graphics dbg; // For double buffering
private Image dbImage = null; // For double buffering as well
// more variables, if needed
public GamePanel() {
setBackground(Color.white);
setPreferredSize(new Dimension(PWIDTH, PHEIGHT));
// create game components
}
private void startGame() {
if (animator == null || !running) {
animator = new Thread(this);
animator.start();
}
}
public void stopGame() {
running = false;
}
public void run() {
long beforeTime, timeDiff, sleepTime; // To determine sleep time of the thread?
beforeTime = System.currentTimeMillis();
running = true;
while (running) {
gameUpdate();
gameRender();
paintScreen(); // This makes active rendering. So I don't need to use repaint etc.
// This loop is said to be problematic, but haven't figured out yet
timeDiff = System.currentTimeMillis() - beforeTime;
sleepTime = period - timeDiff; // what's period? Never used or declared even.
if (sleepTime <= 0) // if drawing took longer than animation (One line up)
sleepTime = 5; //
try {
Thread.sleep(sleepTime); // ms
} catch (InterruptedException ex) {
}
beforeTime = System.currentTimeMillis();
}
System.exit(0);
} // end of run()
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (dbImage != null)
g.drawImage(dbImage, 0, 0, null);
}
private void paintScreen(){ //Active rendering -- No need for repaint or paintComponent
Graphics g; // Also considered to be more efficient
try {
g = this.getGraphics(); // It says JVM may clear this, so every time we run this, we
// have to get graphics
if ((g != null) && (dbImage != null))
g.drawImage(dbImage, 0, 0, null);
g.dispose(); //Why do we dispose that?
} catch (Exception e) {
System.out.println("Graphics context error: " + e);
}
}
private void gameRender() {
if (dbImage == null) { // second image for double buffer
dbImage = createImage(PWIDTH, PHEIGHT);
dbg = dbImage.getGraphics();
}
// Clear the screen
dbg.setColor(Color.white);
dbg.fillRect(0, 0, PWIDTH, PHEIGHT);
// Draw all other stuff
dbg.drawImage(dbImage, 0,0, this);
}
private void gameUpdate() {
if (!gameOver) {
// update game state if it is not over
}
// This is only a skeleton
}
}
And this is a kind wish for who could read so far: Comment on the code - considering that it is obvious that it is not finished. Like, why it will cause problems etc.