Page 1 of 1
Needing to know the angle
Posted: Wed Sep 23, 2009 10:26 pm
by abystus
I'm needing a way to get the angle of a sprite manipulated by RotateSpride3d. In the syntax RotateSprite3D(#Sprite3D, Angle, Mode) we feed it a modifier to the angle which in turn rotates our sprite thus changing the angle by our given amount. However I have not found a way to pull the angle from the sprite once it is set other than storing my changes in a variable given in the example below:
Code: Select all
If KeyboardPushed(#PB_Key_Left)
If ShipAngle.F < 0
ShipAngle.F = 360 - ShipAngle
Else
ShipAngle.F - 7
EndIf
RotateSprite3D(1, -7, 1)
EndIf
If KeyboardPushed(#PB_Key_Right)
If ShipAngle.F > 360
ShipAngle.F = ShipAngle - 360
Else
ShipAngle.F + 7
EndIf
RotateSprite3D(1, 7, 1)
EndIf
Hopefully there is a way to grab the angle that we are modifying on the sprite that I have just looked over. Any help is appreciated.
- Abystus
Re: Needing to know the angle
Posted: Thu Sep 24, 2009 12:14 am
by Kaeru Gaman
no.
the only useful way is to store it in a variable, and rotate the sprite absolute each rotation.
relative rotation is not useful.
Re: Needing to know the angle
Posted: Thu Sep 24, 2009 12:40 am
by Demivec
If you are asking if the sprite keeps track of how much it is rotated, the answer is no.
As Kaeru mentioned it is better to rotate the sprite an absolute amount than to make several partial rotations. If the sprite was rotated partially I think the approximations (errors) in each rotation would add up and the end result wouldn't be as accurate (or desirable).
Re: Needing to know the angle
Posted: Thu Sep 24, 2009 1:30 am
by Kaeru Gaman
the sprite has to keep track of it's recent rotation someway, it should be a property within the Sprite3D struct.
but accessing and using this would mean "hacking of internals".
there is no guarantee that the value will be stored in the identical position in future versions.
the relative rotation flag is made for not restoring the sprite after zooming, so you can zoom and rotate the sprite.
the normal approach would be to create an object structure on your own that keeps position, rotation, (zoom if needed) and recent animation frame, and use an "instance" of this for each of your game objects.
when displaying, you would use absolute rotation, or reset-zoom-relative rotation when you zoom your sprite.
Re: Needing to know the angle
Posted: Thu Sep 24, 2009 1:53 am
by abystus
Long story short I'm needing this "Angle" for the equation below to work correctly (it almost does now, but using my current method of keeping the angle value becomes inaccurate shortly after doing a few turns):
Code: Select all
If KeyboardPushed(#PB_Key_Up)
radians.d = ShipAngle*#PI/180
PosX = PosX + ShipSpeed *Cos(radians.d)
PosY = PosY + ShipSpeed *Sin(radians.d)
EndIf
the only useful way is to store it in a variable, and rotate the sprite absolute each rotation.
relative rotation is not useful.
As Kaeru mentioned it is better to rotate the sprite an absolute amount than to make several partial rotations. If the sprite was rotated partially I think the approximations (errors) in each rotation would add up and the end result wouldn't be as accurate (or desirable).
So everyone seems to agree that Absolute Rotation is better than Relative Rotation. What would be the best way to convert the following routine to use Absolute Rotation instead?
Code: Select all
If KeyboardPushed(#PB_Key_Left)
If ShipAngle.F < 0
ShipAngle.F = 360 - ShipAngle
Else
ShipAngle.F - 7
EndIf
RotateSprite3D(1, -7, 1)
EndIf
If KeyboardPushed(#PB_Key_Right)
If ShipAngle.F > 360
ShipAngle.F = ShipAngle - 360
Else
ShipAngle.F + 7
EndIf
RotateSprite3D(1, 7, 1)
EndIf
Also please pardon me for my lack of knowledge in the area as it is my first game and will be my first time using Absolute Rotation. Also thank you both for the quick replies.
Re: Needing to know the angle
Posted: Thu Sep 24, 2009 2:10 am
by Kaeru Gaman
... you need the type extension only in the first line where you
Define the variable.
Re: Needing to know the angle
Posted: Thu Sep 24, 2009 2:45 am
by abystus
RotateSprite3D(1, ShipAngle, 0)
Ok I tried this method out however either my starting angle is off (set to 270 by default as i assume east is 0) or my angle is not calculating correctly. Below is the full source try out and possibly explain visually more of what I'm working with: (Use any 2 .png files for missle.png and blobship_1-1.png )
Code: Select all
InitKeyboard() : InitSprite() : InitSound() : InitMouse() : InitSprite3D()
;Bomb Struct
Structure Bomb
X.F
Y.F
TX.F
TY.F
SpeedY.L
SpeedX.L
SpriteNum.L
Delay.L
T.F
EndStructure
Dim MyFriends.Bomb(200)
win_id1 = OpenWindow(#PB_Any,#PB_Default,#PB_Default,1280,768,"Bomb Dodge",#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(win_id1),0,0,1280,768,0,0,0)
UsePNGImageDecoder()
LoadSprite(1, "images\blobship_1-1.png",#PB_Sprite_Texture)
TransparentSpriteColor(1, RGB(4,4,4))
CreateSprite3D(1, 1)
;Reset Game
begin:
;Variables
Health = 100
Points = 0
Release = 0
ReleaseCounter = 0
Test = 0
Pause = 0
PosX = 640
PosY = 700
ShipSpeed = 7
ShipAngle.F = 270
;LoadSound(1, "Sounds\Music.wav")
;PlaySound(1)
For a = 2 To 200
result = LoadSprite(a, "images\missle.png")
MyFriends(a)\X = Random(1000) + 1
MyFriends(a)\Y = - Random(50) + -1000
MyFriends(a)\TX = 0
MyFriends(a)\TY = 0
MyFriends(a)\SpeedY = 3
MyFriends(a)\SpeedX = 3
MyFriends(a)\Delay = 0
MyFriends(a)\SpriteNum = a
MyFriends(a)\T = 0
TransparentSpriteColor(a, RGB(4,4,4))
Next
CreateImage(0, 300, 200)
Repeat
event = WaitWindowEvent()
ExamineMouse()
ExamineKeyboard()
;Pause
If KeyboardReleased(#PB_Key_P)
Pause = Pause ! 1
EndIf
;Controls
If KeyboardPushed(#PB_Key_Up)
radians.d = ShipAngle*#PI/180
PosX = PosX + ShipSpeed *Cos(radians)
PosY = PosY + ShipSpeed *Sin(radians)
EndIf
If KeyboardPushed(#PB_Key_Down)
PosY + ShipSpeed
EndIf
If KeyboardPushed(#PB_Key_Left)
If ShipAngle < 0
ShipAngle = 360 - ShipAngle
Else
ShipAngle - 7
EndIf
RotateSprite3D(1, ShipAngle, 0)
EndIf
If KeyboardPushed(#PB_Key_Right)
If ShipAngle > 360
ShipAngle = ShipAngle - 360
Else
ShipAngle + 7
EndIf
RotateSprite3D(1, ShipAngle, 0)
EndIf
Debug ShipAngle
;Check for Pause
If Pause = 0
ClearScreen(RGB(0,0,0))
ReleaseCounter + 1
;Delay Release of Bomb
If ReleaseCounter = 45
release = Random(200)
If release >= 2
MyFriends(release)\Delay = 1
EndIf
ReleaseCounter = 0
EndIf
;If Bomb Delay is Set Non Active Release
For c = 2 To 200
If MyFriends(c)\Delay = 1
Corner = Random(2)
If MyFriends(c)\Y < -20 And MyFriends(c)\Y > -40
Select Corner
Case 1
MyFriends(c)\Y = 0
MyFriends(c)\X = 0
MyFriends(c)\SpeedX = 3
MyFriends(c)\TX = PosX
MyFriends(c)\TY = PosY
Case 2
MyFriends(c)\Y = 0
MyFriends(c)\X = 1280
MyFriends(c)\SpeedX = 3
MyFriends(c)\TX = PosX
MyFriends(c)\TY = PosY
EndSelect
EndIf
EndIf
Next
;Points Generator
Points + 1
;Calculate Path of bombs to current position
For x = 2 To 200
If MyFriends(x)\Delay = 1
MyFriends(x)\T + 0.0001
MyFriends(x)\X = MyFriends(x)\X + (MyFriends(x)\TX - MyFriends(x)\X) * MyFriends(x)\T
MyFriends(x)\Y = MyFriends(x)\Y + (MyFriends(x)\TY - MyFriends(x)\Y) * MyFriends(x)\T
;Ship Collision with bombs
If SpriteCollision(1, PosX, PosY, x, MyFriends(x)\X, MyFriends(x)\Y)
Health - 1
MyFriends(x)\Delay = 0
MyFriends(x)\Y = -50
MyFriends(x)\X = 100
MyFriends(x)\T = 0
EndIf
EndIf
Next
;Display Active Bombs
For a = 2 To 200
If MyFriends(a)\Delay = 1
DisplayTransparentSprite(a ,MyFriends(a)\X , MyFriends(a)\Y)
EndIf
Next
;If health is 0 restart
If Health < 0
Goto begin
EndIf
Start3D()
DisplaySprite3D(1, PosX, PosY)
Stop3D()
If StartDrawing(ScreenOutput())
DrawingMode(#PB_2DDrawing_Transparent)
BackColor(RGB(0,155,155))
FrontColor(RGB(255,255,255))
DrawText(5, 5,"Health: " + Str(Health))
DrawText(5, 20,"Points: " + Str(Points))
StopDrawing()
EndIf
EndIf
FlipBuffers(2)
Until KeyboardPushed(#PB_Key_Escape) Or event = #PB_Event_CloseWindow
End
Sorry about the extra types on my variables, I was previously informed it was the correct way. I think I was able to remove the majority from my code. Thanks again for taking the time to give me a hand with getting this ship to move the way its facing.
Re: Needing to know the angle
Posted: Thu Sep 24, 2009 4:20 am
by abystus
Ok great news... I initialized the angle I set in the definition of ShipAngle by placing a RotateSprite3D(1, ShipAngle, 0) on the next line under it, then i flipped the image to point to the 0 angle (east) instead of the 270 angle (North) and now it works fine

. I want to thank both of you (Kaeru Gaman, Demivec) for your input in helping me resolve this problem in a timely manner.
Re: Needing to know the angle
Posted: Thu Sep 24, 2009 8:40 am
by Trond
0 angle (east) instead of the 270 angle (North)
270 is south.
Re: Needing to know the angle
Posted: Thu Sep 24, 2009 10:24 am
by Kaeru Gaman
Trond wrote:0 angle (east) instead of the 270 angle (North)
270 is south.
Alas!
0 is North, 270 is West!
Code: Select all
EnableExplicit
InitSprite()
InitSprite3D()
InitKeyboard()
OpenWindow( 0, #PB_Ignore,0, 400,300, "Angle" )
OpenWindowedScreen( WindowID(0), 0,0, 400,300, 0,0,0 )
Define n.l
CreateSprite( 0, 64, 64, #PB_Sprite_Texture )
StartDrawing( SpriteOutput(0) )
For n=1 To 32
Line( 32-n, n-1, 2*n, 0, $0000FF )
Next
Box( 16, 32, 32, 32, $0000FF )
StopDrawing()
CreateSprite3D( 0, 0 )
Define Angle.f = 0
Define Event.i
Define EXIT.i = 0
Repeat
Repeat
Event = WaitWindowEvent(5)
If Event = #PB_Event_CloseWindow
EXIT = 1
EndIf
Until Event = #Null
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape)
EXIT = 1
EndIf
If KeyboardPushed( #PB_Key_Left )
Angle - 2
If Angle < 0
Angle +360
EndIf
EndIf
If KeyboardPushed( #PB_Key_Right )
Angle + 2
If Angle >= 360
Angle -360
EndIf
EndIf
ClearScreen( $201008 )
Start3D()
RotateSprite3D( 0, Angle, 0 )
DisplaySprite3D( 0, 168, 118 )
Stop3D()
StartDrawing( ScreenOutput() )
DrawingMode(#PB_2DDrawing_Transparent )
DrawText( 2, 8, "Angle: "+Str(Angle) , $0FF0FF )
StopDrawing()
FlipBuffers()
Until EXIT
this is the Orientation of RotateSprite3D.
use Sin and Cos for your Movement Vectors accordingly.
ZeroVector and Sign of a Rotation is arbitrary, You can chose either Orientation you want.
in this case it would be most practicable to use the Orientation given by RotateSprite3D.