Skip to content

Commit

Permalink
Enable different ways of rendering frames:
Browse files Browse the repository at this point in the history
* Traditionally, with a single bitmapData for every frame
* By drawing a rect from one single bitmap data
* Using tilesheets

For this render targets are introduced, which render into a "graphics" object.
For now the graphics object is the "graphics" member of the AnimatedSprite.

Also: Introduced flag for rendering with "ADD" blendMode.
Due to some issue, rendering with blendmode "Add" works only using tilesheets on C++
targets and by setting "blendMode" of the sprite on flash target.
  • Loading branch information
RudolfVonKrugstein committed Nov 1, 2014
1 parent d458e1d commit 81453cd
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 28 deletions.
45 changes: 32 additions & 13 deletions spritesheet/AnimatedSprite.hx
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
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;
Expand All @@ -23,6 +27,8 @@ class AnimatedSprite extends Sprite {
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,9 +39,16 @@ 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);
}
}


Expand Down Expand Up @@ -156,12 +169,9 @@ class AnimatedSprite extends Sprite {

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);

if (behaviorComplete) {

if (behaviorQueue.length > 0) {
Expand Down Expand Up @@ -193,7 +203,7 @@ class AnimatedSprite extends Sprite {

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

if (bitmap.bitmapData == null) {
if (!isAFrameShown) {

update (0);

Expand All @@ -203,7 +213,7 @@ class AnimatedSprite extends Sprite {

} else {

bitmap.bitmapData = null;
isAFrameShown = false;
currentBehavior = null;
currentFrameIndex = -1;
behaviorComplete = true;
Expand All @@ -212,5 +222,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);
}

}
67 changes: 52 additions & 15 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.Tilesheet;
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.Tilesheet);
}

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.Tilesheet
}

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; //Tilesheet 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 Tilesheet(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
1 change: 1 addition & 0 deletions spritesheet/data/SpritesheetFrame.hx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ 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;
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;
}
}
}
32 changes: 32 additions & 0 deletions spritesheet/render/RenderTilesheetToGraphics.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package spritesheet.render;

import openfl.display.Tilesheet;
import spritesheet.data.SpritesheetFrame;
import flash.display.Sprite;
import spritesheet.AnimatedSprite;

class RenderTilesheetToGraphics implements IRenderTarget {
private var sprite : Sprite;
private var tilesheet : Tilesheet;
private var flags : Int = 0;
public function new(o : Sprite, tilesheet : Tilesheet) {
this.sprite = o;
this.tilesheet = tilesheet;
}
public function drawFrame(frame : SpritesheetFrame, offsetX : Float , offsetY : Float, smoothing : Bool) {
sprite.graphics.clear();
tilesheet.drawTiles(sprite.graphics, [offsetX + frame.offsetX,offsetY + frame.offsetY, frame.tilesheetIndex], smoothing, flags);
}
public function enableFlag(flag : Flag) {
switch(flag) {
case BLEND_ADD:
flags = flags | Tilesheet.TILE_BLEND_ADD;
}
}
public function disableFlag(flag : Flag) {
switch(flag) {
case BLEND_ADD:
flags &= 0xFFFFFFF - Tilesheet.TILE_BLEND_ADD;
}
}
}
30 changes: 30 additions & 0 deletions spritesheet/render/RenderWholeBitmapToGraphics.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package spritesheet.render;

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

class RenderWholeBitmapToGraphics implements IRenderTarget {
private var sprite : Sprite;
public function new(o : Sprite) {this.sprite = o;}
public function drawFrame(frame : spritesheet.data.SpritesheetFrame, offsetX : Float, offsetY : Float, smoothing : Bool) {
var m = new flash.geom.Matrix();
m.translate(offsetX + frame.offsetX, offsetY + frame.offsetY);
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;
}
}
}

0 comments on commit 81453cd

Please sign in to comment.