SmRndGuy
SmRndGuy

Reputation: 1819

Is it a good idea to use repaint() as a game loop?

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

Answers (1)

Nate
Nate

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().

Usage

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);

References

Upvotes: 1

Related Questions