views:

617

answers:

5

Hi,

I am making a multithreaded pacman game.

There is a PacmanController class which extends JFrame, a Maze class which extends JPanel, a Pacman class which runs in its own thread and extends JPanel, and a Ghost class which runs in its own thread and extends JPanel. Each thread (pacman and each Ghost) continuously repaints itself and calls maze.repaint() as well.

When I add the maze to the frame, it displays fine, if I then add pacman, it still displays and animates fine.

However, when I add the Ghost to the frame after pacman, the ghost appears and pacman disappears. If I switch the order in which pacman and the ghost are added, the opposite is true i.e. only one of pacman or each instance of ghost is ever displayed - the one which is added last.

Eg:

add(maze);
add(pacman);
add(ghostA);

Only the maze and ghostA appear?

I realize this has something to do with JFrames BorderLayout, i.e. only one component can be added to the center region, but don't know how to fix it. I have tried adding pacman and ghosts to EAST WEST etc but this didn't work.

I have also tried

maze.add(pacman);
add(pacman); //etc

but this didn't work either.

Sorry for the long post, any help is much appreciated. I can't post any code as the code is too long and spread over many classes.

Many thanks!

A: 

First: Repainting from multiple threads in Swing is a recipe for trouble. A better way is to update from the main game class and pass the Graphics object to all the actors to paint themselves (I'm sure there are other patterns, but I haven't done this sort of thing in a while).

Second: Your actors (pacman, ghosts) should not be JPanels. That's a recipe for even worse trouble. Make them extend an Actor class or something, but they should not be Swing components.

I realize that this doesn't directly answer your question, but some of your problems will go away if you design your game properly. There are a number of tutorials on game design out there on the web; I can't recommend any of them personally, but the first couple of chapters of Killer Game Programming in Java look promising.


Edit: All right, I'll try to address the actual question.

If you're using BorderLayout, the way to add multiple components is to specify the position:

setLayout(new BorderLayout());
add(maze, BorderLayout.CENTER);
add(pacman, BorderLayout.EAST);
add(ghostA, BorderLayout.WEST);

Alternatively (and maybe better), you could add the players to the maze:

setLayout(new BorderLayout());
maze.setLayout(new BorderLayout());
maze.add(pacman, BorderLayout.EAST);
maze.add(ghostA, BorderLayout.WEST);
add(maze, BorderLayout.CENTER);

Now while these ought to get all three components added to the frame, I still can't see how you could have a game where the player is a JPanel trying to escape JPanels.
Anyway, if they don't work, the next thing to do is to try a different layout manager.

Michael Myers
Many recipes for trouble in Swing aye :-)
Peter
Thanks for the reply, but this is for an assignment; thus I don't really have time to start redesigning my program - it is 2000 lines long altogether. What I really want to know is, can I make it work using what I have done so far? Both are displaying OK, just not at the same time - so given what I have described, is there a quick fix for this? Cheers
Rory
Had already tried those with no success. Nevermind, thanks anyway.
Rory
A: 

Are you adding these panels directly to the JFrame? If so, you should be adding them to the frame's content pane instead:

getContentPane().add(maze);
getContentPane().add(pacman);
getContentPane().add(ghostA);
you can add directly to a frame, that problem went away in Java5
basszero
A: 

FYI, mmyers is right. You will be fighting this design until the end and it will never work correctly. You're going about it the wrong way.

Let's start by working on some of these questions

  • How do you control the position/location of pacman and the ghost?
  • Are you setting the position of the jpanel or are you drawing at some x/y within the panel?
  • Do you expect all 3 panels to draw/render on top of each other?
  • Did you override paintComponent() in each JPanel to draw the pacman/ghost/maze?
  • What is the criteria of the homework assignment?
  • Does it have to be multithreaded?
basszero
@mmyers, thanks for the format update. I'm lazy
basszero
Pacman is controlled by arrow keys + a simple algorithm makes ghost move in random directionsIt has to be multithreaded - thats the whole point of the assignment. The maze is represented by a 2d array of Cell objects. Each image associated with a cell is drawn on the Maze Panel in the correct positionPacman and Ghosts move 32 pixels[1 cell position] each time they movepaintComponent() is overridden in each JPanel to draw the maze/ghost/pacman
Rory
A: 

Take a look at

Layered panels

or

StackLayout

l_39217_l
A: 

Hi,

Thanks for the replies everyone.

Kendrick - the StackLayout did the trick, thanks! Just need to improve the flickering a little and I'm done. Many thanks! Been trying to find a fix for this for days now.

Rory

Rory
Can you accept his answer then?
Michael Myers