forked from: forked from: 99 puzzle
// forked from vasylbo's forked from: 99 puzzle
// forked from ngs's 99 puzzle
package {
import flash.display.Sprite;
import flash.net.URLRequest;
import flash.events.Event;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.geom.Matrix;
import flash.system.LoaderContext;
public class NinetyNinePuzzle extends Sprite {
public var puzzle:SlidingBlockPuzzle;
private var loader:Loader;
public static const IMGURL:String = "http://farm7.staticflickr.com/6092/6317168165_80b32f0300.jpg";
public static const W:uint = 465, H:uint = 465;
public function NinetyNinePuzzle() {
addEventListener(Event.ADDED_TO_STAGE,init);
}
private function init(e:Event):void {
loader = new Loader();
var context:LoaderContext = new LoaderContext(true);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onImageLoaded);
loader.load(new URLRequest(IMGURL),context);
}
private function onImageLoaded(e:Event):void {
var source:BitmapData = new BitmapData(W,H,false);
var sx:Number = W / loader.width;
var sy:Number = H / loader.height;
if (sx > sy)
source.draw(loader, new Matrix(sx, 0, 0, sx, 0, (H - loader.height * sx) / 2), null, null, null, true);
else
source.draw(loader, new Matrix(sy, 0, 0, sy, (W - loader.width * sy) / 2, 0), null, null, null, true);
puzzle = new SlidingBlockPuzzle(source,3,3,9);
Block.border = 0;
addChild(puzzle);
}
}
}
import flash.display.Sprite;
import flash.display.BitmapData;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import caurina.transitions.Tweener;
class SlidingBlockPuzzle extends Sprite {
public var board:Array,difficult:uint;
private var _skip:uint,_src:BitmapData,dummy:Sprite,_cols:uint,_rows:uint;
public function SlidingBlockPuzzle(src:BitmapData,cols:uint,rows:uint,skip:uint) {
_cols = cols; _rows = rows; _skip = skip; _src = src;
dummy = new Sprite();
dummy.graphics.beginFill(0,0);
dummy.graphics.drawRect(0,0,src.width,src.height);
dummy.graphics.endFill();
addChild(dummy);
addEventListener(Event.ADDED_TO_STAGE,init);
}
public function get skip():uint { return _skip; }
public function get cols():uint { return _cols; }
public function get rows():uint { return _rows; }
public function get src():BitmapData { return _src; }
private function init(e:Event=null):void {
board = [];
width = src.width;
height = src.height;
var k:uint,i:uint,j:uint=cols-1;
for(k=1;k<=cols*rows;++k) {
var p:Block = new Block(k,this);
addChild(p);
board.push(p);
}
addChild(dummy);
difficult = difficult || cols*(rows+1)*2;
for(k=0;k<difficult;k++) {
i = ~~(Math.random()*cols);
shift(i,j);
j = ~~(Math.random()*rows);
shift(i,j);
}
addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void {
shift(e.localX/(src.width/cols), e.localY/(src.height/rows));
repaint();
});
repaint(true);
removeEventListener(Event.ADDED_TO_STAGE,init);
}
private function shift(x:uint,y:uint):void {
if (x>=0&&x<cols&&y>=0&&y<rows) {
for (var i:int=0;i<rows;++i) {
var p:Block = board[y*rows+i];
if (p.skip) {
for (; i>x; --i)
board[y*rows+i] = board[y*rows+i-1];
for (; i<x; ++i)
board[y*rows+i] = board[y*rows+i+1];
board[y*rows+x] = p;
return;
}
}
for (var j:int = 0; j<cols; ++j) {
p = board[j*cols+x];
if (p.skip) {
for (; j>y; --j)
board[j*cols+x] = board[(j-1)*cols+x];
for (; j<y; ++j)
board[j*cols+x] = board[(j+1)*cols+x];
board[y*cols+x] = p;
return;
}
}
}
}
private function checkComplete(e:Event=null):void {
for(var i:uint=1;i<=board.length;++i) {
var p:Block = board[i-1];
if(p.value!=i) return;
}
dispatchEvent(new Event(Event.COMPLETE));
}
private function repaint(notween:Boolean=false):void {
for (var j:int=0;j<rows;++j) {
for (var i:int=0;i<cols;++i) {
var p:Block = board[j*cols+i];
var tgx:uint = uint(i*src.width/cols);
var tgy:uint = uint(j*src.height/rows);
if(notween) {
p.x = tgx; p.y = tgy;
} else
Tweener.addTween(p, {x:tgx, y:tgy, time:0.1, transition:"easeOutQuad",onComplete:!(j+i)?checkComplete:null});
}
}
}
}
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.geom.Rectangle;
import flash.geom.Point;
class Block extends Sprite {
public var value:uint;
public var skip:Boolean;
public static var border:uint = 1;
public static var embossBitmapData:BitmapData = null;
public function Block(value:uint,puzzle:SlidingBlockPuzzle) {
this.value = value;
this.skip = puzzle.skip == value;
var src:BitmapData = puzzle.src;
if(skip) return;
var w:uint = ~~(src.width/puzzle.cols);
var h:uint = ~~(src.height/puzzle.rows);
var bitmap:BitmapData = new BitmapData(w-border*2, h-border*2, false);
var rect:Rectangle = new Rectangle((value-1)%puzzle.cols*w+border, Math.floor((value-1)/puzzle.rows)*h+border, w-border*2, h-border*2);
bitmap.copyPixels(src, rect, new Point());
var bmp:Bitmap = new Bitmap(bitmap);
bmp.x = border; bmp.y = border;
addChild(bmp);
if(embossBitmapData) {
addChild(new Bitmap(embossBitmapData));
}
}
}