@TeddyDief 4x cut?? (Yesterday)

@biphenyl I'll have to work on my leading with the lightning gun but I think its doable (Yesterday)

@biphenyl let me know when it has internet (Yesterday)

@jswiatek Sure, can work out the details via email: hi@kpulv.com (Yesterday)

@staticsteven ah it might be sampling from outside the bounds. Maybe somehow clamp it's source pixel to the bounds of the texture. (2 days ago)

@staticsteven I add the displacement at explosions and they scale up and fade out over time (2 days ago)

@floatvoid LEVEL 60 ZEBRA ROBOMANCER (2 days ago)

RT @cmuratori: I propose a different name for "Software as a service" that is more accurate: "Software as a tax." (2 days ago)

RT @TomFulp: Gone In A Flash - Kickstarter for a documentary about the Flash boom that changed the internet. Check it out! t.co/rKx… (3 days ago)

@TimothyFitz you just can't win. just get one of those 800lb widescreen CRT monitors~ (3 days ago)

@ADAMATOMIC @TommyRefenes @neilcic hahhaha this is what 11 year old kyle thought was going to happen when they said fire at will (3 days ago)

@konjak yay slot machines (3 days ago)

@TyrusPeace twitter is a fickle beast (4 days ago)

@ADAMATOMIC top 10 blow ups of 2016 (5 days ago)

@nnnehpe haha yeah maybe (6 days ago)

I hope the 3 people in the world that actually get the secret ending in sky sisters appreciate all the art I'm doing for it (6 days ago)

@theBanov @Managore @NoelFB fairy type is so cool look at how fucking pink the fairy energy is auughggh t.co/QYUvhiYRve (6 days ago)

@NoelFB i thought your shades gave you fire resistance (6 days ago)

RT @itchio: The new email recipient field lets you contact buyers, key claims, refinery reward tiers, key groups, etc. #gamedev t.c… (7 days ago)

@theBanov yeah yeah plus I think there's just a checkbox in game maker for it so you should prolly just do that?? (7 days ago)

follow
search

2013 - 2 - 20 / 10:49 am / tutorials

Colliding with Slopes?!

Colliding with Slopes?!

In my last blog post I talked a little bit about how I've implemented slopes in my latest project, but I only talked about how I was actually importing them from Ogmo Editor into Flashpunk and not about how I'm actually using them for platforming. In this post I'll attempt to explain how I actually use slopes in my movement system, which means my platformer characters can walk up and down them without any problems.

The first thing to keep in mind is that all of my slope code only really works with slopes that increase or decrease by 1 pixel. I could rework some of it to make it work with a step of any size that the programmer could define, but for now 1 step is all I really need.

Pixel Sweepin'
The first thing to know is how I actually go about moving my platformer characters, and other moving objects around my game world. I use a method that I refer to as pixel sweeping. Basically whenever an object moves in my games, I move it one pixel at a time and check for collisions at each step! This might sound a little crazy to some folk, but this is the most reliable way I've been able to do stuff like platforming and other moving objects and still collide with even the tiniest pixel of a floor or wall. I've been using this technique since the very beginning of Bonesaw: The Game.

Flashpunk actually has some functions built in that allow you to move things in this manner! You should check out the moveBy() function on the "Entity" class. This function will move the entity by an integer value, and has the option to sweep which will check each pixel for a collision. When there is a collision, it will call the functions moveCollideX() and moveCollideY() which you can override to figure out how you want to respond to collisions in each axis.

The Slope Code
In order to do slopes, I needed to basically make my own moveBy() function so that I could inject my slope code into it at the right spot. First, here's my logic behind it. We'll start with just moving horizontally, and in this example we'll say that I'm only moving to the right.

If the pixel to my right is occupied (there's a collision) then check to see if the pixel to the right, and up one pixel is free. If that's the case, then move one pixel to the right, and one pixel up. We've just moved up a slope by one pixel!

If the pixel to my right is open, then we need to check for a downward slope below! So check to see if the pixel to the right, and down one pixel is open AND check to see if one pixel to the right and two pixels down is occupied. If that is the case, then move one pixel to the right and down one pixel. That's moving down a slope! If we checked one pixel to the right, and down one pixel, and that pixel was occupied, then there is no slope, so just move one pixel to the right.

Actual Source Code
Sorry if that's a little difficult to follow. If it helps any, here is my complete function for moving in the X direction. Note that these functions are still very much a work in progress, so some stuff might not make sense... (like I don't even use that sweep boolean at all? haha!)

public function moveX(collideAgainst:Array, speed:int, sweep:Boolean = true ):void {			
var t:String;
var e:Entity;

_move.x += speed;

var movement:uint = Math.abs(_move.x);
var step:int = FP.sign(_move.x);

while (movement >= speedScale) {
var clear:Boolean = true;

e = collideTypes(collideAgainst, x + step, y);
if (e) {
if (!collideTypes(collideAgainst, x + step, y - 1)) {
y -= 1;
e = null;
}
if (!collideTypes(collideAgainst, x + step, y + 1)) {
y += 1;
e = null;
}
}
else {
if (!collideTypes(collideAgainst, x + step, y + 1)) {
if (collideTypes(collideAgainst, x + step, y + 2)) {
y += 1;
}
}
}

if (e) {
collisionX(e);
movement = 0;
_move.x = 0;
}
else {
x += step;
movement -= speedScale;
_move.x = FP.approach(_move.x, 0, speedScale);
}

}

}


And since I do some checks for slopes in the y direction as well, here's how that looks:

public function moveY(collideAgainst:Array, speed:int, sweep:Boolean = true ):void {
_move.y += speed;

var movement:uint = Math.abs(_move.y);
var step:int = FP.sign(_move.y);

while (movement >= speedScale) {
var clear:Boolean = true;


var e:Entity = collideTypes(collideAgainst, x, y + step);
if (step < 0) {
if (e) {
if (!collideTypes(collideAgainst, x + 1, y + step)) {
x += 1;
e = null;
}
if (!collideTypes(collideAgainst, x - 1, y + step)) {
x -= 1;
e = null;
}
}
}


if (e) {
collisionY(e);
movement = 0;
_move.y = 0;
}
else {
y += step;
movement -= speedScale;
_move.y = FP.approach(_move.y, 0, speedScale);
}
}
}


Both of these functions go on my "Actor" class, which extends "Entity" for some extra functionality.

As far as slopes go in the y direction, it can be a little weird. Right now the way that I use slopes in the Y direction is if you're moving upwards and hit into a slope, you'll slide along it to maintain your upward speed. This feels a little bit more natural to me, but not nearly as necessary as the horizontal movement slope code.

Don't Neglect Downward Slopes!
One thing I want to note is the IMPORTANCE of having code that sticks your objects to slopes that move downward. You might think you can get away with just code that moves your characters up slopes and let gravity do the work for the downward slopes but you are WRONG!

When you try and let gravity do the work for downward slopes you end up with an awkward bouncy walk down every slope. The worst part about this is that your character will actually be leaving the ground every time they walk off the slope to let gravity take them downward. That means whenever the player attempts to jump during this time that they are temporarily off the ground, they will fail. (That is unless you have some sort of jump forgiveness frames, but even with that there is still the issue of the awkward bouncing down the slope.) So that is why I put in the code for checking downward slopes and sticking to those as well.

That's All
Alright I think that's all I got for slopes! If you want to know more feel free to post a comment or whatever. I'll try to answer any question you might have, or if you want to see more code or more examples I can try that too.

1 Comment
Avatar

2013 - 5 - 31 2:57 AM

Shawn McCool

Great article, I like this method and I like the concept of pixel sweeping. I've been using a more traditional collision detection algorithm and I wasn't extremely happy with its reliability.

Do you notice any negatives to extending the capability to check for slopes more than 1 pixel in difference?

Avatar

Post your comment!

POST COMMENT

about

About

Hi! My name's Kyle, and I make video games most of the time in Denver, Colorado. Here you will find my thoughts, games, websites, doodles, and other stuff like that. I worked on Snapshot, Offspring Fling, and a whole bunch of other games. I also created and maintain Otter, a 2d game making framework. If you want to get a hold of me use the form on the bottom of the page, leave a comment, or just tweet at me. I try to post three times a week. Thanks for stoppin' by! You're the coolest.

blog stuff

categories

tags

archives

facebook

videos

Do you want to make a Let's Play of one of my games, or a just a video featuring footage of my games? You have my full permission to do so! Even if you are monetizing your videos, you still have my full permission to use any footage from any of my games. Go for it!

contact

Your message has been sent! Thanks :)
SEND MESSAGE