Pacman Design Issues

Hi, im quite new to java games, so i thought i’d post here.
Im working on a pacman game, which has to have some pathfinding to it later on, but for now im just concentrating on movement of pacman itself.
I have a working movable pacman, but in my opinion it doesnt run as smooth as it should be, and i think its the way i come up with to get it working.

've got a class, Game, which is an extention of JPanel. Furthermore i’ve implemented KeyListener to make pacman move by passing the direction it is supposed to be moving to, to the Pacman object. (ie, pressing left will do something like pacman.setDirection(Pacman.LEFT)).

So i’ve got a class Pacman, which implements Runnable, and has a constructorargument Game.


//constructor
public Pacman(Game game) {
    this.game=game;
}

I also made a method drawObject, which i call from within the Game object its paintComponent method which i have overridden. This method draws the pacman on the screen at the right position.


// in class Game
public void paintComponent(Graphics g) {
    pacman.drawObject(g);
}


// in class Pacman
public void drawObject(Graphics g) { 
    g.fillRect(x,y,20,20);
}

I initialize the Pacman object in the Game object, and let pacman run by creating a new Thread and starting it. In the run method of the Pacman object i have a while loop, and each time it passes it checks the direction of the pacman and then updates its coordinates. Last in the whileloop i call game.repaint(); to redraw.


public void run() {
    while(running) {
        // update x, y
       game.repaint();
       Thread.sleep(50); // if i dont do this, it goes too fast ;) (and yes i know i have to catch an exception here ;))
   }
}

It works, but like i said, its not running as smooth as it should be, and i’ve yet to paint the 30x30 tiles maze ;). What could i consider to make it run more smooth than it does now?

Hm. Its unneccessarly complicated.

You only need one thread - the main thread. And since its java2d there is another one… the event dispatcher thread, which just happens to be there.

You need some KeyListener methods, which are called from that dispatcher thread (therefore they are asynchronously). The only thing you do there is setting flags for the moving-direction.

And over in the main thread you only need three things:
-logic
(like checking the moving-direction flags and responding to that, eating pills, moving ghosts, colliding with ghosts… stuff like that)

-drawing
(the board, the pills, the ghosts, pacman some hud…)

and finally some throtteling code for ensuring that it runs at a fixed speed.

You can find some simple throtteling code here:
http://www.java-gaming.org/forums/index.php?topic=11640.30

allright, it sounds nice, but that would imply that i somehow have to implement a loop somewhere that needs to be running till the game ends?

Yes. (Its the so called “main loop”)

Check kev’s tutorials:
http://www.cokeandcode.com/tutorials

wow, excelent, thx alot :slight_smile:
The performance is so much better now than it was :slight_smile:

so i’ve now come to the point where i’ve got about 900 entities because i made each wall and each dot an entity (30x30 grid), and the performance degraded alot when painting. Logicaly, because it paints everything each loop, just like in Kevin Glass his tutorial on space invaders. So i figured, why should i paint everything each loop, so i came up with the idea that when a entity doesnt move, it doesnt have te be repainted. The only problem with this problem is that i dont clear the screen, causing everything that does move to have a trail, which i obviously dont want.

How should i solve this?

Edit: using buffered images like the space invaders tutorial instead of doing g.fillRect does seem to improve performance alot, but is it still possible to redraw only what is needed, without having to clear the screen?

You can have a boolean on each thing which can be drawn, specifying whether that thing is ‘dirty’ or not. Then, when something moves, everything which has a bounding box intersecting the the bounding box of the moving sprite (actually, the union of the bounding box before and after move, since otherwise there may be small areas where the paint “lingers”) must be set to dirty and thus repainted. As long as you remember to dirtify ANYTHING that has been in touch with the bounding box of your moving object, you’re safe.