Skip to content

Instantly share code, notes, and snippets.

@triplefox
Last active December 11, 2015 14:48
Show Gist options
  • Save triplefox/4616340 to your computer and use it in GitHub Desktop.
Save triplefox/4616340 to your computer and use it in GitHub Desktop.
package com.ludamix.heart;
/**
* Tilemap which turns abstract metatiles into groups of four subtiles via
* an algorithm that checks a collision mask.
*/
class AutoTilemap<T : (AutoTileDef)> implements Tilemap<TypedGrid<T>>
{
public var width (getWidth, null) : Int;
public var height (getHeight, null) : Int;
public var render_width (getRenderWidth, null) : Int;
public var render_height (getRenderHeight, null) : Int;
public var abstract_tile_width (getTileWidth, null) : Float;
public var abstract_tile_height (getTileHeight, null) : Float;
public var render_tile_width (getRenderTileWidth, null) : Float;
public var render_tile_height (getRenderTileHeight, null) : Float;
public var default_sendmask : Int;
public var default_recievemask : Int;
public var g : TypedGrid<T>;
public var z : IntGrid;
public inline function getWidth():Int { return g.width; }
public inline function getHeight():Int { return g.height; }
public inline function getRenderWidth():Int { return g.width * 2; }
public inline function getRenderHeight():Int { return g.height * 2; }
public inline function getTileWidth():Float { return g.tile_width; }
public inline function getTileHeight():Float { return g.tile_height; }
public inline function getRenderTileWidth():Float { return g.tile_width * 0.5; }
public inline function getRenderTileHeight():Float { return g.tile_height * 0.5; }
/**
* Add (and process) new abstract tilemap data.
* @param g
*/
public inline function init(g : TypedGrid<T>) : Void
{
this.g = g;
this.z = new IntGrid(render_width, render_height, render_tile_width, render_tile_height);
}
/**
* Refresh all metatiles.
*/
public inline function refreshAll():Void
{
for (y in 0...height)
{
for (x in 0...width)
{
refreshExact(x, y);
}
}
}
/**
* Refresh the rendering of exactly one metatile.
*/
public inline function refreshExact(x, y) : Void
{
var i = { tl:0, tr:0, bl:0, br:0 };
var tl = g.c2t(x - 1, y - 1);
var t = g.c2t(x, y - 1);
var tr = g.c2t(x + 1, y - 1);
var l = g.c2t(x - 1, y);
var c = g.c2t(x, y);
var r = g.c2t(x + 1, y);
var bl = g.c2t(x - 1, y + 1);
var b = g.c2t(x, y + 1);
var br = g.c2t(x + 1, y + 1);
AutoTile.rewriteAutoTiling(i,
c == null ? default_sendmask : c.sendMask(),
tl == null ? default_recievemask : tl.recieveMask(),
t == null ? default_recievemask : t.recieveMask(),
tr == null ? default_recievemask : tr.recieveMask(),
l == null ? default_recievemask : l.recieveMask(),
r == null ? default_recievemask : r.recieveMask(),
bl == null ? default_recievemask : bl.recieveMask(),
b == null ? default_recievemask : b.recieveMask(),
br == null ? default_recievemask : br.recieveMask()
);
var x2 = x << 1;
var y2 = y << 1;
z.s2(x2, y2, i.tl);
z.s2(x2 + 1, y2, i.tr);
z.s2(x2, y2 + 1, i.bl);
z.s2(x2 + 1, y2 + 1, i.br);
}
/**
* Refresh a metatile and the area around it.
*/
public inline function refresh(x, y):Void
{
refreshExact(x - 1, y - 1);
refreshExact(x, y - 1);
refreshExact(x + 1, y - 1);
refreshExact(x - 1, y );
refreshExact(x, y );
refreshExact(x + 1, y );
refreshExact(x - 1, y + 1);
refreshExact(x, y + 1);
refreshExact(x + 1, y + 1);
}
/**
* Return the metatile data.
*/
public inline function get(x, y) : T
{
return g.c2t(x, y);
}
/**
* Set the metatile data.
*/
public inline function set(x, y, v) : Void
{
g.flat[g.c21(x, y)] = v;
refresh(x, y);
}
/**
* Fill the abstract tilemap data.
*/
public inline function fill(v : Int->T) : Void
{
for (n in 0...g.flat.length)
g.flat[n] = v(n);
refreshAll();
}
/**
* Return the renderable tilemap data.
* @param x
* @param y
* @return
*/
public inline function getRenderable(x, y) : Int
{
return z.c2t(x, y);
}
/**
* Return the length of the abstract data.
* @return
*/
public function iterator() : Iterator<Int>
{
return 0...g.flat.length;
}
public function new(g : TypedGrid<T>, ?default_sendmask=0, ?default_recievemask=0)
{
this.default_sendmask = default_sendmask;
this.default_recievemask = default_recievemask;
init(g);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment