Beautifl - Flash Gallery

Thumbnail : Tweener で 15 パズル forked from: nengafl
Tweener で 15 パズル forked from: nengafl
feb19 2010-01-07 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

// forked from nengafl's nengafl
package
{
	import flash.display.Graphics;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.utils.getTimer;
	
	import caurina.transitions.Tweener;
	
	/*
	 * Tweener で 15 パズル
	 * @author Nobuhiro Takahashi
	 * 汚いコード選手権
	 */
    [SWF(backgroundColor="#ffffff", frameRate=60)]
	public class The15Puzzle extends Sprite
	{
	    	
		private var _world:Array = [];
		private var _shuffleCnt:int = 0;
		private var _shuffleTurn:int = 0;
		private var _init:Boolean = false;
		private var _timer:int = 0;
		private var _timerSp:Sprite;
		private var _timerTf:TextField;
		private var _shuffle_btn:Sprite;
		public function The15Puzzle()
		{
			var sps:Array = [];
			for (var i:int = 0; i < 15; i++)
			{
				sps.push(createTile());
				sps[i].name = "tile" + i;
				_world.push(sps[i]);
				
				var tfm:TextFormat = new TextFormat();
				tfm.color = 0xffffff;
				var tf:TextField = new TextField();
				tf.defaultTextFormat = tfm;
				tf.autoSize = TextFieldAutoSize.LEFT;
				tf.text = (i + 1).toString();
				sps[i].addChild(tf);
				tf.mouseEnabled = false;
				tf.mouseWheelEnabled = false;
				
				sps[i].buttonMode = true;
				sps[i].mouseChildren = false;
			}
			
			for (i = 0; i < 16; i++)
			{
				if (_world[i])
				{
					_world[i].x = i % 4 * 45;
					_world[i].y = Math.floor(i / 4) * 45;
				}
			}
			
			_shuffle_btn = new Sprite();
			_shuffle_btn.graphics.beginFill(0x660000);
			_shuffle_btn.graphics.drawRect(0, 0, 80, 40);
			_shuffle_btn.graphics.endFill();
			_shuffle_btn.x = 200;
			addChild(_shuffle_btn);
			_shuffle_btn.addEventListener(MouseEvent.CLICK, clickHandler2);
			_shuffle_btn.mouseChildren = false;
			
			var f:TextFormat = new TextFormat();
			f.color = 0xffffff;
			var t:TextField = new TextField();
			t.defaultTextFormat = f;
			t.autoSize = TextFieldAutoSize.LEFT;
			t.text = "START";
			t.selectable = false;
			_shuffle_btn.addChild(t);
			
			_timerTf = new TextField();
			_timerTf.selectable = false;
			addChild(_timerTf);
			_timerTf.x = 200;
			_timerTf.y = 50;
			_timerTf.text = "0 ms";
			_timerSp = new Sprite();
		}
		private function clickHandler2(event:MouseEvent):void
		{
			_shuffleCnt = 0;
			addEventListener(Event.ENTER_FRAME, enterFrameHandler);
			
			_timerTf.text = "0 ms";
			for (var i:int = 0; i < 16; i++)
			{
				if (_world[i])
				{
					_world[i].buttonMode = false;
					_world[i].removeEventListener(MouseEvent.CLICK, clickHandler);
				}
			}
			
			_shuffle_btn.buttonMode = false;
			_shuffle_btn.removeEventListener(MouseEvent.CLICK, clickHandler2);
			
			_timerSp.removeEventListener(Event.ENTER_FRAME, enterFrameHandler2);
		}
		
		private function enterFrameHandler2(evnet:Event):void
		{
			_timerTf.text = int(getTimer() - _timer) + " ms";
		}
		
		private function enterFrameHandler(event:Event):void
		{
			var i:int;
			if (_shuffleCnt >= 500)
			{
				removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
				
				_shuffle_btn.buttonMode = true;
				_shuffle_btn.addEventListener(MouseEvent.CLICK, clickHandler2);
				
				for (i = 0; i < 16; i++)
				{
					if (_world[i])
					{
						_world[i].buttonMode = true;
						_world[i].addEventListener(MouseEvent.CLICK, clickHandler);
					}
				}
				_init = true;
				_timer = getTimer();
				_timerSp.addEventListener(Event.ENTER_FRAME, enterFrameHandler2);
			}
			if (_shuffleCnt % 5 == 0)
			{
				var num:int = 0;
				for (i = 0; i < 16; i++)
				{
					if (!_world[i])
					{
						num = i;
						break;
					}
				}
				var t:Array = [];
				var n:int = 0;
				do
				{
					if (_shuffleTurn % 2 == 0)
					{
						switch(num % 4)
						{
							case 0:	t = [0, 4, 8, 12];	break;
							case 1:	t = [1, 5, 9, 13];	break;
							case 2:	t = [2, 6, 10, 14];	break;
							case 3:	t = [3, 7, 11, 15];	break;
						}
					}
					else
					{
						switch(Math.floor(num / 4))
						{
							case 0:	t = [0, 1, 2, 3];	break;
							case 1:	t = [4, 5, 6, 7];	break;
							case 2:	t = [8, 9, 10, 11];	break;
							case 3:	t = [12, 13, 14, 15];	break;
						}
					}
					
					n = t[Math.floor(t.length * Math.random())];
				}
				while (!_world[n]);
				_shuffleTurn++;
				
				if(_world[n])
					moveTile(_world[n]);
			}
			_shuffleCnt++;
		}
		
		private function createTile():Sprite
		{
			var sp:Sprite = new Sprite();
			var g:Graphics = sp.graphics;
			g.lineStyle(0, 0xffffff);
			g.beginFill(0x000000);
			g.drawRect(0, 0, 40, 40);
			g.endFill();
			addChild(sp);
			
			sp.addEventListener(MouseEvent.CLICK, clickHandler);
			
			return sp;
		}
		
		private function clickHandler(event:MouseEvent):void
		{
			var target:Sprite = Sprite(event.currentTarget);
			moveTile(target);
		}
		private function moveTile(target:Sprite):void
		{
			var name:String = target.name.substr(4);
			for (var i:int = 0; i < 16; i++)
			{
				if (_world[i] == target)
				{
					checkVertical(i);
					checkHorizon(i);
					
					for (var j:int = 0; j < 16; j++)
					{
						if (_world[j])
						{
							Tweener.addTween(_world[j], { time:.2, x:j % 4 * 45, y:Math.floor(j / 4) * 45, transition:"easeOutQuint" } );
						}
					}
					break;
				}
			}
			
			checkWorld();
		}
		private function checkVertical(i:int):void
		{
			if (i <= 3)
			{
				if (!_world[i + 12])
				{
					_world[i + 12] = _world[i + 8];
					_world[i + 8] = _world[i + 4];
					_world[i + 4] = _world[i];
					_world[i] = null;
				}
				else if (!_world[i + 8])
				{
					_world[i + 8] = _world[i + 4];
					_world[i + 4] = _world[i];
					_world[i] = null;
				}
				else if (!_world[i + 4])
				{
					_world[i + 4] = _world[i];
					_world[i] = null;
				}
			}
			else if (i >= 12)
			{
				if (!_world[i - 12])
				{
					_world[i - 12] = _world[i - 8];
					_world[i - 8] = _world[i - 4];
					_world[i - 4] = _world[i];
					_world[i] = null;
				}
				else if (!_world[i - 8])
				{
					_world[i - 8] = _world[i - 4];
					_world[i - 4] = _world[i];
					_world[i] = null;
				}
				else if (!_world[i - 4])
				{
					_world[i - 4] = _world[i];
					_world[i] = null;
				}
			}
			else if (i >= 4 && i <= 7)
			{
				if (!_world[i - 4])
				{
					_world[i - 4] = _world[i];
					_world[i] = null;
				}
				else if (!_world[i + 8])
				{
					_world[i + 8] = _world[i + 4];
					_world[i + 4] = _world[i];
					_world[i] = null;
				}
				else if (!_world[i + 4])
				{
					_world[i + 4] = _world[i];
					_world[i] = null;
				}
			}
			else if (i >= 8 && i <= 11)
			{
				if (!_world[i - 8])
				{
					_world[i - 8] = _world[i - 4];
					_world[i - 4] = _world[i];
					_world[i] = null;
				}
				else if (!_world[i - 4])
				{
					_world[i - 4] = _world[i];
					_world[i] = null;
				}
				else if (!_world[i + 4])
				{
					_world[i + 4] = _world[i];
					_world[i] = null;
				}
			}
		}
		
		private function checkHorizon(i:int):void
		{
			var n:int = i % 4;
			
			if (n == 0)
			{
				if (!_world[i + 3])
				{
					_world[i + 3] = _world[i + 2];
					_world[i + 2] = _world[i + 1];
					_world[i + 1] = _world[i];
					_world[i] = null;
				}
				else if (!_world[i + 2])
				{
					_world[i + 2] = _world[i + 1];
					_world[i + 1] = _world[i];
					_world[i] = null;
				}
				else if (!_world[i + 1])
				{
					_world[i + 1] = _world[i];
					_world[i] = null;
				}
			}
			else if (n == 3)
			{
				if (!_world[i - 3])
				{
					_world[i - 3] = _world[i - 2];
					_world[i - 2] = _world[i - 1];
					_world[i - 1] = _world[i];
					_world[i] = null;
				}
				else if (!_world[i - 2])
				{
					_world[i - 2] = _world[i - 1];
					_world[i - 1] = _world[i];
					_world[i] = null;
				}
				else if (!_world[i - 1])
				{
					_world[i - 1] = _world[i];
					_world[i] = null;
				}
			}
			else if (n == 1)
			{
				if (!_world[i - 1])
				{
					_world[i - 1] = _world[i];
					_world[i] = null;
				}
				else if (!_world[i + 2])
				{
					_world[i + 2] = _world[i + 1];
					_world[i + 1] = _world[i];
					_world[i] = null;
				}
				else if (!_world[i + 1])
				{
					_world[i + 1] = _world[i];
					_world[i] = null;
				}
			}
			else if (n == 2)
			{
				if (!_world[i - 2])
				{
					_world[i - 2] = _world[i - 1];
					_world[i - 1] = _world[i];
					_world[i] = null;
				}
				else if (!_world[i - 1])
				{
					_world[i - 1] = _world[i];
					_world[i] = null;
				}
				else if (!_world[i + 1])
				{
					_world[i + 1] = _world[i];
					_world[i] = null;
				}
			}
		}
		
		private function checkWorld():void
		{
			var isComplete:Boolean = true;
			for (var i:int = 0; i < 15; i++)
			{
				if (!_world[i] || int(_world[i].name.substr(4)) != i)
				{
					isComplete = false;
					break;
				}
			}
			
			if (isComplete)
			{
				_init = false;
				_timerSp.removeEventListener(Event.ENTER_FRAME, enterFrameHandler2);
			}
		}
    }
}