Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Collision Issue

I am currently working on a project for the 5-year-contest. it will be made completely from scratch (no default scripts). i have the player, the ground and a test scene.

it is a platformer, and i have the gravity and movement done already, using pixel-perfect collision.

the problem is: the player moves down hills, not up them, it moves through them if you walk toward them from the bottom.

collision methods:
[rgss] 
module Engine
 
  TR_TOL = 1 # transparency tolerance, a pixel which alpha value is below or equal to this value,
                  # will be considered non collidable.
 
  def self.pp_collide(sprite1, sprite2)
 
    left1 = sprite1.x
    left2 = sprite2.x
    right1 = sprite1.x + sprite1.width
    right2 = sprite2.x + sprite2.width
    top1 = sprite1.y
    top2 = sprite2.y
    bottom1 = sprite1.y + sprite1.height
    bottom2 = sprite2.y + sprite2.height
 
    # obvious rejections:
    return false if (bottom1 < top2)
    return false if (top1 > bottom2)
    return false if (right1 < left2)
    return false if (left1 > right2)
 
    # Ok, compute the rectangle of overlap:
    if (bottom1 > bottom2)
      over_bottom = bottom2
    else
      over_bottom = bottom1
    end
 
    if (top1 < top2)
      over_top = top2
    else
      over_top = top1
    end
   
    if (left1 < left2)
      over_left = left2
    else
      over_left = left1
    end
   
    if (right1 > right2)
      over_right = right2
    else
      over_right = right1
    end
    # create the overlapping rectangle
    orect = Rect.new(over_left,over_top,(over_right-over_left).abs,(over_bottom-over_top).abs)
 
    # Now compute starting offsets into both sprites' bitmaps:
    offset1_x = orect.x == left2  ? sprite2.x - sprite1.x : 0#sprite1.width-orect.width   : 0
    offset1_y = orect.y == top2   ? sprite2.y - sprite1.y : 0#sprite1.height-orect.height : 0
    offset2_x = orect.x == left1  ? sprite1.x - sprite2.x : 0#sprite2.width-orect.width   : 0
    offset2_y = orect.y == top1   ? sprite1.y - sprite2.y : 0#sprite2.height-orect.height : 0
 
    # Now start scanning the whole rectangle of overlap,
    # checking the corresponding pixel of each sprite's
    # bitmap to see if they're both non-zero:
    for i in 0..orect.width
      for j in 0..orect.height
        pix1=sprite1.bitmap.get_pixel(i+offset1_x,j+offset1_y)
        pix2=sprite2.bitmap.get_pixel(i+offset2_x,j+offset2_y)
        return true if pix1.alpha >= TR_TOL and pix2.alpha >= TR_TOL
      end
    end
    # Worst case!  We scanned through the whole rectangle of overlap
    # and couldn't find a single colliding pixel!
    return false
  end
 
  def self.pp_collide2(sprite1, sprite2)
 
    left1 = sprite1.x
    left2 = sprite2.x
    right1 = sprite1.x + sprite1.width
    right2 = sprite2.x + sprite2.width
    top1 = sprite1.y
    top2 = sprite2.y
    bottom1 = sprite1.y + sprite1.height + 1
    bottom2 = sprite2.y + sprite2.height
 
    # obvious rejections:
    return false if (bottom1 < top2)
    return false if (top1 > bottom2)
    return false if (right1 < left2)
    return false if (left1 > right2)
 
    # Ok, compute the rectangle of overlap:
    if (bottom1 > bottom2)
      over_bottom = bottom2
    else
      over_bottom = bottom1
    end
 
    if (top1 < top2)
      over_top = top2
    else
      over_top = top1
    end
   
    if (left1 < left2)
      over_left = left2
    else
      over_left = left1
    end
   
    if (right1 > right2)
      over_right = right2
    else
      over_right = right1
    end
    # create the overlapping rectangle
    orect = Rect.new(over_left,over_top,(over_right-over_left).abs,(over_bottom-over_top).abs)
 
    # Now compute starting offsets into both sprites' bitmaps:
    offset1_x = orect.x == left2  ? sprite2.x - sprite1.x : 0#sprite1.width-orect.width   : 0
    offset1_y = orect.y == top2   ? sprite2.y - sprite1.y : 0#sprite1.height-orect.height : 0
    offset2_x = orect.x == left1  ? sprite1.x - sprite2.x : 0#sprite2.width-orect.width   : 0
    offset2_y = orect.y == top1   ? sprite1.y - sprite2.y : 0#sprite2.height-orect.height : 0
 
    # Now start scanning the whole rectangle of overlap,
    # checking the corresponding pixel of each sprite's
    # bitmap to see if they're both non-zero:
    for i in 0..orect.width
      for j in 0..orect.height
        pix1=sprite1.bitmap.get_pixel(i+offset1_x,j+offset1_y)
        pix2=sprite2.bitmap.get_pixel(i+offset2_x,j+offset2_y)
        return true if pix1.alpha >= TR_TOL and pix2.alpha >= TR_TOL
      end
    end
    # Worst case!  We scanned through the whole rectangle of overlap
    # and couldn't find a single colliding pixel!
    return false
  end
end
 
[/rgss]

player's collision detection:
[rgss] 
def update
    update_movement
    if Engine.pp_collide(@sprite, $scene.ground.sprite)
      @y -= 1
    elsif @jumping == true && Engine.pp_collide2(@sprite, $scene.ground.sprite) == true
      @jumping = false
      @grav = 1
    elsif @jumping == true
      @y += @grav
      @grav += 1
    elsif Engine.pp_collide2(@sprite, $scene.ground.sprite) == false
      @y += 1
    end
    @sprite.update
    @sprite.x = @x
    @sprite.y = @y
end
 
[/rgss]

that's the only issue so far. any suggestions?
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top