Graphics Adventure type movement

BlitzMax Forums/BlitzMax Programming/Graphics Adventure type movement

QuickSilva(Posted 2009) [#1]
I`m trying to create a movement similar to the old point and click type Graphic Adventures where you click on a point and your character walks over to it.

As I am not too hot with maths it is proving to be a little difficult. What I want ideally is to click on a point and my character walks over to it with a slight easing in at the end of the movement.

Can anyone give me any hints as to how this could be achieved with as little math as possible.

Thanks for any help,
Jason.


slenkar(Posted 2009) [#2]
will the characters have to negotiate the environment?

as in, will there ever be a table in the middle of the room for example?

If not the calculations arent that bad. If there is going to be stuff in the way you will need a set of nodes for pathfinding or a different kind of pathfinding system.


QuickSilva(Posted 2009) [#3]
No, there is nothing in the way. I just really need a straight a-b type movement with the easing in at the end.

Jason.


Grey Alien(Posted 2009) [#4]
So all you need to do is modify the top speed (diagonal speed) they can walk at when they get within a certain radius of the target. You can probably use Sine as a modifier to get a smoother slow down as the player approaches the target, but that may be overkill, get it working with a linear slow down first.


Warpy(Posted 2009) [#5]
nah, forget all that noise.


Try to move the character a fraction of the distance to his target every frame. This way, as he gets closer, he moves slower.

When he's really far away, though, he'll move quite quickly, so scale the distance moved down to a constant number if it's too fast.

E.g.:

Graphics 800,600,0
Global px#,py#,tx#,ty#	'character is at (px,py), wants to move to (tx,ty)

'start character in middle of screen
px=400
py=300
tx=400
ty=300

Const maxspeed#=2	'the fastest you want the character to move

While 1
	
	If MouseHit(1)	'left click changes where we want to move to
		tx=MouseX()
		ty=MouseY()
	EndIf
	
	'find the difference between where we are and where want to be
	dx#=tx-px
	dy#=ty-py
	
	'move at most a tenth of the distance during this frame
	dx:*.1
	dy:*.1
	
	If Sqr(dx*dx+dy*dy)>maxspeed	'if this movement is bigger than the maximum we want, scale it down
		scale#=maxspeed/Sqr(dx*dx+dy*dy)
		dx:*scale
		dy:*scale
	EndIf
	
	'move the character
	px:+dx
	py:+dy
	
	
	DrawOval px-2,py-2,4,4
	
	DrawRect tx-2,ty-2,4,4

	Flip
	Cls
	
	If KeyHit(KEY_ESCAPE) Or AppTerminate()
		End
	EndIf
Wend


I've tried to make it as maths-free as possible! Just copy this out and use it if you want.


QuickSilva(Posted 2009) [#6]
Cool, thanks Warpy. That`s exactly what I was after and I understand it too :) Thanks for the other replies too.

Jason.


xlsior(Posted 2009) [#7]
No actual code here, but just some ramblings: one thing to consider as well, is how to handle movement to a location that is NOT walkable.

A number of years ago I wrote some code for a point-and-click style adventure movement, and this is how I approached it:

- Create a low-resolution array as an overlay for the screen -- e.g. for a 640x480 screen, I had a 160x120 array, with each slot representing a 4x4 pixel chunk.
- I filled the array with either true or false for each 4x4 block, indicating whether or not the portion was awalkable. (Through a very basic editor where I could 'paint' the walking map on top of the actual background picture, and interprete the results to populate the array)
- Then use one of the A* pathfinding tools to actually plot the path.

- Determine if there is a path from A to B.
- If Yes: Start your walking routines, and traverse the path
- If No: envision a straight line from point A to point B. In ~32 pixel increments or so, traverse that line backwards from point B towards point A and try to find a path. Sooner or later you'll find a spot that's still reachable. At that point you can use use that as your destination: You can walk from point A to this spot, and stop there.
- Optionally, make a comment about how the spot you're trying to get to is out of reach.

As far as the overlay array, it's a bit of a trade-off: The larger the array is, the more precise your morements can be -- but the smaller it is, the less time is needed to calculate a walkable path. Try to find some middle ground there.

Certain evens (e.g. raising or lowering a drawbridge) would affect a portion of the map and by performing the action you can flip that portion of the walking array from true to false or vice-versa.
One advantage of a system like this v.s. using absolute waypoints is that you can walk 'anywhere' on the map.

And if you already have an array representing the entire screen, you can also use it to store other info, like adding a dimension to represent a scaling factor -- in certain screens representing large landscapes you may want to draw your character much smaller in the background than when he's right in the foreground.

You can also use a dimension to define 'trigger' spots, e.g. walking on a certain location may cause something else to happen.


Nate the Great(Posted 2009) [#8]
try a waypoint system for efficiency :) and yes with a modified waypoint system you can walk anywhere. it works like this

1. Find the nearest waypoint to the point clicked and go there
2. Use the waypoint system to get there
3. if you are closer to the point clicked than the waypoint stop within a radius of the point clicked if not move on.
4. if the above is not true then act as though the point clicked is now a waypoint and move strait there.


Grey Alien(Posted 2009) [#9]
Yeah I thought about using Warpy's method too but I didn't think it was cool having the character slowing down over the whole journey, I thought that having a constant speed and then a slow down at the end might look better. Of course capping the max speed as Warpy says should work too. But what if the distance is really small, what happens then? You'll get max (capped) speed for a fraction of a second and then it'll rapidly slow down as the target is reached. With my method you'd get a consistent speed and slow down nearer the target which I prefer. Not trying to say Warpy's method is wrong at all, just explaining my rationale a bit more, hope it's useful :-)


QuickSilva(Posted 2009) [#10]
Valid point. I`ll try to give your idea a try too Grey Alien and see which looks best.

Thanks for the help everyone,

Jason.


Warpy(Posted 2009) [#11]
Grey Alien, as far as I can tell my method's the same as your method - speed goes down linearly but is constant outside a certain radius. I just don't state the radius explicitly.


Grey Alien(Posted 2009) [#12]
@Warpy: I didn't check your code in detail so maybe it does do that. So if the radius is 20 and your player is 20 away from target, they would linearly decrease in speed from full to 0. However, with my suggestion, if the player was 10 away from the target they would start at half speed and decrease to 0. Is that what yours would do or would it start at full-speed and quickly decrease to 0? That's the point I was making.


Warpy(Posted 2009) [#13]
It would start at half speed.


Grey Alien(Posted 2009) [#14]
Cool, so forget everything I said.