Graphics Adventure type movement
BlitzMax Forums/BlitzMax Programming/Graphics Adventure type movement
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
Cool, thanks Warpy. That`s exactly what I was after and I understand it too :) Thanks for the other replies too. Jason. |
| ||
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. |
| ||
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. |
| ||
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 :-) |
| ||
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. |
| ||
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. |
| ||
@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. |
| ||
It would start at half speed. |
| ||
Cool, so forget everything I said. |