@flibitijibibo YUP Going to give it a whirl today! :O (Today)

POOP I totally forgot to put FNA in the poll (Today)

@StegerGames UGGH yeah the music stuff (and shader stuff) is what is making me feel weird about using XNA. (Today)

@larsiusprime HMM Yeah I was going to add that option and then I retyped the tweet and totally forgot -_- (Today)

Hey people that use XNA/Monogame do you use XNA for Windows builds? Or Monogame for Windows & everything else? (Today)

@ADAMATOMIC D E L E T E E V E R Y T H I N G (Today)

@SteveSwink tell johnathan stanley I said whats up (Today)

@braceyourselfok PC~ (Today)

@MattThorson @braceyourselfok @MllePilgrim @JonahD we should do a battle lobby sometime soon with discord or something for voice chats (Today)

@TommyRefenes yeah it's not bad yeah it's not bad yeah it's not bad yeah it's not bad (Yesterday)

@TommyRefenes I dont like how the seats look like ghosts waiting for you in the car (Yesterday)

can someone make a VR game like this t.co/VS0NvtIP4K (Yesterday)

@_mightymarcus_ hahah, yeah I'm not sure if I want to go down that route. I'm always nervous to try the various "calming" medications (Yesterday)

@MattThorson @braceyourselfok @MllePilgrim I can try to give you a rundown of stuff sometime. To be fair there is a lot of shit going on. (Yesterday)

@braceyourselfok @MattThorson @MllePilgrim hey did someone say street fighter (Yesterday)

@TylerGlaiel how to make a successful game step 1 make a slot machine step 2 disguise it as not a slot machine (Yesterday)

@MattThorson noooooooo no dont (Yesterday)

@konjak every E3 I just feel more and more out of touch with what people want out of games so it becomes less and less exciting ;_; (Yesterday)

@kertgartner it was a simpler time... (Yesterday)

@ColinNorthway ( ຈ ﹏ ຈ ) (2 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