Advertisement

Basic 2D tile-based collision help needed

Started by February 24, 2003 03:09 AM
0 comments, last by Uhfgood 21 years, 11 months ago
Okay final problem the collision stuff itself is working just dandy now, and i have but a small problem. Basically from time to time while i''m jumping and hitting left or right at the same time, and it collides with a tile, it manages to bump the sprite to the left or right, resulting in a "jerk" or jump. I can''t figure out how to fix it, because basically i''m doing the moves seperately, move vertically for jumping or falling, and moving left or right. Any ideas of why it could be detecting a left or right collision when moving down? (as if it had hit the tile)? Here''s the code, let me know if you don''t understand what i''m asking This is blitzbasic code, but it should be readable

; move a sprite to the left 
Function MoveLeft( s.KSpriteType ) 

   ; first create temp variables for collision check 
   Local cY# = s\yPos# 
   Local cX# = s\xPos# 
    
   ; these alias''s for more readability 
   Local cW# = cX# + s\width 
   Local cH# = cY# + s\height 

   ; left arrow 
   If KeyDown( 203 ) 
    
      ; negative velocity to move left 
      s\xVel# = -s\Speed# 
       
      ; add velocity to position (making sure the 
      ; position stays with in 1.0 range by - 0.5 
      cX# = ( cX# - 0.5 ) + ( DTime# * s\xVel# ) 
       
      ; bounds check 
      If cX# < 0.0 Then cX# = 0.0 
    
      ; alias to make it more readable 
      cW# = cX# + s\width 
    
      ; check left side of player return right 
      ; side of tile in the variable "pLeft" 
      pLeft = CheckLeft( cY#, cX#, cH#, cW# ) 
       
      ; if there''s a collision from the new position 
      If pLeft > -1 
    
         ; readjust position 
         cX# = pLeft 
          
         ; reset velocity if moving left 
         If s\xVel# < 0.0 Then ResetXVelocity( s ) 
       
      End If 
       
   Else ; key up 
    
      ; reset if the key is not pressed 
      If s\xVel# < 0.0 Then ResetXVelocity( s ) 
             
   End If ; key 
    
   ; set the actual newly calculated position 
   SetPos( s, cX#, cY# )    

End Function ; Move Left 

Function MoveRight( s.KSpriteType ) 

   ; first create temp variables for collision check 
   Local cY# = s\yPos# 
   Local cX# = s\xPos# 
    
   ; these alias''s for more readability 
   Local cW# = cX# + s\width 
   Local cH# = cY# + s\height 

   ; right arrow 
   If KeyDown( 205 ) 

      ; allow movement to the right 
      s\xVel# = s\Speed# 
       
      ; add velocity onto position ( this 0.5 
      ; is simply to be consistant with the one 
      ; for moving left ) It doesn''t hurt anything 
      cX# = ( cX# + 0.5 ) + ( DTime# * s\xVel# ) 
       
      ; bounds checking 
      If cX# > ( 640.0 - s\width ) Then cX# = ( 640.0 - s\width ) 

      ; alias for readability 
      cW# = cX# + s\width 

      ; Check the right side of sprite, and return 
      ; the left side of the tile in the var pRight 
      pRight = CheckRight( cY#, cX#, cH#, cW# ) 
       
      ; if there''s a collision from the new position 
      If pRight > -1 

         ; readjust position 
         cX# = pRight - s\width 
          
         ; only reset if it''s moving right 
         If s\xVel# > 0.0 Then ResetXVelocity( s ) 
          
      End If 
       
   Else ; not key down 
    
      ; reset if not moving right 
      If s\xVel# < 0.0 Then ResetXVelocity( s ) 
       
   End If ; key 

   ; set the final calculated position 
   SetPos( s, cX#, cY# ) 
    
End Function ; move right 

Function MoveVertically( s.KSpriteType ) 

   ; first alias some variables. 
   Local cY# = s\yPos# 
   Local cX# = s\xPos# 
    
   ; these alias''s for more readability 
   Local cW# = cX# + s\width 
   Local cH# = cY# + s\height 

   ; add gravity to the velocity 
   s\yVel# = s\yVel# + s\Gravity# 
    
   ; add velocity onto the position 
   cY# = cY# + ( DTime# * s\yVel# ) 
    
   ; do some bounds checking for temp variables 
   If cY# < 0.0 Then 
      cY# = 0.0 
      ResetYVelocity( s ) 
   End If 
    
   If cY# > ( 480.0 - s\height ) Then cY# = ( 480.0 - s\height ) 
    
   ; adjust bottom of bounding box 
   cH# = cY# + s\height 
    
   ; Check for collision with tiles underneath 
   ; then if there is a collision store the location 
   ; of the top of the tile in the variable "Down" 
   Down = CheckDown( cY#, cX#, cH#, cW# ) 
       
   ; if there''s a collision from the new position 
   If Down > -1 
    
      ; readjust position    
      cY# = Down - s\height 
       
      ; stop it from moving 
      ResetYVelocity( s ) 
       
      ; change the state so we''re no longer falling 
      s\state = StandingState 
    
   End If ; downward collision 

   ; Check if we''re standing (is used for walking 
   ; or anything that''s not jumpng or falling) 
   If s\state = StandingState 
    
      ; Space bar pressed? 
      If KeyDown( 57 ) 
       
         ; now we can jump. 
         s\state = JumpingState 

         ; set the velocity high so we''ll escape gravity 
         s\yVel# = -350 
       
      End If 
       
   End If ; standing state 

   ; we''re jumping now? 
   If s\state = JumpingState 

      ; Add to the position 
      cY# = cY# + ( DTime# * s\yVel# ) 

      ; check bounds again 
      If cY# < 0.0 Then 
         cY# = 0.0 
         ResetYVelocity( s ) 
      End If 
       
      If cY# > ( 480.0 - s\height ) Then cY# = ( 480.0 - s\height ) 
          
      ; adjust bounding box 
      cH# = cY# + s\height 
       
      ; check for up, store the tile bottom in pUp 
      pUp = CheckUp( cY#, cX#, cH#, cW# ) 
       
      ; if there''s a collision from the new position 
      If pUp > -1 
         ; readjust position 
         cY# = pUp 
          
         ; stop from moving 
         ResetYVelocity( s ) 
          
         ; now to allow falling again 
         s\state = FallingState 
      End If 

   End If ; jumping state 
    
   ; Set the final position 
   SetPos( Player, cX#, cY# )    

End Function ; Move Vertically 
 
Why should it be bumping to the left or right, if it hits the ground? Any help would be great, thanks! Keith ************************************* Keith Alan Weatherby II Uhfgood@fireworks-interactive.com http://uhfgood.artoo.net *************************************
*************************************Keith Weatherby IIhttp://twitter.com/Uhfgoodhttp://www.facebook.com/Uhfgoodhttp://www.youtube.com/Uhfgoodhttp://www.gamesafoot.comhttp://indieflux.com*************************************
Okay I understand what''s going on, let me explain a little bit.

To anyone that''s reading this

It checks for collision with the ground, and then bumps it up. Then it checks collision with left or right. But when it''s down say 2 tiles, it bumps it up to the previous one, which means it still is within a tile so it checks left or right collision and bumps it left or right as it bumps it out of the ground.

I''m still trying to figure out how to make sure it bumps it out of the ground completely before actually doing left or right collision checks. And yes I did use a while loop, but obviously I did it wrong, which caused it to go in a near infinite loop. (Thanks to checking for the escape key in the loop i''m able to actually exit it so it doesn''t do an infinite loop)

So any ideas on how to actually make sure it''s clean out of the ground before checking left/right collision? This *may* be impossible, due to the fact that if the sprite is sitting on the ground and you try to move left or right while in a corner, it would always be detecting both down and left/right collisions.

Keith

*************************************
Keith Alan Weatherby II
Uhfgood@fireworks-interactive.com http://uhfgood.artoo.net
*************************************
*************************************Keith Weatherby IIhttp://twitter.com/Uhfgoodhttp://www.facebook.com/Uhfgoodhttp://www.youtube.com/Uhfgoodhttp://www.gamesafoot.comhttp://indieflux.com*************************************

This topic is closed to new replies.

Advertisement