keyboard controls for a gun ship

Blitz3D Forums/Blitz3D Beginners Area/keyboard controls for a gun ship

Hi,

I was just wondering if anybody can give any advice or
perhaps maybe a small fragment of code showing how
to setup the keybord arrow keys to control a gunship that moves up & down and yet allow you to shoot at the same time that you're moving your gunship up & down.

Example:

; ------------------
;  Frenzy Game
; ------------------

Graphics3D 640,480 : SetBuffer BackBuffer()

Global x#=0, y#=0, z#=14, fx#=0, fy#=0, cn#=0.0, fire_on_off=0, fire_left=0, fire_right=0
Global gun, green_jewel, blue_jewel, red_jewel, background

camera = CreateCamera() : light = CreateLight()

gun = LoadMesh ("media\gun2.x")
RotateEntity gun, -90, 0, 0
PositionEntity gun, 0,-14,12
ScaleEntity gun, 1.5,.2,02.2

green_jewel = LoadMesh ("media\gg.x")
RotateEntity green_jewel, -180, 0, 0
PositionEntity green_jewel, 11.0,8.4,12.0
ScaleEntity green_jewel, .7,.7,1

blue_jewel = LoadMesh ("media\bg.x")
RotateEntity blue_jewel, -180, 0, 0
PositionEntity blue_jewel, -.1,4,12
ScaleEntity blue_jewel, 1.5,1.5,1

red_jewel = LoadMesh ("media\rg.x")
RotateEntity red_jewel, -180, 0, 0
PositionEntity red_jewel, -.1,2,12
ScaleEntity red_jewel, .7,.7,1

background = CreateCube()
PositionEntity background, 0,0,20
ScaleEntity background, 20,15,.01
background_tex = LoadTexture("media\bg1.bmp")
EntityTexture background,background_tex



While Not KeyDown( 1 )

		;Copy gun positions into 'Fire' Coordinates
		fx# = x# : fy# = y#

	Controls() : Move_Gun() : Render_Screen()

Wend


; =====================
; ==	Functions    ==
; =====================


Function Controls()

		If KeyDown(200)=True And y#<9.0 Then y#=y#+0.2
						
		If KeyDown(208)=True And y#>-9.0 Then y#=y#-0.2
					
		If KeyDown(203)=True Then Fire_Jewel_Left()
			
		If KeyDown(205)=True Then Fire_Jewel_Right()
								
End Function

Function Fire_Jewel_Left()
			
	For i=0 To -13 Step -1
		PositionEntity blue_jewel, i, y#, z#
		RenderWorld
		Text 0,60, "fx Position: "+i : Flip
		For t=0 To 10000000 : Next
	Next
						 
End Function

Function Fire_Jewel_Right()

	For i=0 To 13
		PositionEntity blue_jewel, i, y#, z#
		RenderWorld
		Text 0,60, "fx Position: "+i : Flip
		For t=0 To 10000000 : Next
	Next

End Function

Function Move_Gun()

	PositionEntity gun, x#, y#, z#
	PositionEntity blue_jewel, x#, y#, z#
		
End Function

Function Render_Screen()

	RenderWorld
	Text 0,20, "Y Position: "+y#
	Text 0,40, "X Position: "+x#
	Flip
	
End Function


Any Help would be very much appreciated, Thank's guys!


jackzip7

Personaly I don't use idividual IF statements for all my keys I do this instead...

  If KeyDown(200)=True And y#<9.0
     y#=y#+0.2			
  Else If KeyDown(208)=True And y#>-9.0
     y#=y#-0.2
  End If			
  If KeyDown(203)=True 
     Fire_Jewel_Left()
  Else If KeyDown(205)=True
     Fire_Jewel_Right()
  End IF


Doesn't make much of a difference. Since these conditionals will only run once per frame, it's merely a question of style.

Common wisdom suggests that you should move all "magic numbers" out of your code and name them. Basically, this means that you should use constants.

Here's how I'd do it:

Const GUNSHIP_SPEED#   = 0.2
Const GUNSHIP_Y_RANGE# = 9.0

Const KEY_UP    = 200
Const KEY_LEFT  = 203
Const KEY_RIGHT = 205
Const KEY_DOWN  = 208

;;;

	; let the player move the gunship
	y = y + (KeyDown(KEY_UP) - KeyDown(KEY_DOWN)) * GUNSHIP_SPEED
	
	; restrict the gunship to reasonable bounds
	if y < -GUNSHIP_Y_RANGE then y = -GUNSHIP_Y_RANGE
	if y > GUNSHIP_Y_RANGE  then y = GUNSHIP_Y_RANGE
	
	; let the player fire the jewels
	If KeyDown(KEY_LEFT)  Then Fire_Jewel_Left()
	If KeyDown(KEY_RIGHT) Then Fire_Jewel_Right()


P.S. Don't forget to remove your debug code:
		RenderWorld
		Text 0,60, "fx Position: "+i : Flip
		For t=0 To 10000000 : Next


Oh! Is your problem that you don't know how to get the jewels moving without hijacking execution from the rest of your code?

Keep track of whether or not your jewels are active. If they are, move them forward each frame. Add an Update_Jewels() function call to your main game loop. The Fire_Jewel_*() functions should set the appropriate jewel to be "active" (so that the update function will move it) and position the jewel at beginning of its flight path.

If this is your problem and you want an example, just ask. Right now I'm off to drink as much vodka as possible.

Here's something I wrote four years ago which is somewhat similar. There's an easier way to do the trig too.
; initialize the usual
SeedRnd MilliSecs()
Graphics3D 800, 600
Global camera = CreateCamera()
PositionEntity camera, 0, 10, -20
Global light = CreateLight()
TurnEntity light, 20, 60, 0

; create some minimal scenery
Global plane = CreatePlane()
EntityAlpha plane, 0.6
EntityColor plane, 0, 0, 255
Global mirror = CreateMirror()

; create our cannon: a stretched cube
Global cannon_entity = CreateCube()
Global cannon_pitch#, cannon_yaw#
PositionEntity cannon_entity, 0, 6, 0
ScaleEntity cannon_entity, 1, 1, 5

; our cannonballs will be a linked link of projectiles: entities and a vector for velocity
Type projectile
	Field entity
	Field vx#, vy#, vz#
End Type


While Not KeyHit(1)

	; control movement of cannon
	If KeyDown(200) Then cannon_pitch = cannon_pitch + 0.5
	If KeyDown(208) Then cannon_pitch = cannon_pitch - 0.5
	If KeyDown(203) Then cannon_yaw = cannon_yaw + 0.5
	If KeyDown(205) Then cannon_yaw = cannon_yaw - 0.5
	RotateEntity cannon_entity, cannon_pitch, cannon_yaw, 0

	; fire!
	If KeyHit(57) Then
		Local cannonball.projectile = New projectile
		cannonball\entity = CreateCube()
		PositionEntity cannonball\entity, EntityX(cannon_entity), EntityY(cannon_entity), EntityZ(cannon_entity)
		Local speed# = 0.5
		cannonball\vx = speed * Cos(cannon_pitch) * Sin(-cannon_yaw)
		cannonball\vy = speed * Sin(-cannon_pitch)
		cannonball\vz = speed * Cos(cannon_pitch) * Cos(cannon_yaw)
	EndIf

	; update all projectiles
	For this.projectile = Each projectile

		; apply gravity
		this\vy = this\vy - 0.01

		; move according to our vector
		TranslateEntity this\entity, this\vx, this\vy, this\vz
		RotateEntity this\entity, VectorPitch(this\vx, this\vy, this\vz), VectorYaw(this\vx, this\vy, this\vz), 0

		; remove projectiles which have hit the "ground"
		If EntityY(this\entity) < 0 Then
			FreeEntity this\entity
			Delete this
		EndIf

	Next

	; show the scene
	RenderWorld()
	Text 0, 0, "Arrow keys to move"
	Text 0, 20, "Space to fire"
	Flip
Wend
End


Hey thanks guys for all your help.. I believe this last code fragment will due after some modification to it.. Thanks alot! ;)

jackzip7