Reputation: 1819
class MyCanvas extends Canvas{
protected void paint(Graphics g) {
//Process keyboard
//Update movement/position
//Draw
repaint(); //loop
}
}
Until now I used the Canvas's paint()
for the game loop, but I came across some article in the web that says that another thread should be used here
Now I'm wondering if paint()
is a good/safe place to process all the data.
So can I continue doing it like this?
Or should I make another thread for that?
I'm not sure of pros and cones of each so I'm not sure which method to choose but I got used to repaint method
Upvotes: 0
Views: 247
Reputation: 31045
I would not use paint()
that way, no. paint()
should be for painting ... drawing. I would split your monitoring of user input, and game logic processing, outside that method.
Have you considered using the GameCanvas subclass of Canvas?
It gives you some nice double-buffering features. You would create another thread, which would call your GameCanvas' run()
method, where it would check for user input, update the game logic, then draw to the off-screen buffer, and finally trigger repainting of the on-screen buffer.
Something like this:
class MyGameCanvas extends GameCanvas implements Runnable {
/** start this game! */
public void start() {
Thread worker = new Thread(this);
worker.start();
}
/** run the game loop */
public void run() {
// Get the Graphics object for the off-screen buffer
Graphics g = getGraphics();
while (true) {
// Check user input and update positions if necessary
int keyState = getKeyStates();
if ((keyState & LEFT_PRESSED) != 0) {
sprite.move(-1, 0);
}
else if ((keyState & RIGHT_PRESSED) != 0) {
sprite.move(1, 0);
}
// Clear the background to white
g.setColor(0xFFFFFF);
g.fillRect(0,0,getWidth(), getHeight());
// Draw the Sprite
sprite.paint(g);
// Flush the off-screen buffer
flushGraphics();
try {
// TODO: of course, you might want a more intelligent
// sleep interval, that reflects the amount of time
// remaining (if any) in the cycle ...
Thread.sleep(10); //sleep 10 ms
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Note that I put basically everything in the run()
method, for brevity. I'm assuming your game is more complicated, and would warrant splitting off separate methods for getting user input, updating logic, and then calling graphics/paint methods. Those would all be called from run()
.
Start this in your MIDlet's startApp()
method:
MyGameCanvas gameCanvas = new MyGameCanvas();
gameCanvas.start();
exitCommand = new Command("Exit", Command.EXIT, 1);
gameCanvas.addCommand(exitCommand);
gameCanvas.setCommandListener(this);
Display.getDisplay(this).setCurrent(gameCanvas);
GameCanvas
and just use Canvas
.Upvotes: 1