diff --git a/src/flambe/Entity.hx b/src/flambe/Entity.hx index d1983d46..e6d5c506 100644 --- a/src/flambe/Entity.hx +++ b/src/flambe/Entity.hx @@ -44,6 +44,12 @@ using Lambda; /** This entity's first component. */ public var firstComponent (default, null) :Component = null; + + //Use setZOrder() to set this value instead of zOrder = x + public var zOrder : Int = 0; + public var orderOfArrival : Int = 1; + + public static var globalOrderOfArrival : Int = 1; public function new () { @@ -165,39 +171,82 @@ using Lambda; return untyped _compMap[name]; } - /** +/** * Adds a child to this entity. * @param append Whether to add the entity to the end or beginning of the child list. * @returns This instance, for chaining. */ - public function addChild (entity :Entity, append :Bool=true) + public function addChild (entity :Entity, append :Bool = true, ?zOrder : Int) { + //trace("entity.addChild = " + zOrder); if (entity.parent != null) { entity.parent.removeChild(entity); } entity.parent = this; - if (append) { - // Append it to the child list - var tail = null, p = firstChild; - while (p != null) { - tail = p; - p = p.next; - } - if (tail != null) { - tail.next = entity; - } else { - firstChild = entity; - } - - } else { - // Prepend it to the child list - entity.next = firstChild; - firstChild = entity; - } + if (append) { + var tail = null, p = firstChild; + + while (p != null) { + tail = p; + p = p.next; + } + if (tail != null) { + if (zOrder == null) { + zOrder = tail.zOrder; + } + if (tail.zOrder <= zOrder) { + tail.next = entity; + } else { + var p = firstChild; + var pre : Entity = null; + while (p != null) { + if (p.zOrder > zOrder) { + if (pre != null) { + pre.next = entity; + entity.next = p; + } else { + entity.next = firstChild; + firstChild = entity; + } + break; + } else { + pre = p; + p = p.next; + } + + } + } + } else { + firstChild = entity; + if (zOrder == null) { + zOrder = 0; + } + } + } else { + if (firstChild == null) { + zOrder = 0; + } else { + zOrder = firstChild.zOrder - 1; + } + entity.next = firstChild; + firstChild = entity; + } + + entity.zOrder = zOrder; return this; } + + public function setZOrder(z : Int) { + if (this.zOrder == z) { + return; + } else { + this.zOrder = z; + this.parent.addChild(this, true, this.zOrder); + } + + } public function removeChild (entity :Entity) { diff --git a/src/flambe/display/PlistEntry.hx b/src/flambe/display/PlistEntry.hx new file mode 100644 index 00000000..3396d298 --- /dev/null +++ b/src/flambe/display/PlistEntry.hx @@ -0,0 +1,41 @@ +package flambe.display; + +/** + * ... + * @author Ang Li(李昂) + */ +class PlistEntry +{ + + public var name : String; + public var x : Float; + public var y : Float; + public var width : Float; + public var height : Float; + public var sourceColorX : Float; + public var sourceColorY : Float; + public var rotated : Bool; + + + public function new(?entry : PlistEntry) { + if (entry == null) { + return; + } + this.name = entry.name; + this.x = entry.x; + this.y = entry.y; + this.width = entry.width; + this.height = entry.height; + this.sourceColorX = entry.sourceColorX; + this.sourceColorY = entry.sourceColorY; + this.rotated = entry.rotated; + } + + public function toString() : String { + var ret : String = name + "," + Std.string(x) + "," + Std.string(y) + "," + + Std.string(sourceColorX) + "," + Std.string(sourceColorY) + "," + Std.string(rotated); + return ret; + + } + +} \ No newline at end of file diff --git a/src/flambe/display/PlistParser.hx b/src/flambe/display/PlistParser.hx new file mode 100644 index 00000000..07736a39 --- /dev/null +++ b/src/flambe/display/PlistParser.hx @@ -0,0 +1,93 @@ +package flambe.display; +import flambe.asset.AssetPack; + +/** + * Parser for Texture Packer + * @author Ang Li(李昂) + */ +class PlistParser +{ + public function new() + { + } + + + public static function parse(xmlDoc : Xml) : Array { + var plist = new Array(); + var frames : Xml = null; + var metadata : Xml = null; + var index : Int = 0; + for (x in xmlDoc.firstElement().firstElement().elements()) { + if (x.firstChild().nodeValue == "frames") { + index = 1; + } else if (x.nodeName == "dict" && index == 1) { + frames = x; + } else if (x.firstChild().nodeValue == "metadata") { + index = 2; + } else if (x.nodeName == "dict" && index == 2) { + metadata = x; + } + } + + index = 1; + var tempEntry : PlistEntry = new PlistEntry(); + var tempKey : String = ""; + for (x in frames.elements()) { + if (x.nodeName == "key" && index == 1) { + + tempEntry.name = x.firstChild().nodeValue; + index = 2; + } else if (x.nodeName == "dict" && index == 2) { + index = 1; + for (info in x.elements()) { + if (info.nodeName == "key") { + tempKey = info.firstChild().nodeValue; + } else { + switch(tempKey) { + case "frame" : + var s : Array = parseString(info.firstChild().nodeValue); + tempEntry.x = s[0]; + tempEntry.y = s[1]; + tempEntry.width = s[2]; + tempEntry.height = s[3]; + + case "sourceColorRect": + var s : Array = parseString(info.firstChild().nodeValue); + tempEntry.sourceColorX = s[0]; + tempEntry.sourceColorY = s[1]; + + case "rotated": + if (info.nodeName == "true") { + tempEntry.rotated = true; + } else { + tempEntry.rotated = false; + } + } + } + } + plist.push(new PlistEntry(tempEntry)); + } + } + return plist; + } + + public static function parseString(str : String) : Array { + var ret : Array = new Array(); + var index : Int; + var temp : String; + var buf : StringBuf = new StringBuf(); + + for (i in 0...str.length) { + if (str.charAt(i) != "{" && str.charAt(i) != "}") { + buf.addSub(str.charAt(i), 0); + } + } + + var newString : String = buf.toString(); + for (i in newString.split(",")) { + ret.push(Std.parseFloat(i)); + } + + return ret; + } +} \ No newline at end of file diff --git a/src/flambe/display/SpriteFrame.hx b/src/flambe/display/SpriteFrame.hx new file mode 100644 index 00000000..0f8477e8 --- /dev/null +++ b/src/flambe/display/SpriteFrame.hx @@ -0,0 +1,130 @@ +package flambe.display; + +import flambe.display.Texture; +import flambe.math.Point; +import flambe.math.Rectangle; +import flambe.math.Size; + +/** + * ... + * @author Ang Li(李昂) + */ +class SpriteFrame +{ + + var _offset : Point; + var _originalSize : Size; + var _rectInPixels : Rectangle; + var _rotated : Bool; + var _rect : Rectangle; + var _offsetInPixels : Point; + var _originalSizeInPixels : Size; + var _texture : Texture; + var _textureFilname : String; + + public function new() { + this._offset = new Point(0, 0); + this._offsetInPixels = new Point(0, 0); + this._originalSize = new Size(0, 0); + this._rectInPixels = new Rectangle(0, 0, 0, 0); + this._rect = new Rectangle(0, 0, 0, 0); + this._originalSizeInPixels = new Size(0, 0); + this._textureFilname = ""; +} + + public function getRectInPixels() : Rectangle { + return this._rectInPixels; + } + + public function setRectInPixels(rectInPixels : Rectangle) { + this._rectInPixels = rectInPixels; + this._rect = rectInPixels; + } + + public function isRotated() : Bool { + return this._rotated; + } + + public function setRotated(bRotated : Bool) { + this._rotated = bRotated; + } + + public function getRect() : Rectangle { + return this._rect; + } + + public function setRect(rect :Rectangle) { + this._rect = rect; + this._rectInPixels = rect; + } + + public function getOffsetInPixels() : Point { + return new Point(this._offsetInPixels.x, this._offsetInPixels.y); + } + + public function setOffsetInPixels(offsetInPixels : Point) { + this._offsetInPixels = offsetInPixels; + this._offset = offsetInPixels; + } + + public function getOriginalSizeInPixels() : Size { + return this._originalSizeInPixels; + } + + public function setOriginalSizePixels(sizeInPixels : Size) { + this._originalSizeInPixels = sizeInPixels; + } + + public function getOriginalSize() : Size { + return new Size(this._originalSize.width, this._originalSize.height); + } + + public function setOriginalSize(sizeInPixels : Size) { + this._originalSize = sizeInPixels; + } + + public function getTexture() : Texture { + if (this._texture != null) { + return this._texture; + } + return null; + } + + public function setTexture(texture : Texture) { + if (this._texture != texture) { + this._texture = texture; + } + } + + public function getOffset() : Point { + return new Point(this._offset.x, this._offset.y); + } + + public function setOffset(offsets : Point) { + this._offset = offsets; + } + + public function initWithTexture(texture : Texture, rect : Rectangle, rotated : Bool, offset : Point, originalSize : Size) : Bool{ + this._texture = texture; + this._rectInPixels = rect; + this._rect = rect; + this._offsetInPixels = offset; + this._offset = offset; + this._originalSizeInPixels = originalSize; + this._originalSize = originalSize; + this._rotated = rotated; + return true; + } + + public function toString() : String { + var ret : String = _offset.x + "," + _offset.y + "," + isRotated() + "," + _rect.x + "," + _rect.y + "," + _rect.width + "," + _rect.height; + return ret; + } + + public static function createWithTexture(texture : Texture, rect : Rectangle, ?rotated : Bool, ?offset : Point, ?originalSize : Size) : SpriteFrame { + var spriteFrame : SpriteFrame = new SpriteFrame(); + spriteFrame.initWithTexture(texture, rect, rotated, offset, originalSize); + return spriteFrame; + } + +} \ No newline at end of file diff --git a/src/flambe/display/SpriteSheet.hx b/src/flambe/display/SpriteSheet.hx new file mode 100644 index 00000000..3bca52ba --- /dev/null +++ b/src/flambe/display/SpriteSheet.hx @@ -0,0 +1,66 @@ +package flambe.display; +import flambe.display.Sprite; +import flambe.display.Texture; +import flambe.display.Graphics; + +/** + * ... + * @author Ang Li(李昂) + */ +class SpriteSheet extends Sprite +{ + public var texture : Texture; + public var g : Graphics; + + var c : Int = 2; + public var frame : SpriteFrame; + + public function new(frame : SpriteFrame) + { + super(); + this.frame = frame; + } + + public function updateFrame(frame : SpriteFrame) { + this.frame = frame; + } + + var flag : Bool = true; + override public function draw(g:Graphics) + { + this.g = g; + + if (frame.isRotated()) { + g.translate(frame.getOffset().x, frame.getOffset().y + frame.getRect().height); + g.rotate( -90); + g.drawSubImage(frame.getTexture(), 0, 0, frame.getRect().x, frame.getRect().y, + frame.getRect().height, frame.getRect().width); + + } else { + g.translate(frame.getOffset().x, frame.getOffset().y); + g.drawSubImage(frame.getTexture(), 0, 0, frame.getRect().x, frame.getRect().y, + frame.getRect().width, frame.getRect().height); + } + } + + public function getCurrentFrame() : SpriteFrame { + return frame; + } + + override public function getNaturalHeight():Float + { + if (this.frame == null) { + return 0; + } + return frame.getRect().height; + } + + override public function getNaturalWidth():Float + { + if (this.frame == null) { + return 0; + } + return frame.getRect().width; + } + +} \ No newline at end of file diff --git a/src/flambe/display/SpriteSheetPlayer.hx b/src/flambe/display/SpriteSheetPlayer.hx new file mode 100644 index 00000000..f09692ca --- /dev/null +++ b/src/flambe/display/SpriteSheetPlayer.hx @@ -0,0 +1,101 @@ +package flambe.display; +import flambe.asset.AssetPack; +import flambe.Component; +import flambe.display.Texture; +import flambe.Entity; +import flambe.math.Rectangle; +import flambe.math.Point; +import flambe.math.Size; +import flambe.util.Assert; +import flambe.display.Sprite; + +/** + * ... + * @author Ang Li(李昂) + */ +class SpriteSheetPlayer extends Component +{ + var plist : Array; + var texture : Texture; + var _spriteFramesInfo : Array; + var sprites : Array; + var _root : Entity; + public var currentIndex : Int = 0; + public var currentFrame : SpriteSheet; + public var paused : Bool = false; + + public function new(pack : AssetPack, plistName : String) + { + var xmlDoc : Xml = Xml.parse(pack.getFile(plistName).toString()); + plist = PlistParser.parse(xmlDoc); + _spriteFramesInfo = new Array(); + sprites = new Array(); + + if (texture == null) { + var name : String = plistName.split(".pli")[0]; + texture = pack.getTexture(name); + } + + this._addSpriteFramesWithDictionary(); + + _addSpriteFramesWithDictionary(); + _initSprites(); + _root = new Entity(); + } + + private function _addSpriteFramesWithDictionary() { + for (p in plist) { + var rect : Rectangle = new Rectangle(p.x, p.y, p.width, p.height); + var rotated : Bool = p.rotated; + var offset : Point = new Point(p.sourceColorX, p.sourceColorY); + var size : Size = new Size(0, 0); + var frame : SpriteFrame = + SpriteFrame.createWithTexture(texture, rect, rotated, offset, size); + + if (this._spriteFramesInfo == null) { + trace("null"); + } + this._spriteFramesInfo.push(frame); + } + } + + private function _initSprites() { + currentFrame = new SpriteSheet(_spriteFramesInfo[0]); + currentIndex++; + } + + public function play() { + if (_root.get(SpriteSheet) == null) { + _root.add(currentFrame); + } + currentIndex = 0; + paused = false; + } + + override public function onAdded() + { + owner.addChild(_root); + + } + + override public function onRemoved() + { + _root.dispose(); + this.currentFrame = null; + } + + override public function onUpdate(dt:Float) + { + if (!paused && currentFrame != null) { + if (currentIndex == _spriteFramesInfo.length) { + currentIndex = 0; + } + currentFrame.frame = _spriteFramesInfo[currentIndex++]; + } + } + + public function setCurrentFrame(index : Int) { + currentIndex = index; + currentFrame = sprites[index]; + } +} \ No newline at end of file diff --git a/src/flambe/math/Size.hx b/src/flambe/math/Size.hx new file mode 100644 index 00000000..8ed36c9e --- /dev/null +++ b/src/flambe/math/Size.hx @@ -0,0 +1,35 @@ +package flambe.math; + +/** + * ... + * @author Ang Li(李昂) + */ +class Size +{ + + public var width : Float; + public var height : Float; + public function new(?width : Float = 0, ?height : Float = 0) + { + this.width = width; + this.height = height; + } + + public function setSize(width : Float , height : Float) { + this.width = width; + this.height = height; + } + + public function equals(size : Size) : Bool { + if (this.width == size.width && this.height == size.height) { + return true; + } else { + return false; + } + } + + public function toString() : String { + return '$width x $height'; + } + +} \ No newline at end of file