Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 46 additions & 30 deletions src/org/ivar/leveltools/DameLevel.hx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package org.ivar.leveltools;
import org.flixel.FlxGroup;
import org.flixel.FlxTilemap;
import org.flixel.FlxPath;
import haxe.xml.Fast;
import org.flixel.FlxG;
import org.flixel.FlxGroup;
import org.flixel.FlxSprite;
import org.flixel.FlxObject;
import org.flixel.FlxTilemap;
import org.flixel.FlxPath;
import org.flixel.FlxPoint;
import org.ivar.leveltools.Level;
import nme.installer.Assets;
import openfl.Assets;


/**
Expand All @@ -19,21 +19,29 @@ typedef LinkAddCallback = FlxSprite -> FlxSprite -> Properties -> Void;
/**
* @author Nemanja Stojanovic
* This class deals with loading levels exported from DAME. It currently supports
* loading tilemap layers, sprite layers, paths layers and links between sprites.
* Properties are loaded into a key-value structure and passed as arguments to callbacks,
* loading tilemap layers, sprite layers, paths layers and links between sprites.
* Properties are loaded into a key-value structure and passed as arguments to callbacks,
* however, individual tile properties are not yet supported.
*/
class DameLevel extends Level
{

/**
* World bounds provided by DAME
*/
public var boundsMinX:Int;
public var boundsMaxX:Int;
public var boundsMinY:Int;
public var boundsMaxY:Int;
/**
* A table of registered link IDs used to link sprites.
*/
private var linkIds:Hash<FlxSprite>;
private var linkIds:Map<String, FlxSprite>;

/**
* A table of parsed paths, stored by name.
*/
private var paths:Hash<FlxPath>;
private var paths:Map<String, FlxPath>;

/**
* A callback that is called whenever a link is loaded.
Expand All @@ -48,12 +56,12 @@ class DameLevel extends Level
* @param objectAddCallback a callback that is called every time an object (sprite) is loaded.
* @param linkAddCallback a callback that is called every time a link is loaded.
*/
public function new(assetsPath:String, tilemapAddCallback:TilemapAddCallback, objectAddCallback:ObjectAddCallback, linkAddCallback:LinkAddCallback)
public function new(assetsPath:String, tilemapAddCallback:TilemapAddCallback, objectAddCallback:ObjectAddCallback, linkAddCallback:LinkAddCallback)
{
super(assetsPath, tilemapAddCallback, objectAddCallback);
this.linkAddCallback = linkAddCallback;
linkIds = new Hash<FlxSprite>();
paths = new Hash<FlxPath>();
linkIds = new Map<String, FlxSprite>();
paths = new Map<String, FlxPath>();
}

/**
Expand All @@ -72,7 +80,12 @@ class DameLevel extends Level
parseLinks(xml.node.links);

if (addToScene)
FlxG.getState().add(masterLayer);
FlxG.state.add(masterLayer);

boundsMaxX = Std.parseInt(xml.att.maxx);
boundsMinY = Std.parseInt(xml.att.minx);
boundsMaxY = Std.parseInt(xml.att.maxy);
boundsMinY = Std.parseInt(xml.att.miny);
}

/**
Expand Down Expand Up @@ -103,7 +116,7 @@ class DameLevel extends Level
}

/**
* Loads a tilemap and adds it to the layer group.
* Loads a tilemap and adds it to the layer group.
* If specified, the tilemapAddCallback is called with the loaded tilemap as argument.
* @param group The group of the layer this map belongs to
* @param mapNode The node that contains tilemap data
Expand All @@ -112,7 +125,7 @@ class DameLevel extends Level
*/
private function parseTilemap(group:FlxGroup, mapNode:Fast, layerNode:Fast):Void
{
var map:FlxTilemap = new FlxTilemap();
var map:FlxTilemap = new FlxTilemapEx();
map.loadMap(
Assets.getText(assetsPath + mapNode.att.csv),
assetsPath + mapNode.att.tiles,
Expand All @@ -121,18 +134,19 @@ class DameLevel extends Level
0, 0,
Std.parseInt(mapNode.att.drawIdx),
Std.parseInt(mapNode.att.collIdx));
map.setSolid(mapNode.has.hasHits && mapNode.att.hasHits == "true");

map.solid = mapNode.has.hasHits && mapNode.att.hasHits == "true";
map.x = Std.parseInt( mapNode.att.x);
map.y = Std.parseInt( mapNode.att.y);
tilemaps.set(layerNode.att.name, map);
group.add(map);
if (tilemapAddCallback != null)
tilemapAddCallback(map);
}

/**
* Loads a sprite and adds it to the layer group. The sprite is created using reflection,
* from the class name specified in Dame (the class name should contain the whole package).
* If the class doesn't exist, it is simply skipped. If the objectAddCallback is specified,
* Loads a sprite and adds it to the layer group. The sprite is created using reflection,
* from the class name specified in Dame (the class name should contain the whole package).
* If the class doesn't exist, it is simply skipped. If the objectAddCallback is specified,
* it is called with the loaded sprite and it's properties as arguments.
* @todo Maybe throw an exception when the sprite doesn't exist?
* @param group The group of the layer this sprite belongs to.
Expand All @@ -145,15 +159,17 @@ class DameLevel extends Level
var spriteClass = Type.resolveClass(spriteNode.x.get("class"));
if (spriteClass == null)
return;
//Since Type.createInstance can't deal with optional args, we have to pass all
//declared arguments manually.
var constructor = Std.string(Reflect.field(spriteClass, "new"));
var arity = Std.parseInt(constructor.substr(constructor.indexOf(":") + 1));
var args = [];
for(i in 0 ... arity)
args.push(null);

// TODO: the following code doesn't work with haxe3,
// needs to be replaced by macro

//var constructor = Std.string(Reflect.field(spriteClass, "new"));
//var arity = Std.parseInt(constructor.substr(constructor.indexOf(":") + 1));
//var args = [];
//for(i in 0 ... arity)
//args.push(null);

var sprite:FlxSprite = cast(Type.createInstance(spriteClass, args), FlxSprite);
var sprite:FlxSprite = cast(Type.createInstance(spriteClass, []), FlxSprite);
sprite.x = Std.parseFloat(spriteNode.att.x);
sprite.y = Std.parseFloat(spriteNode.att.y);
sprite.angle = Std.parseFloat(spriteNode.att.angle);
Expand All @@ -176,7 +192,7 @@ class DameLevel extends Level
}

/**
* Loads a path and adds it to the paths table under the name of the layer. Currently,
* Loads a path and adds it to the paths table under the name of the layer. Currently,
* only one path per layer is supported, until I find a better way to do this.
* @todo Find a way around the path naming issue
* @param group The group of the layer this path belongs to.
Expand All @@ -197,7 +213,7 @@ class DameLevel extends Level
}

/**
* Loads a link and calls the LinkAddCallback, passing the two linked sprites and the properties
* Loads a link and calls the LinkAddCallback, passing the two linked sprites and the properties
* of the link. If the sprites the link references do not exist, the link is simply skipped.
* @param linkNode The node that contains link data
* @return Nothing.
Expand All @@ -207,7 +223,7 @@ class DameLevel extends Level
for (link in linkNode.nodes.link)
{
var fromId:String = link.att.from;
var toId:String = link.att.to;
var toId:String = link.att.to;
if (linkIds.exists(fromId) && linkIds.exists(toId))
{
var properties:Properties;
Expand Down
31 changes: 31 additions & 0 deletions src/org/ivar/leveltools/FlxTilemapEx.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.ivar.leveltools;
import flash.geom.ColorTransform;
import org.flixel.FlxTilemap;

/**
* ...
* @author k.nepomnyaschiy
*/
class FlxTilemapEx extends FlxTilemap
{


public var color(default, set_color):UInt = 0;

private function set_color(Color:UInt):UInt
{
_tiles.colorTransform(_tiles.rect, intToColorTransform(Color));
return Color;
}

private inline static function intToColorTransform(Color:UInt):ColorTransform
{
var colorTransform:ColorTransform = new ColorTransform();
colorTransform.redMultiplier = (Color >> 16) / 255;
colorTransform.greenMultiplier = (Color >> 8 & 0xff) / 255;
colorTransform.blueMultiplier = (Color & 0xff) / 255;

return colorTransform;
}

}
18 changes: 9 additions & 9 deletions src/org/ivar/leveltools/Level.hx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.ivar.leveltools;
import org.flixel.FlxTilemap;
import org.flixel.FlxGroup;
import org.flixel.FlxObject;
import org.flixel.FlxSprite;
import org.flixel.FlxTilemap;
import nme.installer.Assets;
import openfl.Assets;

/**
* A function type used as a callback for adding objects.
Expand All @@ -19,7 +19,7 @@ typedef TilemapAddCallback = FlxTilemap -> Void;
* @author Nemanja Stojanovic
* The base class of other level loaders.
*/
class Level
class Level
{
/**
* The group that contains all other groups.
Expand All @@ -29,12 +29,12 @@ class Level
/**
* A table that contains the loaded tilemaps stored by name of the layer.
*/
private var tilemaps:Hash<FlxTilemap>;
private var tilemaps:Map<String, FlxTilemap>;

/**
* A table that contains all the layers regardless of type, by the name of the layer.
*/
private var layers:Hash<FlxGroup>;
private var layers:Map<String, FlxGroup>;

/**
* Name of the level.
Expand All @@ -43,7 +43,7 @@ class Level

/**
* Path to the assets directory.
*/
*/
private var assetsPath:String = "assets/";

/**
Expand All @@ -62,13 +62,13 @@ class Level
* @param tilemapAddCallback a callback that is called every time a tilemap is loaded.
* @param objectAddCallback a callback that is called every time an object (sprite) is loaded.
*/
private function new(assetsPath:String, tilemapAddCallback:TilemapAddCallback, objectAddCallback:ObjectAddCallback)
private function new(assetsPath:String, tilemapAddCallback:TilemapAddCallback, objectAddCallback:ObjectAddCallback)
{
this.tilemapAddCallback = tilemapAddCallback;
this.objectAddCallback = objectAddCallback;
masterLayer = new FlxGroup();
tilemaps = new Hash<FlxTilemap>();
layers = new Hash<FlxGroup>();
tilemaps = new Map<String, FlxTilemap>();
layers = new Map<String, FlxGroup>();
this.assetsPath = assetsPath;
}

Expand Down
29 changes: 22 additions & 7 deletions src/org/ivar/leveltools/Properties.hx
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,25 @@ import haxe.xml.Fast;

/**
* @author Nemanja Stojanovic
* This class is used to easily parse key-value properties exported from Dame and Tiled.
* It provides some useful methods for retreiving values and allows the user to specify
* This class is used to easily parse key-value properties exported from Dame and Tiled.
* It provides some useful methods for retreiving values and allows the user to specify
* default values for properties.
*/
class Properties extends Hash<String>
class Properties
{

private var _map:Map<String, String>;
/**
* Constructs the object and loads all the properties into the hash table.
* Both keys and values are strings (as this class extends Hash), but helper methods
* provide conversions to other basic types. It treats all nodes named <code>prop</code> and
* <code>property</code> as properties and reads their <code>name</code> and <code>value</code>
* <code>property</code> as properties and reads their <code>name</code> and <code>value</code>
* attributes.
* @param node The node that contains all the properties.
* @return Nothing.
*/
public function new(?node:Fast = null)
public function new(?node:Fast = null)
{
super();
_map = new Map<String, String>();
if (node == null)
return;
for (property in node.nodes.property)
Expand Down Expand Up @@ -105,4 +105,19 @@ class Properties extends Hash<String>
return def;
}
}

private inline function get(key:String):Dynamic
{
return _map[key];
}

private inline function set(key:String, value:String):Void
{
_map[key] = value;
}

private inline function exists(key:String):Bool
{
return _map[key] != null;
}
}
Loading