forked from: are
fork from https://github.com/nulldesign/nd2d
...
fork from https://github.com/nulldesign/nd2d
a flash bitmapdata animation engine.
http://code.google.com/p/animation-render-engine/
function
efficient bitmap rendering
based on grid of efficient mouse collision detection
support DuoZhong animation format into including movieclip spritesheet
to the special GunBing map optimization
regional cutting
@author lizhi http://game-develop.net/
/**
* Copyright hellogavin1988 ( http://wonderfl.net/user/hellogavin1988 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/9NyO
*/
// forked from lizhi's are
//fork from https://github.com/nulldesign/nd2d
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
import flash.geom.Rectangle;
import net.hires.debug.Stats;
import sliz.net.MiniLoader;
/**
* ...
* fork from https://github.com/nulldesign/nd2d
* a flash bitmapdata animation engine.
* http://code.google.com/p/animation-render-engine/
* function
* efficient bitmap rendering
*based on grid of efficient mouse collision detection
*support DuoZhong animation format into including movieclip spritesheet
*to the special GunBing map optimization
*regional cutting
*
* @author lizhi http://game-develop.net/
*/
[SWF(width=465,height=465,backgroundColor=0x666666,frameRate=60)]
public class Test2 extends Sprite
{
private var world:World;
private var bmdsource:BitmapData;
private var upbmds:Vector.<BitmapData>;
private var rightbmds:Vector.<BitmapData>;
private var downbmds:Vector.<BitmapData>;
private var leftbmds:Vector.<BitmapData>;
private var sw:int = 24;
private var sh:int = 32;
private var p:Point = new Point(-sw / 2, -sh / 2);
private var frames:Vector.<uint> = new Vector.<uint>;
private var sprite:Particle;
private var loader:MiniLoader;
public function Test2()
{
loader = new MiniLoader;
loader.loadImage("http://assets.wonderfl.net/images/related_images/9/94/9404/9404101258150fca19594c3b9bb852c12cc4f68a");
loader.addEventListener(Event.COMPLETE, onLoad);
}
private function onLoad(e:Event):void
{
bmdsource = loader.getImage();
for (var i:int = 0; i < 3; i++)
{
var fps:int = 10;
while (fps-- > 0)
frames.push(i);
}
upbmds = getBmds([0, 1, 2]);
rightbmds = getBmds([3, 4, 5]);
downbmds = getBmds([6, 7, 8]);
leftbmds = getBmds([9, 10, 11]);
world = new World;
addChild(world);
add(500);
world.start();
addChild(new Stats);
addEventListener(Event.ENTER_FRAME, update);
}
private function getBmds(arr:Array):Vector.<BitmapData>
{
var bmds:Vector.<BitmapData> = new Vector.<BitmapData>;
for each (var i:int in arr)
{
var bmd:BitmapData = new BitmapData(sw, sh, true, 0);
bmd.setVector(bmd.rect, bmdsource.getVector(new Rectangle(i % 3 * sw, int(i / 3) * sh, sw, sh)));
bmds.push(bmd);
}
return bmds;
}
private function add(num:int):void
{
while (num-- > 0)
{
sprite = new Particle(world);
sprite.vx = (Math.random() - Math.random()) * 3;
sprite.vy = (Math.random() - Math.random()) * 3;
sprite.x = stage.stageWidth * Math.random();
sprite.y = stage.stageHeight * Math.random();
sprite.addAnimationFromSpriteSheet(upbmds, frames, p, "up");
sprite.addAnimationFromSpriteSheet(downbmds, frames, p, "down");
sprite.addAnimationFromSpriteSheet(rightbmds, frames, p, "right");
sprite.addAnimationFromSpriteSheet(leftbmds, frames, p, "left");
world.add(sprite, false);
sprite.play("up", int(upbmds.length * Math.random()));
}
}
private function update(e:Event):void
{
var s:Particle = sprite;
while (s != null)
{
s.x += s.vx;
s.y += s.vy;
//s.rotation += 10;
if (s.x < 0)
{
s.x = 0;
s.vx *= -1;
}
if (s.x > stage.stageWidth)
{
s.x = stage.stageWidth;
s.vx *= -1;
}
if (s.y < 0)
{
s.y = 0;
s.vy *= -1;
}
if (s.y > stage.stageHeight)
{
s.y = stage.stageHeight;
s.vy *= -1;
}
var vxabs:Number = Math.abs(s.vx);
var vyabs:Number = Math.abs(s.vy);
if (s.vx > 0 && vxabs > vyabs)
{ // right
s.play("right",s.frame);
}
else if (s.vx < 0 && vxabs > vyabs)
{ // left
s.play("left",s.frame);
}
else if (s.vy > 0 && vyabs > vxabs)
{ // down
s.play("down",s.frame);
}
else if (s.vy < 0 && vyabs > vxabs)
{ // up
s.play("up",s.frame);
}
s = s.pre as Particle;
}
world.sortByY();
}
}
}
import flash.geom.Point;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.geom.Rectangle;
import flash.events.Event;
import flash.events.MouseEvent;
class AnimationData
{
public var name:String;
public var frames:Vector.<uint>;
public var bmds:Vector.<BitmapData>;
public var offset:Point;
public var wh:Point;
public function AnimationData()
{
}
public function updateWH():void {
if (wh == null) wh = new Point;
for each(var bmd:BitmapData in bmds) {
wh.x = wh.x < bmd.width?bmd.width:wh.x;
wh.y = wh.y < bmd.height?bmd.height:wh.y;
}
}
}
class BitmapDataSprite extends Sprite
{
public var next:BitmapDataSprite;
public var pre:BitmapDataSprite;
private var image:Bitmap;
private var isPlaying:Boolean = false;
private var currentAnimationName:String;
public var currentAnimationBitmapData:BitmapData;
private var currentAnimationData:AnimationData;
private var _frame:int;
private var animations:Array;
public var bound:Rectangle;
public var gridindexs:Array;
public var onMouseOver:Function;
public var onMouseOut:Function;
private var world:World;
public function BitmapDataSprite(world:World)
{
this.world = world;
}
public function update():void {
if (isPlaying && currentAnimationData) {
currentAnimationBitmapData = currentAnimationData.bmds[currentAnimationData.frames[frame]];
image.bitmapData = currentAnimationBitmapData;
_frame++;
if (frame >= currentAnimationData.frames.length) _frame = 0;
}
}
public function play(name:String, frame:int = 0):void {
isPlaying = true;
_frame = frame;
currentAnimationName = name;
currentAnimationData = animations[name];
if (image == null) image = new Bitmap;
addChild(image);
image.x = currentAnimationData.offset.x;
image.y = currentAnimationData.offset.y;
}
public function stop(name:String, frame:int=0):void {
isPlaying = false;
}
public function addAnimationFromMc(mc:MovieClip, name:String):AnimationData {
return null;
}
public function addAnimationFromSpriteSheet(bmds:Vector.<BitmapData>,frames:Vector.<uint>, offset:Point,name:String):AnimationData {
var ani:AnimationData = new AnimationData;
ani.bmds = bmds;
ani.updateWH();
ani.frames = frames;
ani.name = name;
ani.offset = offset;
if (bound == null) bound = new Rectangle;
if (bound.left > ani.offset.x) bound.left = ani.offset.x;
if (bound.top > ani.offset.y) bound.top = ani.offset.y;
if (bound.right < ani.offset.x + ani.wh.x) bound.right = ani.offset.x + ani.wh.x;
if (bound.bottom < ani.offset.y + ani.wh.y) bound.bottom = ani.offset.y + ani.wh.y;
if (animations==null) animations = [];
animations[name] = ani;
return ani;
}
public function addAnimationFromSpriteSheet2(bmds:Vector.<BitmapData>,frames:Vector.<uint>, offset:Point,name:String):AnimationData {
var ani:AnimationData = new AnimationData;
ani.bmds = bmds;
ani.updateWH();
ani.frames = frames;
ani.name = name;
ani.offset = offset;
if (bound == null) bound = new Rectangle;
if (bound.left > ani.offset.x) bound.left = ani.offset.x;
if (bound.top > ani.offset.y) bound.top = ani.offset.y;
if (bound.right < ani.offset.x + ani.wh.x) bound.right = ani.offset.x + ani.wh.x;
if (bound.bottom < ani.offset.y + ani.wh.y) bound.bottom = ani.offset.y + ani.wh.y;
if (animations==null) animations = [];
animations[name] = ani;
return ani;
}
public function get frame():int
{
return _frame;
}
}
class Particle extends BitmapDataSprite
{
public var vx:Number;
public var vy:Number;
public function Particle(world:World)
{
super(world);
}
}
class World extends BitmapDataSprite
{
private var sprite:BitmapDataSprite;
private var endSprite:BitmapDataSprite;
private var sprites:Array;
private var mouseSprites:Vector.<BitmapDataSprite>;
private var grid:Array;
private var _gridWidth:Number = 123;
private var _gridHeight:Number = 58;
private var firstPoint:Point = new Point;
private var secondObject:Point = new Point;
private var lastMouseSprite:BitmapDataSprite;
public function World()
{
super(null);
sprites = [];
mouseChildren = false;
}
public function add(sprite:BitmapDataSprite,enableMouse:Boolean=false):BitmapDataSprite {
addChild(sprite);
if (this.sprite == null) {
this.sprite = sprite;
}else {
endSprite.next = sprite;
sprite.pre = endSprite;
}
endSprite = sprite;
if (enableMouse) {
addToGrid(sprite);
addEventListener(MouseEvent.MOUSE_MOVE, testGrid);
addEventListener(MouseEvent.MOUSE_OUT, testGrid);
if (mouseSprites == null) mouseSprites = new Vector.<BitmapDataSprite>;
mouseSprites.push(sprite);
}
sprites.push(sprite);
return sprite;
}
public function sortByY():void {
sprites.sortOn("y", Array.NUMERIC);
while (numChildren > 0) {
removeChildAt(0);
}
for each(var s:BitmapDataSprite in sprites) {
addChild(s);
}
}
public function resetGridNoSort():void {
grid = [];
for each(var sprite:BitmapDataSprite in mouseSprites) {
for (var y:int = (sprite.y+sprite.bound.top)/ _gridHeight; y < int((sprite.y+sprite.bound.bottom) / _gridHeight) + 1;y++ ) {
if (grid[y] == null) grid[y] = [];
for (var x:int = (sprite.x+sprite.bound.left) / _gridWidth; x < int((sprite.x+sprite.bound.right) / _gridWidth) + 1;x++ ) {
if (grid[y][x] == null) grid[y][x] = [];
grid[y][x].unshift(sprite);
}
}
}
}
public function addToGrid(sprite:BitmapDataSprite):void {
if (grid == null) grid = [];
if (sprite.gridindexs) {
for (var i:int = 0; i < sprite.gridindexs.length;i+=2 ) {
var x:int = sprite.gridindexs[i];
var y:int = sprite.gridindexs[i + 1];
if (grid[y] && grid[y][x]) {
var index:int = grid[y][x].indexOf(sprite);
if (index != -1) grid[y][x].splice(index, 1);
}
}
}
sprite.gridindexs = [];
for (y = (sprite.y+sprite.bound.top)/ _gridHeight; y < int((sprite.y+sprite.bound.bottom) / _gridHeight) + 1;y++ ) {
if (grid[y] == null) grid[y] = [];
for (x = (sprite.x+sprite.bound.left) / _gridWidth; x < int((sprite.x+sprite.bound.right) / _gridWidth) + 1;x++ ) {
if (grid[y][x] == null) grid[y][x] = [];
var flag:Boolean = true;
for (i = 0; i < grid[y][x].length;i++ ) {
var temp:BitmapDataSprite = grid[y][x][i];
if (getChildIndex(temp)<getChildIndex(sprite)) {
grid[y][x].splice(i, 0, sprite);
flag = false;
break;
}
}
if (flag) grid[y][x].push(sprite);
sprite.gridindexs.push(x, y);
}
}
}
//格子鼠标碰撞检测类
private function testGrid(e:MouseEvent):void
{
var x:int = mouseX / _gridWidth;
var y:int = mouseY / _gridHeight;
var flag:Boolean = false;
if (grid && grid[y] && grid[y][x]) {
for each(var sprite:BitmapDataSprite in grid[y][x]){
var bmd:BitmapData = sprite.currentAnimationBitmapData;
firstPoint.x = sprite.x;
firstPoint.y = sprite.y;
secondObject.x = mouseX;
secondObject.y = mouseY;
if (bmd.hitTest(firstPoint,0,secondObject)) {
if (sprite == lastMouseSprite) {
}else {
if (lastMouseSprite) {
if (lastMouseSprite.onMouseOut!=null) lastMouseSprite.onMouseOut(lastMouseSprite);
}
lastMouseSprite = sprite;
if (lastMouseSprite.onMouseOver!=null) lastMouseSprite.onMouseOver(lastMouseSprite);
}
flag = true;
break;
}
}
}
if (!flag&&lastMouseSprite) {
if (lastMouseSprite.onMouseOut!=null) lastMouseSprite.onMouseOut(lastMouseSprite);
lastMouseSprite = null;
}
}
public function remove(sprite:BitmapDataSprite):BitmapDataSprite {
return null;
}
override public function update():void {
super.update();
var temp:BitmapDataSprite = sprite;
while (temp) {
temp.update();
temp = temp.next;
}
}
public function start():void {
addEventListener(Event.ENTER_FRAME, enterFrame);
}
public function pause():void {
removeEventListener(Event.ENTER_FRAME, enterFrame);
}
private function enterFrame(e:Event):void {
update();
}
public function set gridWidth(value:Number):void
{
_gridWidth = value;
}
public function set gridHeight(value:Number):void
{
_gridHeight = value;
}
}