Realisitic movement in space using a joystick
Blitz3D Forums/Blitz3D Programming/Realisitic movement in space using a joystick
| ||
Hi, I'm currently working on a space simulator, and since im doing a level maths i thought i'd introduce the principles of taking moments and resolving into the movement of the spaceship. The way this works is to define thrusters, their force, their position relative to the ship and their direction, and then enable or disable these thrusters depending on the joystick position, and then resolve and take moments to find out the movement and rotation of the ship. However, although ive worked this out on paper and as far as i know it should work, when I try to fly the ship in game, the angles are clearly not getting translated into proper forces in the proper directions. It would be great if someone would look over the following code and tell me if ive put a cos in the wrong place or somthing stupid like that. Thanks in advance, Alex --------------IMPORANT----------------- The code below will not work on its own, you need to make a text document called '1.txt' in the same directory which contains data about the thrusters on the ship. The text for 1.txt is below the code for the program. The code itself is here: [CODE] ;Controls- either joystick input OR ;use arrows for pitch and yaw, Q and E for roll left and roll right. W and S are forwards and backwards ;A and D are strafe left and right ;When the ship turns, the downward force of the thrusters not only turns the ship but also causes ;it to move, this is intended since it is what would actually happen. ;The problem with this code, I suspect, is that I am either taking the angle of the ship incorrectly ;or I am using sin and cos in the wrong places, or another stupid error like that :( Graphics3D 800,600,32,2 SetBuffer BackBuffer() ;Cubes for frame of reference For c=1 To 20 cu=CreateCube() PositionEntity cu,Rand(-20,20),Rand(-20,20),Rand(-20,20) Next ;Star background s=CreateSphere(32) FlipMesh s ScaleEntity s,100,100,100 t=CreateTexture(512,512) SetBuffer TextureBuffer(t) For i=1 To 300 size=Rand(1,2) Rect Rand(0,512),Rand(0,512),size,size Next EntityTexture s,t SetBuffer BackBuffer() ;Globals Global x#,y#,z#,xv#,yv#,zv#,ax#,ay#,az#,axv#,ayv#,azv# Global shipname$,shipmass# ;Types Type thruster Field ax#,ay#,az#,x#,y#,z#,thrust#,parent,on#,id End Type ;Load the thruster profile for the ship (this textfile must be made in order for the program to funtion) loadthrusters("1.txt") Global ship=CreateCube() Global cam=CreateCamera(ship) EntityType ship,1 EntityRadius ship,2 EntityType s,2 Collisions 1,2,2,3 While Not KeyHit(1) ;DETECT JOYSTICK INPUT. (For the purposes of this test I have also enabled key input) ;LEFT Y AXIS roll#=JoyRoll() If Abs(roll#)<1 Then roll#=0 If roll#<0.01 Then choosethruster(4,(roll#/180.0)) choosethruster(5,(roll#/180.0)) EndIf If KeyDown(203) Then choosethruster(4,1) choosethruster(5,1) EndIf ;RIGHT Y AXIS If roll#>0.01 Then choosethruster(3,(roll#/180.0)) choosethruster(6,(roll#/180.0)) EndIf If KeyDown(205) Then choosethruster(3,1) choosethruster(6,1) EndIf ;UP X AXIS pitch#=JoyY() If pitch#<0.01 Then ;steer down choosethruster(7,pitch#) choosethruster(10,pitch#) EndIf If KeyDown(208) Then choosethruster(7,1) choosethruster(10,1) EndIf If pitch#>0.01 Then ;steer up choosethruster(8,pitch#) choosethruster(9,pitch#) EndIf If KeyDown(200) Then choosethruster(8,1) choosethruster(9,1) EndIf ;ROLLING yaw#=JoyX() If yaw#>0.01 Then choosethruster(12,yaw#) choosethruster(11,yaw#) EndIf If KeyDown(16) Then choosethruster(12,1) choosethruster(11,1) EndIf If yaw#<0.01 Then choosethruster(13,yaw#) choosethruster(14,yaw#) EndIf If KeyDown(18) Then choosethruster(13,1) choosethruster(14,1) EndIf ;Primary Engine Thrusters If KeyDown(31) Then choosethruster(1,1) If KeyDown(17) Then choosethruster(2,1) If KeyDown(30) Then choosethruster(3,1) choosethruster(5,1) EndIf If KeyDown(32) Then choosethruster(5,1) choosethruster(6,1) EndIf takemoments() resolve() updateship() UpdateWorld() RenderWorld() Text 10,10,"Pitch "+EntityPitch(ship) Text 10,30,"Yaw "+EntityYaw(ship) Text 10,50,"Roll "+EntityRoll(ship) Text 10,70,"z acc "+zv# Text 10,90,"x acc "+xv# Text 10,110,"y acc "+yv# Flip Wend Function choosethruster(id,amount#) ;Enables the correct thruster for the input recieved, with the correct force as determined ;by the joystick push amount For t.thruster= Each thruster If t\id=id Then t\on#=Abs(amount#) EndIf Next End Function Function takemoments() ;Takes moments of the thrusters, this increases the angle of the ship depending on thruster angle, ;power, and distance fromt the center of mass of the ship For t.thruster=Each thruster If Not t\on#=0 Then axv#=axv#+(((t\z#)*(t\on#*Sin(-t\ax#)))/shipmass#) azv#=azv#+(((t\x#)*(t\on#*Sin(-t\ax#)))/shipmass#) ayv#=ayv#+(((t\z#)*(t\on#*Sin(-t\ay#)))/shipmass#) EndIf Next End Function Function resolve() ;Increases the velocity of the ship taking into account the angle of the ship relative to the ;absolute coordinate vectors (if that is what they are named) For t.thruster=Each thruster If Not t\on=0 Then yv#=yv#+((t\on#*Sin(ax#-t\ax#))/shipmass#) xv#=xv#+((t\on#*Sin(ay#-t\ay#))/shipmass#) zv#=zv#+((t\on#*Cos(ay#-t\ay#))/shipmass#) EndIf t\on#=0 Next End Function Function updateship() ;Limits the maximum speed of the ship, dampens the velocity of the ship, and ;moves and rotates the ship using turn and translateentity. If ayv#<-2 Then ayv#=-2 If ayv#>2 Then ayv#=2 axv#=axv#*0.99 ayv#=ayv#*0.99 azv#=azv#*0.99 xv#=xv#*0.99 yv#=yv#*0.99 zv#=zv#*0.99 ;Translateentity is used rather than moveentity because if the entity was moved, the spaceship ;Would not behave in the correct way. TranslateEntity ship,xv#,yv#,zv# TurnEntity ship,axv#,ayv#,azv# End Function Function loadthrusters(name$) Print "loading ships..." f=OpenFile(name$) For i=1 To 13 ReadLine$(f) Next shipname$=ReadLine$(f) shipmass#=ReadLine$(f) Print shipname$+" at"+shipmass+"Kg" numthrust=ReadLine$(f) Repeat reached=reached+1 t.thruster=New thruster ReadLine$(f) t\id=ReadLine$(f) t\thrust#=ReadLine$(f) t\x#=ReadLine$(f) t\y#=ReadLine$(f) t\z#=ReadLine$(f) t\ax#=ReadLine$(f) t\ay#=ReadLine$(f) t\az#=ReadLine$(f) If reached=numthrust Then Exit Forever Print "Loaded "+numthrust+"thrusters" ;WaitKey() End Function [/CODE] THE ALL IMPORTANT SHIP THRUSTER DATA IS HERE::: [CODE] FORMAT FOR SHIP THRUSTERS IS AS FOLLOWS: (ship info followed by as many thrusters as you like) shipname shipmass numthrusters editinfo thrusterid thrusterthrust thrusterx thrustery thrusterz thrusterxa thrusterya thrusterza viper 1000 14 Primary thruster 1 10 0 0 -1 0 180 0 Reverse thruster 2 3 0 0 5 0 0 0 Steer left thruster 3 1 0 0 5 0 90 0 Steer right thruster 4 1 0 0 5 0 -90 0 steer left (rear) thruster 6 2 0 0 -2.5 0 -90 0 steer right (rear) thruster 5 2 0 0 -2.5 0 90 0 steer down thruster 7 1 0 0 5 -90 0 0 steer up thruster 8 1 0 0 5 90 0 0 steer down (rear) thruster 10 2 0 0 -2.5 90 0 0 steer up (rear) thruster 9 2 0 0 -2.5 -90 0 0 roll left thruster 12 1 2 0 0 90 0 0 roll right thruster 13 1 -2 0 0 90 0 0 roll left (opposite) thruster 11 1 -2 0 0 -90 0 0 roll right (opposite) thruster 14 1 2 0 0 -90 0 0 [/CODE] Good Luck :D |
| ||
http://www.blitzbasic.com/codearcs/codearcs.php?code=327 I also ran into some problems with trying this mthod, and instead resorted to a pivot and vector-driven style, having a separate velocity for 3 dimensions. |
| ||
Is that not what i'm doing, or are you talking about vectors that rotate with the ship? If thats the case then the only difference is that you would use moveentity instead of translateentity, otherwise im not sure I get what you mean |