HaxeFlixel Tutorial: Single Separation Collisions
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:
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…
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:
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.
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!
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
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)
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
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!
Comments
By using the Disqus service you confirm that you have read and agreed to the privacy policy.
comments powered by Disqus