Skip to content

Instantly share code, notes, and snippets.

@AustinEast
Last active April 21, 2021 19:02
Show Gist options
  • Save AustinEast/2240167ebe2438acc30459ecd3d7022a to your computer and use it in GitHub Desktop.
Save AustinEast/2240167ebe2438acc30459ecd3d7022a to your computer and use it in GitHub Desktop.
Simple collision listener implementation for Haxeflixel. Grabbed from the source code of Wet Jet Racing!
package;
typedef Listener =
{
tag1:String,
tag2:String,
callback:Dynamic->Dynamic->Void
}
package;
import Listener;
using Tags;
class PlayState extends FlxState
{
var objects:FlxGroup;
var listeners:Array<Listener> = [];
override public function create()
{
// .... insert normal create logic here ....
objects = new FlxGroup();
add(objects);
// Create FlxObjects and add tags to them
var jetski = new Jetski();
jetski.add_tag('JetSki');
objects.add(jetski);
for (i in 0...900)
{
var obstacle = new Obstacle();
obstacle.add_tags('Obstacle');
objects.add(obstacle);
}
// Initialize your listeners somewhere in your state's `create()` method
init_listeners();
}
function init_listeners()
{
listeners = [
{
tag1: 'JetSki',
tag2: 'Ring',
callback: (jetski:JetSki, ring:Ring) ->
{
jetski.collect_ring();
var p = ring_particles.recycle(FlxSprite, () ->
{
var s = new FlxSprite().loadGraphic(AssetPaths.item_boostring_activated__png, true, 26, 58);
s.animation.add('play', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], 20, false);
s.animation.finishCallback = (name) ->
{
s.kill();
};
return s;
});
var mid = ring.front.getMidpoint();
p.set_midpoint_position(mid);
p.animation.play('play', true);
mid.put();
FlxG.sound.play(AssetPaths.collect_ring__wav);
ring.kill();
}
},
{
tag1: 'JetSki',
tag2: 'Fuel',
callback: (jetski:JetSki, fuel:Fuel) ->
{
collect_fuel();
fuel.animation.play('collected');
fuel.solid = false;
}
},
{
tag1: 'JetSki',
tag2: 'Time',
callback: (jetski:JetSki, time:Time) ->
{
time_remaining = (time_remaining + 5).min(total_time);
time.animation.play('collected');
FlxG.sound.play(AssetPaths.collect_time__wav);
time.solid = false;
}
},
{
tag1: 'JetSki',
tag2: 'Obstacle',
callback: (jetski:JetSki, obstacle:Entity) ->
{
if (!FlxFlicker.isFlickering(jetski))
{
FlxObject.separate(jetski, obstacle);
if (jetski.touching == RIGHT)
{
jetski.velocity.x = -30;
FlxFlicker.flicker(jetski, 3);
drop_fuel();
}
}
}
}];
}
override public function update(elapsed:Float)
{
// .... insert normal update logic here ....
// Collide all of your game objects at once, so only 1 quadtree needs to be built
// This can lead to large performance improvements in many scenarios
FlxG.overlap(objects, null, (obj1:FlxObject, obj2:FlxObject) ->
{
for (listener in listeners)
{
if (obj1.has_tag(listener.tag1) && obj2.has_tag(listener.tag2))
listener.callback(obj1, obj2);
else if (obj2.has_tag(listener.tag1) && obj1.has_tag(listener.tag2))
listener.callback(obj2, obj1);
}
});
}
}
package;
class Tags
{
static var map:Map<String, Array<FlxObject>> = new Map();
public static function add_tag(object:FlxObject, tag:String)
{
if (!map.exists(tag)) map.set(tag, []);
map[tag].push(object);
}
public static function has_tag(object:FlxObject, tag:String):Bool
{
return map.exists(tag) && map[tag].contains(object);
}
public static function remove_tag(object:FlxObject, tag:String):Bool
{
return map.exists(tag) && map[tag].remove(object);
}
public static function remove_all_tags(object:FlxObject)
{
for (arr in map) arr.remove(object);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment