Skip to content

Instantly share code, notes, and snippets.

@azrafe7
Created March 29, 2014 20:42
Show Gist options
  • Save azrafe7/9862593 to your computer and use it in GitHub Desktop.
Save azrafe7/9862593 to your computer and use it in GitHub Desktop.
Convert Grid to a Masklist of coalesced Hitboxes (HaxePunk) (surprisingly less performant)
import com.haxepunk.debug.Console.TraceCapture;
import com.haxepunk.Engine;
import com.haxepunk.Entity;
import com.haxepunk.graphics.Text;
import com.haxepunk.HXP;
import com.haxepunk.masks.Grid;
import com.haxepunk.masks.Hitbox;
import com.haxepunk.masks.Masklist;
import com.haxepunk.Scene;
import com.haxepunk.utils.Draw;
import com.haxepunk.utils.Input;
import com.haxepunk.utils.Key;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.system.System;
import haxe.Timer;
class TestScene extends Scene {
var gridMask:Grid;
var masklist:Masklist;
var points:Array<Point>;
var frameCount = 0;
public function new():Void {
super();
}
public function rndGridStr(nCols:Int, nRows:Int):String
{
var rows = [];
for (c in 0...nRows) {
var row = [for (c in 0...nCols) Math.random() < .450 ? 0 : 1];
rows.push(row.join(","));
}
return rows.join("\n");
}
override public function begin()
{
super.begin();
gridMask = new Grid(35*7, 20*9, 35, 20);
var gridStr:String =
"0,0,0,1,0,1,1\n" +
"0,0,0,1,0,1,1\n" +
"1,1,0,1,1,1,1\n" +
"1,1,0,1,1,1,1\n" +
"1,0,0,1,1,1,0\n" +
"1,1,0,1,1,1,1\n" +
"1,1,0,1,1,1,1\n" +
"1,0,0,1,1,1,0\n" +
"0,1,0,0,0,0,1\n";
// random
var cols = 21, rows = 28;
var tw = 18, th = 15;
gridStr = rndGridStr(cols, rows);
gridMask = new Grid(tw * cols, th * rows, tw, th);
gridMask.loadFromString(gridStr);
gridMask.x = -6;
gridMask.y = -10;
var gridEntity:Entity = addMask(gridMask, "grid", 15, 50);
masklist = toMasklist(gridMask);
addMask(masklist, "masklist", gridMask.width + 40, 50);
var solidTiles = 0;
for (i in 0...gridMask.rows * gridMask.columns) solidTiles += gridMask.getTile(i % gridMask.columns, Std.int(i / gridMask.rows)) ? 1 : 0;
addGraphic(new Text('$solidTiles tiles/${masklist.count} hitboxes', HXP.halfWidth, HXP.height - 30));
HXP.console.paused = true;
HXP.engine.paused = false;
points = [for (i in 0...1000) new Point(Math.random() * gridMask.width, Math.random() * gridMask.height)];
trace(masklist.parent.x);
}
function testGrid() {
var cnt = 0;
for (p in points) if (collidePoint("grid", gridMask.parent.x + p.x, gridMask.parent.y + p.y) != null) cnt++;
trace("grid: " + cnt);
}
function testMasklist() {
var cnt = 0;
for (p in points) if (collidePoint("masklist", masklist.parent.x + p.x, masklist.parent.y + p.y) != null) cnt++;
trace("masklist: " + cnt);
}
public function toMasklist(grid:Grid):Masklist
{
var masklist = new Masklist([]);
var tiles = grid.clone();
var tw = tiles.tileWidth;
var th = tiles.tileHeight;
// returns true IFF all tiles in column `col` from `startRow` to `endRow` are solid.
inline function solidColumn(col:Int, startRow:Int, endRow:Int) {
var solid = true;
for (row in startRow...endRow) {
if (!tiles.getTile(col, row)) {
solid = false;
break;
}
}
return solid;
};
var col = 0;
var row = 0;
while (col < tiles.columns) {
row = 0;
while (row < tiles.rows) {
var endRow = row; // start from current row
while (tiles.getTile(col, endRow)) { // expand vertically
endRow++;
}
if (endRow > row) { // expand horizontally
var endCol = col + 1;
while (solidColumn(endCol, row, endRow)) {
endCol++;
}
// add hitbox
masklist.add(new Hitbox((endCol - col) * tw, (endRow - row) * th, col * tw + tiles.x, row * th + tiles.y));
// mark tiles as used (empty)
for (i in col...endCol)
for (j in row...endRow)
tiles.setTile(i, j, false);
row = endRow;
}
row++;
}
col++;
}
return masklist;
}
override public function update():Void
{
super.update();
frameCount++;
if (frameCount == 2) {
Timer.measure(testMasklist);
Timer.measure(testGrid);
}
if (Input.check(Key.ESCAPE)) quit();
if (Input.pressed(Key.BACKSPACE)) HXP.scene = new TestScene();
}
override public function render():Void
{
super.render();
//for (p in points) Draw.circle(Std.int(gridMask.parent.x + p.x), Std.int(gridMask.parent.y + p.y), 3, 0xFF0000);
//for (p in points) Draw.circle(Std.int(masklist.parent.x + p.x), Std.int(masklist.parent.y + p.y), 3, 0xFF0000);
}
public function quit():Void
{
#if (flash || html5)
System.exit(1);
#else
Sys.exit(1);
#end
}
}
class Main extends Engine {
public function new():Void {
super(800, 600, 60, false);
HXP.console.enable(TraceCapture.No);
HXP.world = new TestScene();
}
static function main():Void {
flash.Lib.current.addChild(new Main());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment