asynchronous mover

Started by
5 comments, last by NotAYakk 15 years, 9 months ago
Hi Could you please help me understand how the following requirements could be fulfilled? 1.) I have a bunch of figures on my game map and I want to move them around. 2.) I only want to issue the movement order, and the figure will automatically start moving towards the designated destination - and I wnat this operation to be asynchronous - a fire and forget solution :) 3.) I want to be able to perform additional operations when the movement is started and once the destination is reached. An example of such an operation would be to display an arrow marking the movement destination once the movement order is issued, and hiding this arrow once the moving figure reaches the destination. 4.) The solution needs to be extensible in terms of these actions mentioned in pt 3. I've already tried several different approaches to this problem, and I always end up with a very crappy code. Can someone please help? Thanks a lot :) Paksas
Advertisement
Why not just store a function pointer or functor with your movement order, and call that function pointer / functor when the move order is complete? I'm assuming you already have the async movement part working (Since it's just a case of keeping track of each units target position and updating their current position each tick).
It's not that easy - I'm talking to the mover through an interface that only has one single method in it - move(Destination dest) - just as it's described in the requirement 2.




I tried a similar approach - to employ an Observer pattern to get notified about the figure reaching the destination.
Such a DestinationMarkerSubject would have a bunch of DestinationReachedObservers registered (each of these observers performing a particular command).


The problem with that solution was that I have a pair of behaviours - one executed when the movement order is issued, and its counterpart - executed when the destination is reached.

Now I want to keep their definition close - preferably in the same implementation.
So I want something like this:

class SomeMovementCycleRelatedCommand {
public:
void onMovementOrderIssued() {
doThis();
}

void onDestinationReached() {
doThat();
}
};

But it blows - since now I want to be able to receive 2 commmands from the context - and one of them is activated by the Observer context, and the other one - from the context that issues the movement commands.

Are the adornments part of the move order, or are they features of the thing doing the movement?
Assuming we're working with a relatively simple order structure, as is typical in almost all RTS games (a unit has one order at a time to work with, and might queue them), what you want is an order delegation mechanism.

Each figure on your map knows how to move itself small distances at appropriate speed. For instance, while a little whirligig can, on demand, move in any direction, a tank will have to turn to face the travel direction, and then accelerate up to speed appropriate for the terrain. But basically, your unit itself knows how to move some minor quanta of distance. At this level you will probably also have micronavigation, such as avoiding walls, circumnavigating small boulders, and not colliding with other units in the immediate vicinity.

You have an Order object type, which is on creation (or shortly after) given all the information the order needs. For a move order, the destination is the critical info in following the order.

When you give a figure an order, associate the two somehow. It doesn't matter, so long as given a unit you can find its current orders (if any) very inexpensively. A unit having a pointer to a one current order might be enough; a unit with a queue of orders might work. A unit who is a member of a squad, or each unit who was selected when giving a single order, might all share a single order queue, so that changes to the orders affect all the units in the squad.

Each simulation tick, go through a list of units who have orders, and tell their order to do its duty, passing the unit it is assigned to for reference. The order can then do one of several things; it can perform the next possible action in the order, such as firing or using a weapon, pathfinding and then giving a new general heading, doing some work in the immediate vicinity, or cancelling the order because the target is invalid (unit to attack is dead or out of sight) or the unit attached is invalid (path cannot be found, unit is not a harvester, etc).
RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.
>> NotAYakk wrote:
>> ----------------
>> Are the adornments part of the move order, or are they features of the
>> thing doing the movement?

They are just a part of the movement order. There may be different adornments for different types of figures - I want to be able to see where the player I'm navigating is going to for instance, so I want some kind of a marker set on the ground. But I don't want the same to be done for the figures navigated by other players or the AI.

>> Wyrframe wrote:
>> ----------------
>> Assuming we're working with a relatively simple order structure, as is
>> typical in almost all RTS games (a unit has one order at a time to work
>> with, and might queue them), what you want is an order delegation mechanism.
>>
>> Each figure on your map knows how to move itself small distances at
>> appropriate speed. For instance, while a little whirligig can, on demand,
>> move in any direction, a tank will have to turn to face the travel
>> direction, and then accelerate up to speed appropriate for the terrain. But
>> basically, your unit itself knows how to move some minor quanta of distance.
>> At this level you will probably also have micronavigation, such as avoiding
>> walls, circumnavigating small boulders, and not colliding with other units
>> in the immediate vicinity.

That's a great idea - thank you so much :)

So far I had my figures representing an abstraction of a doll with a few "buttons" on it - meaning that you could put it somewhere on the map, rotate it around, "push a button" so that it starts a different animation sequence - that's it.
Then I used a completely separate Micro-Movement abstraction that took such an inanimate figure and told it how to move - I could stuff it with the different movement scenarios (the ones that you mention - a tank needs to rotate before it moves, which a soldier doesn't really need to do as long as he's not u-turning).
I didn't have the order structure. Instead - this "Micro Movemement" object could have been set with different sets of commands that would do some "additional" actions.


And I thought the responsibilities are well separated, but it kinda bugged me that when I'm creating a new figure, I also have to come up with a different movement strategy and place it in a different class.

My point is - if I understood correctly, you suggest combining the "micro movement" abstraction with the figure abstraction - combine the two interfaces and make a figure know how to do the micro movements?
If the movement adornments are a feature of the movement order, then they should be bundled with the movement order.

If, for example, the order got cancelled -- then the adornments would also be cancelled.

"I'm talking to the mover through an interface that only has one single method in it - move(Destination dest) - just as it's described in the requirement 2."

If your interface doesn't match your needs, is the interface holy or something? :-)

This topic is closed to new replies.

Advertisement