0

I'm doing a path-finding project as part of my 4th year software engineering degree. We're suppose to give visual representation to a bunch of multi-agent pathfinding algorithm. The simplest one is A* adapted for multiagents.

Anyway our environment is a grid map where every cell can be either blocked or used as part of an agent's path. What I want to do is use animation to give a good representation of the final movement of the agent, but animating color change in my grid. I.E paint every step in the path for a second or so with some color to show how the agent moves.

And the other thing I want to do is to represent the way the algorithm works by painting the changes in the open list and closed list of the A* algorithm while its doing its calculation.

I'm using an adapted version of the observer design pattern to send events from my algorithm layer to my controller and GUI layer. What I want to do in the GUI layer is every time a tile is added to the open list, I want to have that cell painted in some color and then have it fade away according to a predefined timer or maybe later add a slider to control this timer.

I looked at the code here. It seems pretty simple, the problem is that every tile animation has to be independent of the others to allow the algorithm and everything to keep running and different animations to start.

So what's the best way to achieve the results I'm looking for? Should I just open a different thread for each animation or have a pre-made thread for each cell? Would that be an overkill for the application, since there can be up to 1000 cells and therefore close to 1000 threads performing animation.

Another issue I think I might encounter is the fact that it might happen that a cell will start its color fading animation and then will have to restart and I don't want the two animations to go at the same time (only one thread performing animation for the same cell at the same time).

I hope I was clear enough with what I'm trying to achieve, if someone has any ideas or thought it could really help me with my project.

jessehouwing
  • 106,458
  • 22
  • 256
  • 341
Amit Ofer
  • 413
  • 1
  • 7
  • 26
  • "I hope I was clear enough with what I'm trying to achieve,.." It is only now after 10 minutes of editing, that I can even understand that mess of letters you posted. So - no. Someone in the 4th year of a technical degree should be able to find their shift key and apply it once at the start of every sentence, and for every use of the word 'I'. It also does not help to use slang words like *wanna*. These are international forums and many people will not understand the term. Those that do will consider you to be goofy, and unworthy of their attention & time. Please take more care. – Andrew Thompson Mar 26 '11 at 12:31

3 Answers3

2

You can find Trident animation library useful. More information at http://kenai.com/projects/trident/pages/Home

Eugene Ryzhikov
  • 17,131
  • 3
  • 38
  • 60
  • seems like a cool library, how does it handle many animations happening at the same time? will it be efficient? looks as if i have to create one of these timeline objects to every cell, wouldn't it by like creating a thread per cell? thanks – Amit Ofer Mar 26 '11 at 14:54
  • The Trident is very efficient. Check out Kirill's blog: http://www.pushing-pixels.org/2009/06/23/trident-part-5-supporting-ui-toolkits.html – Eugene Ryzhikov Mar 26 '11 at 16:57
1

I would consider a scenario with a single animation thread only. You might e.g. try the following strategy:

  • standard event thread for swing events
  • one worker thread for your logic
  • only one additional for all animations

This third thread manages all animation within your gui. Therefore it maintains a list of animation actions to perform together with their timestamp. Such an action can be e.g. "set color of cell [1,2] to CF0000 @ 17:01:00" in an approriate data structure. This list of actions is then filled by the worker thread with the animation actions (e.g. you may add several actions at once for a fading cell - 1) set to 100% @ now; 2) set to 75% @ now+10s; 3) set to 50% @ now+20s ...). Make sure that this list is properly synchronized since it will be accessed from both threads.

If you keep this list sorted by timestamp it is quite easy to determine the which actions this thread has to do at any time. This thread has then a quite simple loop, e.g. something like

while(true) {
    AnimationAction action = list.get(0);
    if(action!=null && action.timestamp <= now()) {
            action.perform(); // <= be sure that paint events occur in the edt
        list.remove(0);
        continue;
    }
    sleep(...);
}

Note that you can determine the time to sleep from the timestamp of the next action but consider that a new animation event arriving might have to interrupt this. Otherwise you can also sleep for some short amount of time.

Regarding your second question this thread might remove any actions from this list on demand for a special cell if a new action arrives. Therefore you might also maintain a secondary data structure in order to do this efficiently.

Howard
  • 38,639
  • 9
  • 64
  • 83
  • thanks, that sort of what i had in mind, what i'm not sure is how to tell the animationManager thread to how much time it needs to sleep, since every change can occur in a different moment in time.The thread should probably stay alive at all time or somehow manage to wake up the next animation in queue needs to change. maybe i need to use a mechanism that is close to what happens in games, that everytime the thread wakes up it checks against the last time it performed his action and then calculates the color value chnage according to the elapsed time, is this necessary? thanks – Amit Ofer Mar 26 '11 at 16:44
  • @Amit As mentioned in my answer you may either sleep a fixed amount of time (e.g. something around 50 to 100 ms should be ok for any kind of fading animation) or just by the time span action.timestamp-now(). In latter case be sure to handle the case that a new action is arriving which has to be scheduled before and interrupt the sleep in that case. If you want to handle it the other way you suggest in your comment you have a different situation. You then have to manage all "ongoing" fadings and reprocess each of them according to the time span expired. – Howard Mar 26 '11 at 16:55
  • +1 Just be sure to perform all drawing on the [event dispatch thread](http://download.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html). – trashgod Mar 26 '11 at 17:01
  • ok thanks, one more question where did u get the AnimationAction class from? – Amit Ofer Mar 26 '11 at 20:01
1

I'd use javax.swing.Timer and AlphaComposite, as demonstrated here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045