Collision(jumping) help
Blitz3D Forums/Blitz3D Beginners Area/Collision(jumping) help
| ||
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 |
| ||
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. |
| ||
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 |