tricky fight control problem

Blitz3D Forums/Blitz3D Programming/tricky fight control problem

jfk EO-11110(Posted 2005) [#1]
(ehm, I wish I could edit the title: flight, not fight control)
hi
I am curently working on a game that contains some free flight controls. The ship must b capable of flying proper loopings. my code looks like this:

I catch mouse movement speed in mxs# and mys#, then

TurnEntity ship, mys,mxs,0
RotateEntity ship, entitypitch(ship),entityyaw(ship),0


Now this works nicely until I fly right down with a pitch of 90 degrees. Then (when I try to fly headover and complete the looping) the pitch jumps from 90 to -90 as expected, but an undesired effect appears: the Roll of the ship jumps 180 degrees as well! Althoug I explicitely set it to 0 with the RotateEntity Command. I already checked if it's a global/local problem, it isn't

Could anybody help me to solve this, I need this badly and I think anyone who wants flight controls will need it too.


jfk EO-11110(Posted 2005) [#2]
Ok, I kind of solved it, I simply removed the second line and also make sure that the camera that follows the ship always keeps the ships rotation (don't use PointEntity to make the cam look at the ship).


nadia(Posted 2005) [#3]
LOL.. nice solution jfk...
and happy flying!


jfk EO-11110(Posted 2005) [#4]
thanks - I'm free as a bird now :)


Viperfish(Posted 2005) [#5]
I had the same problem in my current project. My ship has completely free 360 degree movement and I wanted the camera to smoothly follow behind the ship and look kind of dynamic rather than a camera fixed at a set point. But, every time the ship rolled or climbed past vertical the camera jumped and caused some wacky effects. I've now got it workin' sweeeeeet. Check out the following code. Just change the code to point to your own mesh and a texture for the plane and it should work as is.
Graphics3D 1024,768,16,1
SetBuffer BackBuffer()

Const climbspeed# = 1, rollspeed# = 2

Global xrotation#,zrotation#,speed#
Global camera% = CreateCamera()

Global plane% = CreatePlane()
Global planetex% = LoadTexture("planettextures/ground4.bmp");Replace with your own texture
ScaleTexture planetex,10,10
EntityTexture plane,planetex

Global ship = LoadMesh("fighter5.3ds");replace with your own mesh
PositionEntity ship,0,100,0 

While Not KeyDown(1)
	speed# = 1
	FlightControls()
	MoveShip(xrotation,zrotation)
	MoveCamera()
	RenderWorld
	Flip
Wend
End

Function MoveShip(xrotate#,zrotate#)
	roll#=rollspeed*Sin(zrotate#)		
	pitch#=climbspeed*Sin(xrotate)
	
	TurnEntity ship,pitch#,0,roll#
	MoveEntity ship,0,0,speed#
End Function

Function MoveCamera()
	;I believe there may be a better way to write the following code using TFORMPOINT, but 
	;this works really well.
	EntityParent(camera,ship,True)
	dx#=EntityX(camera)
	dy#=EntityY(camera)
	dz#=EntityZ(camera)
	r#=EntityRoll(camera)
	p#=EntityPitch(camera)
	y#=EntityYaw(camera)
	;The following 4 lines cause the camera to follow just behind the ship(30 behind, 2 up).
	;Pitch roll and yaw are also just behind the ship giving your camera a super smooth action.
	If r# => 180 Then r# = r# - 360
	If r# =< -180 Then r# = r# + 360
	TurnEntity camera,-p#,-y#,-r#*(.06)
	TranslateEntity camera,-dx*.1,(-dy*.1)+2,(-dz)-30
	EntityParent(camera,0)
End Function

Function FlightControls()
	;The xrotation and yrotation values are passed to the MoveShip function which
	;use the sine wave to give you smooth movement. It is very important these
	;values never exceed 90. But 70 is sufficient.
	If KeyDown(200);x rotation(pitch)
		If xrotation < 70 Then
			xrotation = xrotation + climbspeed#
			If xrotation < 0 Then
				xrotation = xrotation / 1.1
				;If you use Delta timing then the above line should
				;read  "xrotation = xrotation / 1.1 ^ FL\SpeedFactor"
				;note the (^) not (*)
			End If
		End If
	Else 
		If KeyDown(208)
			If xrotation > -70
				xrotation = xrotation -climbspeed#
				If xrotation > 0 Then
					xrotation = xrotation / 1.1
				End If
			End If
		Else 
			If xrotation <> 0 Then
				xrotation = xrotation / 1.1
			End If
		End If
	EndIf
	
	If KeyDown(203);z rotation(roll)
		If zrotation < 70 Then
			zrotation = zrotation + rollspeed#
			If zrotation < 0 Then
				zrotation = zrotation / 1.1
			End If
		End If
	Else 
		If KeyDown(205)
			If zrotation > -70
				zrotation = zrotation - rollspeed#
				If zrotation > 0 Then
					zrotation = zrotation / 1.1
				End If
			End If
		Else 
			If zrotation <> 0 Then
				zrotation = zrotation / 1.1
			End If
		End If
	EndIf
End Function




jfk EO-11110(Posted 2005) [#6]
Thanks a lot!


slenkar(Posted 2005) [#7]
I changed the distance of the camera to the ship so it is closer, but I dont know how to adjust it so the ship is on the screen still,
also when you go down the ship goes off the screen in the actual demo, anyway to fix that?


Viperfish(Posted 2005) [#8]
You simply need to change .1 in the following line to a greater number. It will depend on the size of your entities and the distance of the camera.

TranslateEntity camera,-dx*.1,(-dy*.1)+2,(-dz)-30

The higher number you use the less lag between your entity and the camera. Perhaps try something like this.

lag# = .7 ;<----trial and error will get this right for you.
TranslateEntity camera,-dx* lag# ,(-dy* lag# )+2,(-dz)-30



slenkar(Posted 2005) [#9]
thanks John Ill try it out