IF'S from hell

Blitz3D Forums/Blitz3D Programming/IF'S from hell

DroolBucket(Posted 2006) [#1]
im having troble getting the movement in my game working the way i need it 2. Im trying to make my character be able to strafe (like move left and right while faceing forward) problem is if u push forward then he seems to move double fast and then their seems to be like a hundred possible combinations of buttons i would need to take care of using if's. is their an easyier way?


Sledge(Posted 2006) [#2]
The easy way to strafe is to translate the player depending on whether left/right is pressed (see MoveEntity); the more complex way is to use vector math for x and z velocity and use TranslateEntity (bit early for that, I think). Using MoveEntity and TranslateEntity this is four lines of code - post what you've got if you're in a mess.


im having troble getting the movement in my game working the way i need it 2



This is probably one of the worst places ever to obfuscate your language - if you don't mean a value, don't write one.


EDIT: Original post was misleading (see below) - fixed.


octothorpe(Posted 2006) [#3]
Player control systems can easily get very complicated, but it's worth making a great and intuitive interface. Read up on State Machines and draw a diagram of all the different actions your player can perform to figure out what states you'll need to keep track of.

Does this solve your immediate problem?

Local move_z# = KeyDown(KEY_UP) - KeyDown(KEY_DOWN)
Local move_x# = KeyDown(KEY_RIGHT) - KeyDown(KEY_LEFT)

If move_z <> 0 And move_x <> 0 Then
	move_z = move_z * Sin(45)
	move_x = move_x * Sin(45)
EndIf


You could then multiply both by one coefficient for sprinting or another for sneaking/crawling, depending on which modifier buttons are being pressed.

the way i need it 2


Please use English properly. Reading "abbreviations" like that can be very annoying.


WolRon(Posted 2006) [#4]
DroolBucket, have you seen my FPS example at my programming tutorial?

It can already strafe.


DroolBucket(Posted 2006) [#5]
Please use English properly. Reading "abbreviations" like that can be very annoying.

Sorry, to much AIM :P

diagram of all the different actions your player can perform and figure out what states you'll need to keep track of. <-- I think that would be the best way to solve my problem.


jhocking(Posted 2006) [#6]
The easy way to strafe is to translate the player depending on whether left/right is pressed (see TranslateEntity); the more complex way is to use vector math for x and z velocity (bit early for that, I think)

Actually, from his initial post it sounds like he is already doing things the easy way and doesn't like it. You'll need to use some vector math for what you want (or rather, use the TForm commands to do some vector math for you.)


Sir Gak(Posted 2006) [#7]
I'm using a keyboard movement system, not a mouse, but here is how I do a strafe. I created a pivot for my camera, naming it "pcam". Movement operations are done to the pivot pcam, and the camera follows along for the ride.

	strafe=False:dir#=0
	If KeyDown(205)       ;turn right
		If KeyDown(56) Or KeyDown(184) ;either ALT key
			strafe=True	
			dir=0.1
		Else
			cam_y=cam_y-2
		EndIf
	Else If KeyDown(203)  ;turn left 
		If KeyDown(56) Or KeyDown(184) ;either ALT key
			strafe=True	
			dir=-0.1
		Else	
			cam_y=cam_y+2
		EndIf
	EndIf
	cam_z#=0		
	If KeyDown(200)       ;Up arrow, go forward
		If KeyDown(42) Or KeyDown(54) ;either Shift key
			cam_z = .3  ;running
		Else
			cam_z = .1
		EndIf
	Else If KeyDown(208)  ;Down arrow, go back
		If KeyDown(42) Or KeyDown(54) ;either Shift key
			cam_z = -.3 ;running
		Else
			cam_z = -.1
		EndIf
	EndIf
	If strafe
		MoveEntity pcam,dir,0,0     ;go left or right
	Else
		RotateEntity pcam,0,cam_y,0 ;turn to left or right
		MoveEntity pcam,0,0,cam_z   ;go foward or back
	EndIf
	FlushKeys
	Collisions 1,2,2,2 ;Camera collision with objects, slide from point of collision
	UpdateWorld
	RenderWorld 


As you can see, I create a "strafe" condition, and activate based on whether someone is pressing an ALT key (either one). Works like a charm.

(Hmm, upon looking at my code, it occurs to me that I never initialize "cam_y", so I'll have to fix that.)


octothorpe(Posted 2006) [#8]
Remixed with less Ifs
	Local strafing = KeyDown(56) Or KeyDown(184) ;either ALT key
	Local running = KeyDown(42) Or KeyDown(54) ;either Shift key
	Local input_z = KeyDown(200) - KeyDown(208) ;up=+1, down=-1
	Local input_x = KeyDown(205) - KeyDown(203) ;right=+1, left=-1

	Local turn#
	If Not strafing Then
		turn = input_x * 2
		input_x = 0 ;remove sideways input so we can assume it's used for strafing hereafter
	EndIf

	Local running_z_speed_modifier# = 1.0
	If running Then running_z_speed_modifier = 3.0

	Local move_x# = input_x * .1
	Local move_z# = input_z * .1 * running_z_speed_modifier
	
	RotateEntity pcam,0,turn,0 ;turn to left or right
	MoveEntity pcam,move_x,0,move_z   ;go foward or back

Also, to solve your "double fast" problem, I'd normalize the movement vector to its largest dimension. This means that if move_z and move_x are .3 and .1, they'll be trimmed down to ~.285 and ~.095 respectively, creating a triangle with a hypotenuse length of .3.
	Local move_max# = max(Abs(move_z), Abs(move_x))
	If move_max > 0 Then
		Local hypot# = Sqr(move_z*move_z + move_x*move_x)
		move_z = move_z * move_max / hypot
		move_x = move_x * move_max / hypot
	EndIf

Function max#(a#, b#)
	If a>b Then Return a Else Return b
End Function



Sledge(Posted 2006) [#9]

Actually, from his initial post it sounds like he is already doing things the easy way and doesn't like it.



On review, my original post was totally misleading becuse MoveEntity provides the easier method - fixed that now.

He seems to have plenty of help, but I just posted an example of mouselook in this thread which also involves strafing if that helps any.