Set a delay before another statement is executed
Hi,
I've already looked on the internet but found nothing really suitable or I don't understand.
Here's the deal:
I have a maze, with a hero and monsters in it.
When it's the monsters turn to move I call this function:
publicvoid zombieMove()
{
List <Point> path =new ArrayList<Point>();
for (Char c : game.getCharList())
{
game.setCurrentzombie(c);
path = game.findPath(this);
for(Point p : path)
{
game.setZombiePos(p);
repaint();
}
}
}
I used the A-star algorithm for the monsters to move, the findpath function returns a List<Point> with al the points the monster needs to move to. A monster is an object of the 'Char' class. On start of the game a list of monsters is created, and you can always access this list by sending a request to my domain controller (game.getCharList() ).
This works.
What I want: I want to see the monster move to its end position, so actually I need something like a delay after the repaint() method is used.
What i've already tied (without success):
//>> end part of the method
game.setZombiePos(p);
repaint();
try{
Thread.currentThread().sleep(200);
}catch (InterruptedException e){
e.printStackTrace();
}
// After this the "for(Point p : path) loop" is executed again if there are point objects left.
This sleep thing doesn't really work well for this. When it' s the monsters turn, 200 ms (it looks longer) are passed and bang!, all the monsters are at a new position in one time and I didnt( see them move.
Could someone help me out with this?
Greetz Daan
EDIT:
Another question, how can I award people with these so called 'duke stars' when they found a solution.
[2455 byte] By [
D-a-a-na] at [2007-11-27 5:07:03]

I don't have the book with me that I need at the moment, but my advice is to simplify your problem with a small prototype. Build a small maze with nothing in it but one monster. Have the monster walk around the maze and fiddle with it until you get the results you want. I would have to make some guesses as to your graphical implementation before I could get any more specific. Someone else may have some insight that I don't.
PS.
Ok, I made the maze smaller with only one monster in it. The same happens, I can't see the monster moving.Greetz Daan
I guess what you need is to create a Timer, and move the monsters in response to your Timer's events.
This will allow the user to interact with your program in between the monster moves.
If you want the monsters to move without any possible user interaction, then you could read the current time, run an empty loop until your time laps has passed, and go on with the next monster move again. Here's a quick pseudo-code:
while monsters need to move
move the monsters one step
myTimeSnapshot = get the current time in milliseconds()
while myTimeSnapshot + 200ms < get the current time in milliseconds()
do nothing
Normally the first method should be preferable, as it is more user-friendly.
You need a different thread to see the movement. Your display/repaint happens after the last step of the monster.
'nother question. Is your game turn based or real time based?PS.
> You need a different thread to see the movement. Your
> display/repaint happens after the last step of the
> monster.
So it seems,
in order to manage the repaint() in need something like a repainttThread() ?
Could you tell me roughly how to do this?
Greetz Daan
> 'nother question. Is your game turn based or real> time based?> > PS.Turn based.
Read the tutorials first: http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html http://java.sun.com/docs/books/tutorial/uiswing/concurrency/index.html
Ok, after you read the tutorials that PhHein recommended (good reading by the way) consider this. A turn is not a thing unto itself. A turn is the culmination of all of the events that go into it. To show all of those events you need to semantically break down to the turn into a more granular number of segments. Each of the things that happens in each segment/turn should be going on in its own thread and each thread needs to update the ui with its current state or whatever every segment and the ui needs to update every segment with the new information.
There are a number of ways to get there so I can't give you a "write it this way" answer. What I can tell you is that my foray into 2D Java development of this type was turn based and I approached it from this standpoint and it worked very well. Things are a bit more complicated in a real time situation.
PS.
I'm still kinda stuck actually,I'm sorry but I can't really find what I'm looking for.
I already made a runnable class
class RepaintThread implements Runnable
{
public void run()
{
repaint();
try
{
Thread.currentThread().sleep(100);
System.out.print(Thread.currentThread().getName());
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
and did this in my for loop:
for(Point p : path)
{
game.setZombiePos(p);
System.out.print(Thread.currentThread().getName());
repaintThread.run();
try {
repaintThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
But that doesn't really changes anything, what I need is something like a force repaint method. The repaint only happens on the last modifying of the monsters coordinates. I want it to repaint every single time in the for loop and not just at the end.
I searched the net and found that i'm not the first struggling this problem:
http://www.velocityreviews.com/forums/t136844-how-to-force-gui-updates.html
http://www.programmersheaven.com/mb/java/335878/335878/readmessage.aspx
You'll want to call start() on a thread rather than run(). Otherwise, you'll just directly execute the run() function in the current thread, effectively defeating the purpose of creating a thread :).
http://java.sun.com/docs/books/tutorial/essential/concurrency/runthread.html
By the way... have you seen Swing Timers?
http://java.sun.com/docs/books/tutorial/uiswing/misc/timer.html
Calling repaint() where you are would repaint the RepaintThread, not the ui element. You might try passing a reference to the component that the RepaintThread is controlling and call repaint on that component instead. Say for example that your ui component is actually a JPanel that you're moving around in a container. Pass a reference to the JPanel or the container (try one then the other) into the constructor for RepaintThread and call its repaint instead of the Thread's repaint.
This is of course assuming that RepaintThread is not the component itself in which case boy have you badly named things. :)
PS.