Skip to content

Instantly share code, notes, and snippets.

@Geokureli
Created October 1, 2021 22:58
Show Gist options
  • Save Geokureli/69789154a653dc90ac2c719a9c284963 to your computer and use it in GitHub Desktop.
Save Geokureli/69789154a653dc90ac2c719a9c284963 to your computer and use it in GitHub Desktop.
import flixel.FlxG;
import flixel.FlxBasic;
import flixel.FlxObject;
class MassUtil
{
/**
* Same as FlxG.collide but allows objects to ride other non-immovable objects.
*
* @param objectOrGroup1 The first object or group you want to check.
* @param objectOrGroup2 The second object or group you want to check. If it is the same as the first,
* Flixel knows to just do a comparison within that group.
* @param notifyCallback A function with two `FlxObject` parameters -
* e.g. `onOverlap(object1:FlxObject, object2:FlxObject)` -
* that is called if those two objects overlap.
* @return Whether any objects were successfully collided/separated.
*/
static public function collide(?objectOrGroup1:FlxBasic, ?objectOrGroup2:FlxBasic, ?notifyCallback:Dynamic->Dynamic->Void):Bool
{
return FlxG.overlap(objectOrGroup1, objectOrGroup2, notifyCallback, separate);
}
/**
* Same as FlxObject.separate but allows objects to ride other non-immovable objects.
*
* @param object1 Any `FlxObject`.
* @param object2 Any other `FlxObject`.
* @return Whether the objects in fact touched and were separated.
*/
public static function separate(object1:FlxObject, object2:FlxObject):Bool
{
// No mass calculations needed on immovable objects or tilemaps
@:privateAccess
if (object1.immovable || object2.immovable || object1.flixelType == TILEMAP || object2.flixelType == TILEMAP)
return FlxObject.separate(object1, object2);
var separatedX:Bool = separateX(object1, object2);
var separatedY:Bool = separateY(object1, object2);
return separatedX || separatedY;
}
/**
* The X-axis component of the object separation process.
*
* @param object1 Any `FlxObject`.
* @param object2 Any other `FlxObject`.
* @return Whether the objects in fact touched and were separated along the X axis.
*/
public static function separateX(object1:FlxObject, object2:FlxObject):Bool
{
@:privateAccess
var overlap:Float = FlxObject.computeOverlapX(object1, object2);
// Then adjust their positions and velocities accordingly (if there was any overlap)
if (overlap != 0)
{
var vel1 = object1.velocity.x;
var vel2 = object2.velocity.x;
var mass1 = object1.mass;
var mass2 = object2.mass;
// negate overlap
overlap *= 0.5;
object1.x = object1.x - overlap;
object2.x += overlap;
var newVel1 = (mass1 * vel1 + mass2 * vel2 + object1.elasticity * mass2 * (vel2 - vel1)) / (mass1 + mass2);
var newVel2 = (mass2 * vel2 + mass1 * vel1 + object2.elasticity * mass1 * (vel1 - vel2)) / (mass1 + mass2);
object1.velocity.x = newVel1;
object2.velocity.x = newVel2;
return true;
}
return false;
}
/**
* The Y-axis component of the object separation process.
*
* @param object1 Any `FlxObject`.
* @param object2 Any other `FlxObject`.
* @return Whether the objects in fact touched and were separated along the Y axis.
*/
public static function separateY(object1:FlxObject, object2:FlxObject):Bool
{
@:privateAccess
var overlap:Float = FlxObject.computeOverlapY(object1, object2);
// Then adjust their positions and velocities accordingly (if there was any overlap)
if (overlap != 0)
{
var delta1 = object1.y - object1.last.y;
var delta2 = object2.y - object2.last.y;
var vel1 = object1.velocity.y;
var vel2 = object2.velocity.y;
var mass1 = object1.mass;
var mass2 = object2.mass;
// negate overlap
overlap *= 0.5;
object1.y = object1.y - overlap;
object2.y += overlap;
var newVel1 = (mass1 * vel1 + mass2 * vel2 + object1.elasticity * mass2 * (vel2 - vel1)) / (mass1 + mass2);
var newVel2 = (mass2 * vel2 + mass1 * vel1 + object2.elasticity * mass1 * (vel1 - vel2)) / (mass1 + mass2);
object1.velocity.y = newVel1;
object2.velocity.y = newVel2;
// This is special case code that handles cases like horizontal moving platforms you can ride
if (object1.collisonXDrag && object2.active && object2.moves && (delta1 > delta2))
object1.x += object2.x - object2.last.x;
else if (object2.collisonXDrag && object1.active && object1.moves && (delta1 < delta2))
object2.x += object1.x - object1.last.x;
return true;
}
return false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment