HaxeFlixel Tutorial: Single Separation Collisions

Posted November 3, 2017

Collision detection (and handling) is one of the most fiddly things when it comes to creating games, at least in my experience. There seems to be no shortage of weird bugs and issues that can pop up throughout the entire dev cycle of a game (the weirdest one I’ve encountered so far is this one right here). It’s a good thing then that HaxeFlixel comes with several functions that can take care of it for you. FlxG.collide(a,b) and you’re done, right?

Well yes, you can be. I have run into several instances where the default functions didn’t cut it for me though. The thing is that FlxCollide(a,b) separates both objects from each other when a collision occurs, which isn’t good when one of them is not supposed to be moving (for example a door). An easy fix for that is to set the immovable property of the immovable object to true; this will tell the physics code to leave that object where it is. The player will be stopped by it, but the door won’t fly off its hinges.

For truly stationary objects this is fine. However, there are cases where you want objects to act immovable some times but be movable at other times. Let me show you an example:

solidbox.gif

This metal block should stay where it is when the player walks into it. Setting immovable = true seems like a good option as it achieves that effect.

However, the game actually requires the player to move the block into position using a Speer. So I’ve added some code that sets the block’s velocity when it gets hit by a Speer. However…

phasebox.gif

The block phases through the wall! This is because it is marked as immovable which prevents the physics engine from touching its position, even if it notices the block going into a wall. Setting immovable = false will fix this, but also allow the player to push the block which we don’t want:

pushbox.gif

What a conundrum! But I’ve found a very simple way around these limitations. It’s really quite dumb but it works, so here it is!

Introducing: Single Separation

Without much ado, here’s the function I wrote to help me out in these cases:

public function separateFirst(obj:FlxObject, staticObject:FlxObject){
    var p = staticObject.immovable;
	staticObject.immovable = true;
	var r = FlxObject.separate(obj, staticObject);
	staticObject.immovable = p;
	return r;
}

This function will only separate obj, while the staticObject will stay right where it is. The function is quite simple but let’s step through it one by one.

First, we save the immovable object’s immovable value in p. Then we set the staticObject to be immovable.

We then call HaxeFlixel’s built-in FlxObject.separate function to handle the collision for us. We save the result of the separation in r so we can return it.

Finally, we restore the immovable property of staticObject to whatever it was before we called the function and return the result of the separation. Pretty simple, huh?

Implementation and Result

Using separateFirst we can now implement the behavior we want by using it to check the collision between player and block. To collide the block with the world we can simply use the default FlxG.collide(). Note: The block must have immovable = false set for this to work as intended!

separateFirst(player,block);
FlxG.collide(block,world);

This will make sure that if the player touches the block, the block will act as if it was solid, meaning the player can’t just push it around. However, the block will still properly collide with the world, be affected by gravity, etc.

finalbox.gif

There might be better or smarter ways to achieve this, but this solution has worked out quite well for me so far. If you have any better approaches let me know in the comments!

Join my Discord Server!

Hang out, get news, be excellent!

Come hang out!

Want To Buy Me a Coffee?

Coffee rules, and it keeps me going! I'll take beer too, though.

Related Posts

From Quackshot to Speer

POST | | #Ramblings #Retro #Mega Drive #Speer

Back when I got my Mega Drive in 1991 I got two games along with it: Sonic the Hedgehog and Castle of Illusion. Not only did these excellent titles provide hours of fun for me and my dad, they also left a huge impression on me. Through their sheer quality, these games became my taste in games. I loved the platforming, the colors, the charm, the easy to grasp mechanics and how they were simply fun.

Setting Up SGDK in Visual Studio Code (With Auto-Complete)

POST | | #SGDK #Tutorial #VSCode

As I mentioned in part 2 of Adventures in Mega Drive Coding I set up Code::Blocks as my IDE for Mega Drive development. And Code::Blocks is great, but I still had two issues with it. First of all, auto-complete didn’t really work. Considering I’m pretty much poking around the SGDK API blindly, that wasn’t helpful. And secondly…I use VSCode for pretty much anything else coding-related, so it would be nice to also use it for SGDK stuff.

Using Shoebox With MonoGame

POST | | #Tutorial #MonoGame

If you’ve worked with spritesheets at any point you might have worked with tools like TexturePacker or Shoebox, which can make creating and managing spritesheets a lot easier. I’ve actually not used them until now, but since I’m experimenting with a new framework (MonoGame) I thought I might as well give them a try! However, while TexturePacker has built-in MonoGame support you can only access it in the paid version. Shoebox is completely free, but doesn’t offer support for MonoGame out of the box…but luckily you can modify the output parameters to enable that support!

By using the Disqus service you confirm that you have read and agreed to the privacy policy.

comments powered by Disqus