Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable different ways of rendering frames, also introduced flag for drawing with "ADD" blendMode #15

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
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
82 changes: 50 additions & 32 deletions spritesheet/AnimatedSprite.hx
Original file line number Diff line number Diff line change
@@ -1,28 +1,37 @@
package spritesheet;


import flash.display.Bitmap;
import spritesheet.render.IRenderTarget;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.Lib;
import spritesheet.data.BehaviorData;

enum Flag {
BLEND_ADD;
}

@:access(spritesheet.Spritesheet)
class AnimatedSprite extends Sprite {


public var bitmap:Bitmap;
public var renderTarget:IRenderTarget;
public var currentBehavior:BehaviorData;
public var currentFrameIndex:Int;
public var smoothing:Bool;
public var spritesheet:Spritesheet;

public var currentFrameOrigWidth(default,null):Int=0;
public var currentFrameOrigHeight(default,null):Int=0;

private var behaviorComplete:Bool;
private var behaviorQueue:Array <BehaviorData>;
private var behavior:BehaviorData;
private var loopTime:Int;
private var timeElapsed:Int;

private var isAFrameShown : Bool = false; //Inidicates if any frame has been drawn at all


public function new (sheet:Spritesheet, smoothing:Bool = false) {
Expand All @@ -33,12 +42,18 @@ class AnimatedSprite extends Sprite {
this.spritesheet = sheet;

behaviorQueue = new Array <BehaviorData> ();
bitmap = new Bitmap ();
addChild (bitmap);

renderTarget = switch(sheet.imageData) {
case BITMAP_DATA(_,_):
if (sheet.useSingleBitmapData) {
new spritesheet.render.RenderBitmapRectToGraphics (this);
} else {
new spritesheet.render.RenderWholeBitmapToGraphics (this);
}
case TILESHEET(ts):
new spritesheet.render.RenderTilesheetToGraphics(this, ts);
}
}


public function getFrameData (index:Int):Dynamic {

if (currentBehavior != null && currentBehavior.frameData.length > index) {
Expand Down Expand Up @@ -118,27 +133,22 @@ class AnimatedSprite extends Sprite {
}

}



public function update (deltaTime:Int):Void {

if (!behaviorComplete) {

timeElapsed += deltaTime;

var ratio = timeElapsed / loopTime;

if (ratio >= 1) {
if (timeElapsed >= loopTime) {

if (currentBehavior.loop) {

ratio -= Math.floor (ratio);

timeElapsed -= loopTime;
} else {

behaviorComplete = true;
ratio = 1;
timeElapsed = loopTime-1; //Stop time

}

}
Expand All @@ -150,17 +160,20 @@ class AnimatedSprite extends Sprite {
// This is the number of ms we have been in this animation
var timeInAnimation:Int = timeElapsed % loopTime;
// The raw frame index is the number of frames we have had time to show
var rawFrameIndex:Int = Math.round(timeInAnimation / frameDuration);
currentFrameIndex = Std.int(timeInAnimation / frameDuration);
// Make sure we loop correctly
currentFrameIndex = rawFrameIndex % frameCount;

if (currentFrameIndex >= frameCount) {
currentFrameIndex = frameCount - 1;
}

var frame = spritesheet.getFrame (currentBehavior.frames [currentFrameIndex]);


bitmap.bitmapData = frame.bitmapData;
bitmap.smoothing = smoothing;
bitmap.x = frame.offsetX - currentBehavior.originX;
bitmap.y = frame.offsetY - currentBehavior.originY;
isAFrameShown = true;
renderTarget.drawFrame(frame, -currentBehavior.originX, -currentBehavior.originY, smoothing);

// Set frame data
currentFrameOrigWidth = frame.origWidth;
currentFrameOrigHeight = frame.origHeight;

if (behaviorComplete) {

Expand Down Expand Up @@ -193,17 +206,13 @@ class AnimatedSprite extends Sprite {

loopTime = Std.int ((behavior.frames.length / behavior.frameRate) * 1000);

if (bitmap.bitmapData == null) {

update (0);

}
update (0);

}

} else {

bitmap.bitmapData = null;
isAFrameShown = false;
currentBehavior = null;
currentFrameIndex = -1;
behaviorComplete = true;
Expand All @@ -212,5 +221,14 @@ class AnimatedSprite extends Sprite {

}

public function setFlag(flag : Flag) {
renderTarget.enableFlag(flag);
update(0);
}

public function unsetFlag(flag : Flag) {
renderTarget.disableFlag(flag);
update(0);
}

}
}
69 changes: 53 additions & 16 deletions spritesheet/Spritesheet.hx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,22 @@ package spritesheet;


import flash.display.BitmapData;
import openfl.display.Tilemap;
import flash.geom.Point;
import flash.geom.Rectangle;
import spritesheet.data.BehaviorData;
import spritesheet.data.SpritesheetFrame;

private enum ImageData {
BITMAP_DATA(sourceImage : BitmapData, sourceImageAlpha : BitmapData);
TILESHEET(sheet : openfl.display.Tilemap);
}

enum StorageType {
INDIVIDUAL_BITMAPS;// Store every frame in its own BITMAP_DATA
SINGLE_BITMAP; // Store all frames in onw single bitmap
TILESHEET; // Store using openfl.display.Tilemap
}

class Spritesheet {

Expand All @@ -16,14 +27,29 @@ class Spritesheet {
public var totalFrames:Int;

private var frames:Array <SpritesheetFrame>;
private var imageData : ImageData;
private var sourceImage:BitmapData;
private var sourceImageAlpha:BitmapData;
public var useSingleBitmapData(default,null):Bool;


public function new (image:BitmapData = null, frames:Array <SpritesheetFrame> = null, behaviors:Map <String, BehaviorData> = null, imageAlpha:BitmapData = null) {

this.sourceImage = image;
this.sourceImageAlpha = imageAlpha;
public function new (image:BitmapData = null, frames:Array <SpritesheetFrame> = null, behaviors:Map <String, BehaviorData> = null,
imageAlpha:BitmapData = null, storageType : StorageType = null) {

if (storageType == null) {
#if flash
storageType = INDIVIDUAL_BITMAPS; //Tilemap does not work with blendmode = ADD on flash
#else
storageType = TILESHEET; //Only tilesheets work for blendmode = ADD on other targets
#end
}

if (storageType == TILESHEET) {
this.imageData = TILESHEET(new Tilemap(image));
this.useSingleBitmapData = true;
} else {
this.imageData = BITMAP_DATA(image, imageAlpha);
this.useSingleBitmapData = storageType == SINGLE_BITMAP;
}

if (frames == null) {

Expand All @@ -46,6 +72,12 @@ class Spritesheet {
this.behaviors = behaviors;

}

if (useSingleBitmapData && imageAlpha != null) {
var targetRect = new Rectangle(0,0,image.width,image.height);
var targetPoint = new Point();
image.copyChannel (imageAlpha, targetRect, targetPoint, 2, 8);
}

}

Expand Down Expand Up @@ -80,20 +112,25 @@ class Spritesheet {

var frame = frames[index];

var bitmapData = new BitmapData (frame.width, frame.height, true);
var sourceRectangle = new Rectangle (frame.x, frame.y, frame.width, frame.height);
var targetPoint = new Point ();

bitmapData.copyPixels (sourceImage, sourceRectangle, targetPoint);

if (sourceImageAlpha != null) {

bitmapData.copyChannel (sourceImageAlpha, sourceRectangle, targetPoint, 2, 8);

switch(imageData) {
case BITMAP_DATA(sourceImage, sourceImageAlpha):
if (useSingleBitmapData) {
frame.bitmapData = sourceImage;
} else {
var bitmapData = new BitmapData (frame.width, frame.height, true);
bitmapData.copyPixels (sourceImage, sourceRectangle, targetPoint);

if (sourceImageAlpha != null) {
bitmapData.copyChannel (sourceImageAlpha, sourceRectangle, targetPoint, 2, 8);
}
frame.bitmapData = bitmapData;
}
case TILESHEET(sheet):
frame.tilesheetIndex = sheet.addTileRect(sourceRectangle, new Point(0,0));
}

frame.bitmapData = bitmapData;

}


Expand Down Expand Up @@ -225,4 +262,4 @@ class Spritesheet {
}


}
}
7 changes: 6 additions & 1 deletion spritesheet/data/BehaviorData.hx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ class BehaviorData {
return new BehaviorData ("behavior" + (uniqueID++), frames.copy (), loop, frameRate, originX, originY);

}


public function reverse():BehaviorData {
var nFrames = frames.copy();
nFrames.reverse();
return new BehaviorData (name + "Reverse", nFrames, loop, frameRate, originX, originY);
}

}
9 changes: 7 additions & 2 deletions spritesheet/data/SpritesheetFrame.hx
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,30 @@ class SpritesheetFrame {


public var name:String;
public var tilesheetIndex:Int;//Used when drawing this frame from a tilesheet
public var bitmapData:BitmapData;
public var height:Int;
public var offsetX:Int;
public var offsetY:Int;
public var width:Int;
public var x:Int;
public var y:Int;
public var origWidth:Int;
public var origHeight:Int;


public function new (x:Int = 0, y:Int = 0, width:Int = 0, height:Int = 0, offsetX:Int = 0, offsetY:Int = 0) {
public function new (x:Int = 0, y:Int = 0, width:Int = 0, height:Int = 0, offsetX:Int = 0, offsetY:Int = 0, origWidth:Int = -1, origHeight:Int = -1) {

this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.offsetX = offsetX;
this.offsetY = offsetY;
this.origWidth = (origWidth == -1)?width:origWidth;
this.origHeight = (origHeight == -1)?height:origHeight;

}


}
}
2 changes: 1 addition & 1 deletion spritesheet/importers/LibGDXImporter.hx
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class LibGDXImporter {
for (i in 0...frames.length) {

var gdxFrame = frames[i];
var sFrame = new SpritesheetFrame (gdxFrame.xy.x, gdxFrame.xy.y, gdxFrame.size.w, gdxFrame.size.h, gdxFrame.offset.x, gdxFrame.orig.h - gdxFrame.size.h - gdxFrame.offset.y);
var sFrame = new SpritesheetFrame (gdxFrame.xy.x, gdxFrame.xy.y, gdxFrame.size.w, gdxFrame.size.h, gdxFrame.offset.x, gdxFrame.orig.h - gdxFrame.size.h - gdxFrame.offset.y, gdxFrame.orig.w, gdxFrame.orig.h);
sFrame.name = gdxFrame.filename;

indexes.push (allFrames.length);
Expand Down
2 changes: 1 addition & 1 deletion spritesheet/importers/TexturePackerImporter.hx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class TexturePackerImporter {
for (i in 0...frames.length) {

var tpFrame:TPFrame = frames[i];
var sFrame = new SpritesheetFrame ( tpFrame.frame.x, tpFrame.frame.y, tpFrame.frame.w, tpFrame.frame.h );
var sFrame = new SpritesheetFrame ( tpFrame.frame.x, tpFrame.frame.y, tpFrame.frame.w, tpFrame.frame.h, tpFrame.sourceSize.w, tpFrame.sourceSize.h );

if( tpFrame.trimmed )
{
Expand Down
10 changes: 10 additions & 0 deletions spritesheet/render/IRenderTarget.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package spritesheet.render;

import spritesheet.data.SpritesheetFrame;
import spritesheet.AnimatedSprite;

interface IRenderTarget {
function drawFrame(frame : SpritesheetFrame, offsetX : Float, offsetY : Float, smoothing : Bool) : Void;
function enableFlag(flag : Flag) : Void;
function disableFlag(flag : Flag) : Void;
}
31 changes: 31 additions & 0 deletions spritesheet/render/RenderBitmapRectToGraphics.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package spritesheet.render;

import spritesheet.data.SpritesheetFrame;
import flash.display.Sprite;
import flash.display.BlendMode;
import spritesheet.AnimatedSprite;

class RenderBitmapRectToGraphics implements IRenderTarget {
private var sprite : Sprite;
public function new(o : Sprite) {this.sprite = o;}
public function drawFrame(frame : SpritesheetFrame, offsetX : Float, offsetY : Float, smoothing : Bool) {
var m = new flash.geom.Matrix();
m.translate(offsetX + frame.offsetX - frame.x, offsetY + frame.offsetY - frame.y);
sprite.graphics.clear();
sprite.graphics.beginBitmapFill(frame.bitmapData, m, false, smoothing);
sprite.graphics.drawRect(offsetX + frame.offsetX,offsetY + frame.offsetY,frame.width, frame.height);
sprite.graphics.endFill();
}
public function enableFlag(flag : Flag) {
switch(flag) {
case BLEND_ADD:
sprite.blendMode = BlendMode.ADD;
}
}
public function disableFlag(flag : Flag) {
switch(flag) {
case BLEND_ADD:
sprite.blendMode = BlendMode.NORMAL;
}
}
}
Loading