Skip to content

Instantly share code, notes, and snippets.

@pixels4nickels
Created May 6, 2013 05:51
Show Gist options
  • Save pixels4nickels/5523552 to your computer and use it in GitHub Desktop.
Save pixels4nickels/5523552 to your computer and use it in GitHub Desktop.
AnimatedSprite for h2d library. AnimatedH2DSprite.hx subclasses h2d.Sprite.hx instead of flash.display.Sprite. Spritesheet.hx was updated because h3d/h2d libraries use Haxe 3. Hash references were replaced with Map.
import h2d.Scene;
import h2d.Sprite;
import h2d.Bitmap;
import h2d.Tile;
import com.eclecticdesignstudio.spritesheet.data.BehaviorData;
import com.eclecticdesignstudio.spritesheet.Spritesheet;
import flash.display.BitmapData;
class AnimatedH2DSprite extends Sprite
{
public var bitmap:h2d.Bitmap;
public var currentBehavior:BehaviorData;
public var currentFrameIndex:Int;
public var spritesheet:Spritesheet;
private var cb:Dynamic;
private var behaviorComplete:Bool;
private var behaviorQueue:Array <BehaviorData>;
private var behavior:BehaviorData;
private var loopTime:Int;
private var timeElapsed:Int;
public function new (spritesheet:Spritesheet, parent:Sprite, callback:Dynamic = null)
{
super(parent);
this.cb = callback;
this.spritesheet = spritesheet;
behaviorQueue = new Array <BehaviorData> ();
bitmap = new Bitmap (null, this);
}
public function getFrameData (index:Int):Dynamic
{
if (currentBehavior != null && currentBehavior.frameData.length > index)
{
return currentBehavior.frameData[index];
}
else
{
return null;
}
}
public function queueBehavior (behavior:Dynamic):Void
{
var behaviorData = resolveBehavior (behavior);
if (currentBehavior == null)
{
updateBehavior (behaviorData);
}
else
{
behaviorQueue.push (behaviorData);
}
}
private function resolveBehavior (behavior:Dynamic):BehaviorData
{
if (Std.is (behavior, BehaviorData))
{
return cast behavior;
}
else if (Std.is (behavior, String))
{
if (spritesheet != null)
{
return spritesheet.behaviors.get (cast behavior);
}
}
return null;
}
public function showBehavior (behavior:Dynamic, restart:Bool = true):Void
{
behaviorQueue = new Array <BehaviorData> ();
updateBehavior (resolveBehavior (behavior), restart);
}
public function showBehaviors (behaviors:Array <Dynamic>):Void
{
behaviorQueue = new Array <BehaviorData> ();
for (behavior in behaviors)
{
behaviorQueue.push (resolveBehavior (behavior));
}
if (behaviorQueue.length > 0)
{
updateBehavior (behaviorQueue.shift ());
}
}
public function update (deltaTime:Int):Void
{
if (!behaviorComplete)
{
timeElapsed += deltaTime;
var ratio = timeElapsed / loopTime;
if (ratio >= 1)
{
if (currentBehavior.loop)
{
ratio -= Math.floor (ratio);
}
else
{
behaviorComplete = true;
ratio = 1;
}
}
currentFrameIndex = Math.round (ratio * (currentBehavior.frames.length - 1));
var frame = spritesheet.getFrame (currentBehavior.frames [currentFrameIndex]);
var tile = Tile.fromBitmap(frame.bitmapData);
bitmap.tile = tile;
bitmap.x = frame.offsetX - currentBehavior.originX;
bitmap.y = frame.offsetY - currentBehavior.originY;
if (behaviorComplete)
{
if (behaviorQueue.length > 0)
{
updateBehavior (behaviorQueue.shift ());
}
else if (cb != null)
{
cb();
}
}
}
}
private function updateBehavior (behavior:BehaviorData, restart:Bool = true):Void
{
if (behavior != null)
{
if (restart || behavior != currentBehavior)
{
currentBehavior = behavior;
timeElapsed = 0;
behaviorComplete = false;
loopTime = Std.int ((behavior.frames.length / behavior.frameRate) * 1000);
if (bitmap.tile != null)
{
update (0);
}
}
}
else
{
bitmap.tile = null;
currentBehavior = null;
currentFrameIndex = -1;
behaviorComplete = true;
}
}
}
package com.eclecticdesignstudio.spritesheet;
import com.eclecticdesignstudio.spritesheet.data.BehaviorData;
import com.eclecticdesignstudio.spritesheet.data.SpritesheetFrame;
import flash.display.BitmapData;
import flash.geom.Point;
import flash.geom.Rectangle;
/**
* ...
* @author Joshua Granick
*/
class Spritesheet {
public var behaviors:Map <String, BehaviorData>;
public var name:String;
public var totalFrames:Int;
private var frames:Array <SpritesheetFrame>;
private var sourceImage:BitmapData;
private var sourceImageAlpha:BitmapData;
public function new (image:BitmapData = null, frames:Array <SpritesheetFrame> = null,
behaviors:Map <String, BehaviorData> = null, imageAlpha:BitmapData = null) {
this.sourceImage = image;
this.sourceImageAlpha = imageAlpha;
if (frames == null) {
this.frames = new Array <SpritesheetFrame> ();
totalFrames = 0;
} else {
this.frames = frames;
totalFrames = frames.length;
}
if (behaviors == null) {
this.behaviors = new Map();
} else {
this.behaviors = behaviors;
}
}
public function addBehavior (behavior:BehaviorData):Void {
behaviors.set (behavior.name, behavior);
}
public function addFrame (frame:SpritesheetFrame):Void {
frames.push (frame);
totalFrames ++;
}
public function generateBitmaps ():Void {
for (i in 0...totalFrames) {
generateBitmap (i);
}
}
public function generateBitmap (index:Int):Void {
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);
}
frame.bitmapData = bitmapData;
}
public function getFrame (index:Int, autoGenerate:Bool = true):SpritesheetFrame {
var frame = frames[index];
if (frame != null && frame.bitmapData == null && autoGenerate) {
generateBitmap (index);
}
return frame;
}
public function getFrameIDs ():Array <Int> {
var ids = [];
for (i in 0...totalFrames) {
ids.push (i);
}
return ids;
}
public function getFrames ():Array <SpritesheetFrame> {
return frames.copy ();
}
public function merge (spritesheet:Spritesheet):Array <Int> {
var cacheTotalFrames = totalFrames;
for (i in 0...spritesheet.frames.length) {
if (spritesheet.frames[i].bitmapData == null && (spritesheet.sourceImage != sourceImage || spritesheet.sourceImageAlpha != sourceImageAlpha)) {
spritesheet.generateBitmap (i);
}
addFrame (spritesheet.frames[i]);
}
for (behavior in spritesheet.behaviors) {
if (!behaviors.exists (behavior.name)) {
var clone = behavior.clone ();
clone.name = behavior.name;
for (i in 0...behavior.frames.length) {
behavior.frames[i] += cacheTotalFrames;
}
addBehavior (behavior);
}
}
var ids = [];
for (i in cacheTotalFrames...totalFrames) {
ids.push (i);
}
return ids;
}
public function updateImage (image:BitmapData, imageAlpha:BitmapData = null):Void {
sourceImage = image;
sourceImageAlpha = imageAlpha;
for (frame in frames) {
if (frame.bitmapData != null) {
frame.bitmapData = null;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment