rotation/direction

BlitzPlus Forums/BlitzPlus Beginners Area/rotation/direction

Amiga(Posted 2006) [#1]
Hi blitzcoders, can some one help me with an "rotation, direction" question.
Let's say i have created some 8, 16 or 36 or whatever rotated images(that part i allready understand). I need to know how to get the correct direction (the correct image out of, for example "36" images), when i got an angle from then mouse position or another object.
I know how to get the angle ( Atan2(y1-y2,x1-x2)) and the distance ,TotalDist# = Sqr#((XDist# * XDist#) + (YDist * YDist)). There is an example of it in the book "Learn to Program 2D games in Blitz Basic", but that function i so complex with "hundreds of variables ;)".
I only want to get an correct "direction number" out of an angle.
It should work with an Static object or an moving object, the moving part i should try to fix myself.


Grey Alien(Posted 2006) [#2]
Get the angle and make sure it's in the range 0-359, the divide it by 360 (same principle applies if you are using radians, just the range is 0 - 2*PI). This will give you a number in the range 0-0.999999. Then multiply this number by the number of frames you are using e.g. 36. This will give you a frame number from 0 to 35. You may want to work out how to round it properly so that a frame number result of <.5 goes to the lower frame and >= 0.5 goes to the higher frame. Hope this makes sense.


Amiga(Posted 2006) [#3]
Hi Grey Alien! thanks for your reply.
Ehh could you show me the code for this, please :).
I measure the angle between the mouse position and an object with atan2(my-y,mx-x), that's the only way i know it. That gives me an angle between -180 and 180, and every attempt in making an solution ends with an scream.

Too learn an programming language is not so hard, the difficulties is in all the other stuff ;).


Grey Alien(Posted 2006) [#4]
Try this, I haven't tested it:

Const ANIM_FRAMES = 36
angle# = ATan2(my-y,mx-x) + 180 ;makes it in the range >0 to 360
unit# = angle#/360 ;get in the range >0 to 1 as a float
finalframe% = Ceil(unit*ANIM_FRAMES)-1 ;round up and subtract 1 to get in range 0 to ANIM_FRAMES-1


note that it's not ideal as the first frame will be shown for degrees 0 to 10 instead of -5 to 5 and so on. See if you can figure out how to make it more accurate ;-)


Amiga(Posted 2006) [#5]
Super thanks, Grey Alien

I have not figured it out how to make it correct, would you mind helping me??
I hope you have the strength with me.
Here is what i achieved so far...well the images is a problem. Look in the Function "UpdateTank1(t.Tank)" there the problem is ???.




Grey Alien(Posted 2006) [#6]
Sorry I've been a bit busy and literally can't find the time to look at it right now, hopefully soon...


Amiga(Posted 2006) [#7]
You have been very helpful Grey Alien, you don't have to help me, i have to figure it out myself.
"Cudgel one's brains" ;). But don't be suprised if have the same question again, on this forum :).
....... I hope my english is readable.


Grey Alien(Posted 2006) [#8]
Your English is fine. When you call CreateTank you don't need .Tank after the function name. .Tank is only needed in the function declaration. So you can do this:

Global tTank1.Tank = CreateTank(True,200,200)
It saves typing.

Anyway, to get frame 0 for angle -5 to 5 (where 0 is at the top, like a clock), we need to add on half of the number of "degrees per frame". 360/ANIM_FRAMES = degrees per frame. Then if the number is greater than 360, we have to keep it in the range 0 to 360, so we need to subtract 360 from it e.g. 362 changes to 362-360=2 degrees i.e. the first frame!

Adjusting my original code looks like this:

Const ANIM_FRAMES = 36
angle# = ATan2(my-y,mx-x) + 180 ;makes it in the range >0 to 360
;add on half the degrees per frame for accuracy
angle = angle + (360/ANIMFRAMES)/2
;Is angle too large now?
If angle > 360 then angle=angle-360
unit# = angle#/360 ;get in the range >0 to 1 as a float
finalframe% = Ceil(unit*ANIM_FRAMES)-1 ;round up and subtract 1 to get in range 0 to ANIM_FRAMES-1

And that's it I think. This is untested so I hope it works. Good luck.


iaqsuk(Posted 2012) [#9]
Hi Amiga & Grey Allen or anyone interested, I know this is a very old script, but for a beginner, it is still useful to start off with. The above script can be very useful for character movements for a tank or car or even a heilcopter if thats the game your creating for a topdown view game.

It sure is way better then a loadanimimage with frames like a person walking. For those who have BlitzMax, I did find another script similar to above code in BlitzMax thanks to TomToad. Here is the link: http://www.blitzbasic.com/Community/posts.php?topic=91640 . I updated the script also making it go in reverse in BlitzMax. See my comments as well.

I also updated the above script to make the car or tank go in reverse for more practical usage if its a car or tank or whatever. Great script. However, I was trying to make the tank or car go faster and couldnt figure it out. I tried to add a global speed = # but it didn't work, it just made the car go diagonal faster. If anyone wants to help. Thanks.


andy_mc(Posted 2012) [#10]
this might help too.

It's the source code for a simple overhead tank game I started writing a while back.

https://dl.dropbox.com/u/8673694/You%20Tube%20Files/Blitz3D/360_Degree_movement.zip


iaqsuk(Posted 2012) [#11]
Hi andy_mc, thanks for the reply. I know this is a really old script, but for a beginner its a wealth of information. I downloaded your sample script and it's a another great script for beginners. However, it's another loadanimimage character type movement.

I was referring to the above post #5 by Amiga script and how to add more speed to his tank. It only has ONE Speed going forward. I've been looking on his script over and over and testing and testing by putting other numbers and adding speed = # to it to make the forward speed faster or slower but I can't figure it out. Your script would of worked and I do understand loadanimimages and making the speed faster, but Amiga's script is different.

The only place I see the speed is in:
t\x# = t\x# + (fXSinTable#(t\rot)); * Speed)
t\y# = t\y# + (fYCosTable#(t\rot)); * Speed)

and possible the default speed is (fXSin & CosTable#. I was thinking of adding another Dim fX & Y Sin & Cos Table AND (ispeed). not sure if that will work though. If you can help or anyone. Thanks.