jumping problem
Blitz3D Forums/Blitz3D Beginners Area/jumping problem
| ||
Here's my problem. In my game, there is double jumping. I set up a flag where when the player is touching the map, jumping = 1. When jumping = 1, he can jump. Whenever he is not touching the map, jumping = 0, so he can't jump. While in the air, pressing the key to jump makes jumping = 2, so he can jump again. When jumping = 2, he absolutly cannot jump anymore until he touches the map. Now for the problem. I used entitycollided to determine when the player lands on the floor so he can jump again. The problem is that when the player is colliding with ANYTHING on the map, walls, buildings etc, he can jump again, so there is now limit to how much you can jump, even when touching a wall. Is there anyway to determine whether the player is touching the floor or touching the wall in a map? I'm honestly stumped. |
| ||
I had the same problem for a while, not with infinite jumping, but with the player hitting a wall and sliding down without getting hurt from a long fall. There's a couple of ways you can correct this: 1. If possible, use a different EntityType on walls than you use on the floor. This would require separate meshes for each type, so this may not be an option. 2. Create a pivot at the players feet. Then create another pivot and place it directly at the point of the player/level intersection using CollisionX(), CollisionY(), and CollisionZ(). Last, perform an EntityDistance check between the two pivots. If they are close together, then you know that the player's "feet" are touching the ground, but if they are not close, then you know that it's the player's chest or head or somewhere other than the feet colliding. You can use this check to disable infinite jumping like you described above. I was going to provide some sample code, but I don't have access to it right now, and I'm not thinking clearly enough to re-write it. Let me know if a sample would be helpful. |
| ||
Rob the Great Seeing a sample would be very helpful. Also, I have another idea, but i'm not sure if I can use it. You could use the findchild command to pick out peices of the map, let's say the floor, and create an entitytype for it. It sounds like it would make sense, but i'm still kinda weary on it. I'm actually pretty interested in your idea, since you can do other things with the pivots, such as allow the player to jump on enemie heads to kill them. If you could be generous enough, maybe you can try to re-write the example so I can get the idea better. I'm still very confused with collision functions. |
| ||
Give this a try. It's a little longer than I had remembered, but it works. When you run the demo, purposely jump around, and then run into a wall and try jumping off of that wall again:Graphics3D 640,480,0,2 ;Set Up Graphics SetBuffer BackBuffer() ;Set Up the Buffer While Not KeyDown(28) ;This is just some demo text... Text 0,0,"The purpose of this demo is to show" Text 0,20,"how to determine if the player's feet are" Text 0,40,"touching the ground or not. This is" Text 0,60,"useful to ensure that your character" Text 0,80,"can't slide down walls or perform" Text 0,100,"double jumping when they hit a wall." Text 0,180,"Press Enter to Continue..." Flip Wend Cls Type feet ;Create a type for our feet. You'll need this later to keep track of all collisions for the player Field state$ ;We only need to store the current state of the specific collision End Type Global feettouching$ = "No" ;This is a string variable to know for sure whether or not the feet of the player are touching the ground. Global type_level = 1 ;Set Up the Level to be collision type 1 Global type_player = 2 ;Set Up the Player to be collision type 2 Global UPKEY = 200 Global DOWNKEY = 208 Global RIGHTKEY = 205 Global LEFTKEY = 203 Global sun = CreateLight(2) PositionEntity sun,0,500,0 Global camera = CreateCamera() ;Create a camera MoveEntity camera,0,2,-5 ;Move it up 1 and back 10 Global player = CreateSphere() ;Create a ball for our player EntityColor player,255,0,0 ;Color him Red EntityType player,type_player ;Set our player to be collision type 2 Global playerfeet = CreateCube() ;Create a cube to represent our player's feet EntityColor playerfeet,0,0,255 ;Color his feet blue MoveEntity playerfeet,0,-0.9,0 ;Move his feet where they need to be ScaleEntity playerfeet,1,0.1,1 ;Make his feet the right size EntityParent playerfeet,player ;Now whever the player goes, so do the feet Global feetpivot = CreatePivot() ;Create a pivot for the feet PositionEntity feetpivot,0,-0.7,0 ;This is roughly where the player's feet are EntityParent feetpivot,player ;The Feet Pivot will now follow the player Global feetpivot2 = CreatePivot() ;Create a second pivot for the feet. We will use this later to get collision location. EntityParent camera,player ;Just make the camera follow the player, makes for an easy camera system Global level = CreatePlane() ;Create an infinite plane for the ground EntityColor level,0,255,0 ;Color the ground green MoveEntity level,0,-5,0 ;Move the ground down 5 EntityType level,type_level ;Set the level to be collision type 1 For i = 1 To 500 ;Use this for:next loop to make a multi-surface level cube = CreateCube() ScaleEntity cube,2,30,2 PositionEntity cube,Rand(-100,100),0,Rand(-100,100) EntityColor cube,255,255,255 EntityType cube,type_level Next Collisions type_player,type_level,2,3 ;Tell Blitz that you want collision type 2 (player) to collide with collision type 1 (level) While Not KeyDown(1) ;Until we push the esc key, the MAIN LOOP PointEntity camera,player ;Point the camera at the player TranslateEntity player,0,-0.2,0 ;Gravity on our player, very slow fall to see the full effect GetPlayerMovement() ;Call this function to use the arrows keys to move UpdatePlayerJump() ;Call this function to make the player jump UpdateFeetCollision() ;Call this function to see if the player's feet are touching RenderWorld ;Tell Blitz to Update all 3D positions, rotations, ect. UpdateWorld ;Tell Blitz to Update all Animations, Collisions, ect. If EntityCollided(player,type_level) ;If the Player has collided with the level Text 0,0,"The Player has Collided with the Level." ;Tell us that he has EndIf If Not EntityCollided(player,type_level) ;If the player is in the air Text 0,0,"The Player is in the air." ;Tell us that he is in the air EndIf Text 0,20,"Are the player's feet touching? " + feettouching$ Text 0,40,"Here's the distance between the the feet" Text 0,50,"and the point of the last collision: " + EntityDistance(feetpivot,feetpivot2) Flip ;Physically draw all of the updated game to the screen Wend ;Return to the MAIN LOOP, repeat until we push the esc key Function GetPlayerMovement() ;Call this function to use the arrows keys to move If KeyDown(UPKEY) MoveEntity player,0,0,0.5 EndIf If KeyDown(DOWNKEY) MoveEntity player,0,0,-0.5 EndIf If KeyDown(RIGHTKEY) TurnEntity player,0,-5,0 EndIf If KeyDown(LEFTKEY) TurnEntity player,0,5,0 EndIf End Function Function UpdatePlayerJump() ;Call this function to make the player jump (CRUDE EXAMPLE) If EntityCollided(player,type_level) ;If the player is touching the level If KeyDown(57) ;And if we hit the space bar If feettouching$ = "Yes" ;This is the most important line. If, and only if, the feet are touching, can the player jump. Comment this line out to see the difference without it. TranslateEntity player,0,20,0 ;Just move the player up 10 and let gravity do the rest EndIf EndIf EndIf End Function Function UpdateFeetCollision() ;Call this function to see if the player's feet are touching For x = 1 To CountCollisions(player) ;For Every Single Collision that the Player had in this loop... f.feet = New feet ;Create a new type feet to 'remember' this specific collision PositionEntity feetpivot2,EntityX(player),CollisionY(player,x),EntityZ(player) ;move the pivot to the vertical collision spot. X and Z don't matter. If EntityDistance(feetpivot,feetpivot2) <= 0.35 ;If the player's 'feet' and the collision location of the player are close... f\state$ = "Yes" ;the feet type state of being string is True, Yes, Confirmed, the feet are touching EndIf If EntityDistance(feetpivot,feetpivot2) > 0.35 ;If the player's 'feet' and the collision location of the player are not close... f\state$ = "No" ;the feet type state of being string is False, No, Denied, the feet are not touching EndIf Next ;Go back to the top of this loop until we've done this for every single collision the player had in the main loop. For f.feet = Each feet ;For every single feet type we've created up above... If f\state$ = "Yes" ;If the feet type state of being for that one is True, Yes, Confirmed, the feet are touching... feettouching$ = "Yes" ;then, even if it's only one collision, we now want to remember that the feet are touching. EndIf Next For f.feet = Each feet ;Again, for ever single feet type we've created up above... Delete f ;get rid of the bastards and start over for the next loop around Next If Not EntityCollided(player,type_level) ;Finally, we need to check to reset the feettouching state if the player isn't touching the level anywhere feettouching$ = "No" EndIf End Function End ;Kill this sample!!! Read the comments in the sample carefully, and it should all make sense. Let me know if there are questions or problems. |