Help with custom space-type movement and speed limiting

For questions about using Classic.

Post » Tue Dec 04, 2007 12:08 pm

Hi, I'm making a little movement engine, it's LOTS of events so I've made a tiny little example that has the basic (and i mean basic) fundaments of how I will be moving the player/objects.
So far everything is running ok, I even found a way (although somewhat crude) to find the angle of the any wall to calculate a way to bounce off it corrctly, but there is ONE main thing stopping me from really developing this much further and that is, I can't get it to stop accelerating beyond a certain point. That is to say, if I hold up for example, the player will just keep getting faster.
I'm pretty rubbish at most maths, and i've spent many hours just trying to fix this problem...
I've tried lots of things and most of them, if they even work result in usually one of two things, I -can- get it to stop accelerating once a certain speed is reached BUT after that point I am unable to move in any other direction,
OR
I can move in any direction again but it's not realistic looking, as in moving diagonally will actually move faster than moving up/down or left/right, also when turning whilst moving forward, the player moves in more of an octogon type shape.

Any help with limiting the speed (and some nice accel/deceleration code would be nice too :) ) while still maintaining control would be VERY helpful :D

To fully understand what I'm raving about, here's the link to the reduced version
(you don't really want the big one I'm working on, way too confusing for now I just want this movement thing sorted)
http://www.fileshack.us/get_file.php?id ... ntdemo.cap

Oh one more thing, I don't -really- wanna make it use the built-in movement types, I know it may be a little counter-productive on my part but I really wanna know how to actually do this myself. Plus I like custom movements more anyway ;)
Anyway PLEASE help if you can! yay
bye
B
3
S
2
G
5
Posts: 351
Reputation: 2,377

Post » Tue Dec 04, 2007 9:17 pm

I read that really quickly, but one "hacky" kind of way i found in setting a maximum speed is like this-

When speed is greater than "maxspeed"
- Set speed (or xvector, yvector, however you made it) to speed *0.98

This way, when it gets above max speed, it will take down the speed slightly.

Not sure if this is what you were looking for, if not, I'll look a little closer.
Theres probably a better way to do this as well XD
B
2
S
2
G
5
Posts: 448
Reputation: 2,546

Post » Wed Dec 05, 2007 3:21 am

I've been thinking about going down that road, however, due to the nature of how I'm doing it, I can't actually SET the speed in a specific direction by using a speed variable, I can only -retreive- the speed and that's by using the system event distance between points, by using a LastX and LastY variable.
In any case I suppose I might be able to work around it by taking whatever offset is in my MoveX and MoveY variables and multiplying it by something like 0.98
Thanks for your input, if anyone else has any other ideas I'd still love to hear em! :D
B
3
S
2
G
5
Posts: 351
Reputation: 2,377

Post » Thu Dec 06, 2007 1:07 am

The theory behind this is that your MoveX and MoveY values are the change in the X and Y position every frame. If you make a triangle of width MoveX and height MoveY, the hypotenuse is the speed. As you've worked out, you can get the speed by pythagoras, i.e.
sqrt('MoveX' ^ 2 + 'MoveY' ^ 2)

So now you can make an event which runs when the speed is too high, using Compare Values:
sqrt(Player('MoveX') ^ 2 + Player('MoveY') ^ 2)
greater than
0.5 (or whatever maximum speed you want).

Now all you want to do in this event is set the speed to your maximum speed, i.e. the hypotenuse must be 0.5. So all you have to do is work out what the values for MoveX and MoveY are for a triangle of hypotenuse 0.5 at the current angle. So add these actions:

Set MoveX to 0.5 * cos(.Angle)
Set MoveY to 0.5 * sin(.Angle)

And there you have it, whenever your speed goes above 0.5, it's adjusted to exactly 0.5.

Unfortunately, this doesn't work. I found a bug in Construct while doing this :P

To work around it, you need to adjust the Compare Values condition to eliminate the square root. You can easily do this by squaring both sides of the equation, eg:
sqrt(Player('MoveX') ^ 2 + Player('MoveY') ^ 2) > 0.5
becomes
Player('MoveX') ^ 2 + Player('MoveY') ^ 2 > 0.25

Why it doesn't work I'm not particularly sure and need to debug it at some point, but I guess SOMEHOW it's trying to square root a negative number, which is mathematically impossible, and shouldn't be possible in this case because both the values passed to it are squared. Weird, I'll look in to it.

Anyways, hope that helps :)

Edit: one more thing, with custom movements you really should have some TimeDelta expressions in there somewhere. Otherwise if yuo V-sync it people with different refresh rates will have it run at different speeds. If MoveX and MoveY are in values of pixels per second, and you adjust the Player's X and Y coordinates as such:
.X + 'MoveX' * TimeDelta
.Y + 'MoveY' * TimeDelta
then you will avoid this problem, and it will run the same speed for everyone.
Scirra Founder
B
359
S
214
G
72
Posts: 22,952
Reputation: 178,580

Post » Thu Dec 06, 2007 2:15 am

pythagoras! of course! If you had told me in highschool that I would find an actual USE for trigonomerty AND pythagoras I would have laughed in your face
I was just trying to find an accurate speed reading!
Thanks heaps ash, also I didn't know about that timedelta thing, i'll implement it in too
B
3
S
2
G
5
Posts: 351
Reputation: 2,377

Post » Thu Dec 06, 2007 2:40 am

ok i tried it like this, I made the variable 'Speed' always set to sqrt(MoveX ^ 2 + MoveY ^ 2) that way I can just say like, if 'speed' > than 20
but if i go into any directions where cos or sin return negative values, i get a speed reading of -1.#IND and my object just floats along at whatever tragectory it was at

Also as i'm not much of a brain, I'm still a little confused about the Player('MoveX') ^ 2 + Player('MoveY') ^ 2 > 0.25 thing you mentioned, would that fix the problem I have at the moment?
B
3
S
2
G
5
Posts: 351
Reputation: 2,377

Post » Thu Dec 06, 2007 3:59 am

Yeah, the -1.#IND is the square root bug.

To get around it you could set Speed to just:
'MoveX' ^ 2 + 'MoveY' ^ 2
You can still compare it to speeds, but you have to square the speed you compare it to because you got rid of the square root. So you'd say greater than 400 instead of greater than 20.
This is because you've squared both sides of the equation, consider:
sqrt(a) > b
square both sides:
sqrt(a)^2 > b^2
this cancels the square root and you're left with:
a > b^2
it's actually an optimisation at a programming language level, the RTS movement uses it for faster range detection :P square roots are computationally expensive, and if you're doing a lot of them, squaring both sides of the equation makes it just some quick multiply commands.
Still, not worth it in Construct because the event overheads make it about a 0.01% saving :)
Scirra Founder
B
359
S
214
G
72
Posts: 22,952
Reputation: 178,580


Return to Help & Support using Construct Classic

Who is online

Users browsing this forum: No registered users and 1 guest