Collision(jumping) help

Blitz3D Forums/Blitz3D Beginners Area/Collision(jumping) help

codermax(Posted 2013) [#1]
Hi.

I'm kind of stuck on this whole jumping thing. The code basically goes like this:
1. when players wants to jump, press space
2. player will fly up for a bit, then fall down
3. player will fall to the ground, then stop
4. stopping the fall is based on zeroing the fall velocity

I've tried various methods from the forums to get this working perfect. LinePick doesn't work. It took me a couple tries to get the internal collisions to work. The problem is, when I set "playerisonground=false", the character will fall whenever the player leaves the ground. Two problems exist here:

1. the player will fall through the ground no matter what

And if I happen to fix that, then:

1. the game will check and say that the player has collided with the ground when they reach the peak of their jump, so they'll stop falling in mid-air and can no longer jump

The funny thing is, linepick USED to work, but it was quite finnicky, so I decided to use the internal collisions, which seemed to work for a bit. But as I added unrelated code, the jumping failed to work and I'm kinda stuck. :/

The collision code is based on my understanding of entity scaling and entity boxes.

Just copy, paste and run.

camera.bb



RemiD(Posted 2013) [#2]
Here is an example :
http://blitzbasic.com/codearcs/codearcs.php?code=2933

However this is a really simple example. Please note that if you want to be able to detect collision against walls and against the ground there are several more complex ways to do it.

One would be to use only a collider sphere for the player and seperate the ground collider and the wall collider for the environment

One would be to use one collider sphere for the player to check the collision against the walls and use linepick to check the distance between the player feet and the ground.


_PJ_(Posted 2013) [#3]
Okay, I haven't looked in real depth yet, but I did find a small issue:

In the CheckInput function, you have the following:

;UP key.
	If KeyDown(200) =True
		If PlayerIsJumping=True
			MoveEntity cameracube,0,0,TotalSpeed/3
		EndIf
		If PlayerIsJumping=False
			MoveEntity cameracube,0,0,TotalSpeed/7.6
		EndIf
		
	EndIf

With similar code for other directions too.
This seems a little counter-intuitive to me, and may be better if you consider that while JUMPING the player is only going to ACCELERATE DOWNWARDS due to gravity, and when in the air, no keypresses will make a difference to the movement.

You then have a CheckGravity function in which your AccelerationDueToGravity CHANGES, yet the modification to the PlayerYVelocity is going to quickly become a constant -0.3 or constant +0.5

Overall it seems that at some point, the code has gotten so confusing that the essential principle of what you tried to achieve has become lost in the jumble!

I would recommend simplifying the code in the following way:


1) Acceleration due to Gravity is constant (Okay, it's not TRULY in reality, it varies according to the mass of the objects, but for a game, a constant acceleration downwards should be the value for the effect of gravity).

2) When pressing jump (provided player is not already jumping (see later) then an impulse of velocity UPWARDS is given to the player - this upwards momentum will naturally lessen due to the constant effect of gravity - no more need be done)

3) When checking keys, first, check to see if player is on the ground (With LinePick or the methods mentioned above). If so, then check for keypresses. If not, Apply Gravity (Ideally, gravity would be applied every loop, but to make things easier on the CPU, we only really need to do so if the player is in the air)


____


I really hope this makes sense.

Some brief example code here for each part I mentioned, If I have time, I will see if I can incorporate this into your code, if you need it :)

;The Values below should be chosen according to the scale/units you use for your game.
Const AccelerationDueToGravity#=-0.5
Const MoveSpeed#=1.0 ;Standard Movement Rate
Const JumpSpeed#=2.0 ;Standard Jump Rate

Global MoveXSpeed#;Remembers speed for Momentum in X dimension
Global MoveZSpeed#;Remembers speed for Momentum in Z dimension
Global MoveYSpeed#;Remembers speed for Momentum in Y dimension

While (Loop)
;Main Loop Stuff
	Loop=(Not(KeyHit(1)))
	GetInput
	UpdateMovement
Wend
End

Function GetInput()
	If (PlayerOnGround())
		MoveXSpeed=(KeyDown(205)-KeyDown(203))*MoveSpeed
		MoveZSpeed=(KeyDown(208)-KeyDown(200))*MoveSpeed
		MoveYSpeed=(KeyHit(57))*JumpSpeed
	Else
		;Apply Gravity, Player is in air
		;NOTE We ADD AccelerationDueToGravity, since the Value is NEGATIVE
		MoveYSpeed=MoveYSpeed+AccelerationDueToGravity;This will require some collision checking or similar to ensure that (EntityY(Player,True)+MoveYSpeed)>=GroundLevel and if not, MoveYSpeed=GroundLevel-(EntityY(Player,True)) etc.
	End If
End Function

Function UpdateMovement()
	;Simple Collision Detecting
	If (MoveYSpeed<0)
		If (PlayerOnGround())
			;Here is where any falling-induced damage can occur, MoveYSpeed will hold a value that should indicate magnitude of damage in arbitrary units of MoveSpeed and AccelerationDueToGravity
			MoveYSpeed=0
		End If
	End If
	
	MoveEntity Player,MoveXSpeed,MoveYSpeed,MoveZSpeed		
		
End Function

Function PlayerOnGround()
	If (DoLinePickOrWhatever())
	;Result = Player Touching (OR BENEATH!) Ground
		Return True
	End If
	;Result = Player Not Touching Ground - i.e. jumping, in-air or falling
	Return False
End Function