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?
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?