Flex Builder3でFlexとかActionScriptの勉強をしているわけですが、
15パズルを作りたくなったので作ってみました。
最低限の機能はできたのでVer.0.1としてあげます。
制作にあたっては、こちらの記事とこちらの本を参考にさせてもらいました。
ドラッグ&ドロップで自動的に画像を16分割します。
画像ファイルそのままの大きさで16分割するので大きい画像はパズルに向かないかも。
今後そういうとこを直して機能を追加していこうと思ってます。
ソースコードは↓
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" nativeDragEnter="onDragEnter(event);" nativeDragDrop="onDragDrop(event);" width="500" height="400" viewSourceURL="srcview/index.html"> <mx:MenuBar labelField="@label" itemClick="useFile(event)" width="100%" id="myMenu"> <mx:dataProvider> <mx:XMLList> <Menu label="操作"> <MenuItem label="スタート" /> </Menu> </mx:XMLList> </mx:dataProvider> </mx:MenuBar> <mx:Image id="myImage" width="100%" height="100%" /> <mx:Script> <![CDATA[ import mx.controls.Alert; import mx.events.MenuEvent; // 画像のロード判定用 private var loadEnd:Boolean = false; private var file_ary:Array; // 1ピースの幅 private var pieceWidth:Number; // 1ピースの高さ private var pieceHeight:Number; // 空ピースの番号 private var empty:int; // 完成確認用配列 private var order:Array = new Array(); // メニュー用の関数 private function useFile(e:MenuEvent):void { if(e.label == "スタート") { shuffle(); } } // ドラッグ&ドロップでロード private function onDragEnter(event:NativeDragEvent):void { trace("entered"); var cb:Clipboard = event.clipboard; if(cb.hasFormat(ClipboardFormats.FILE_LIST_FORMAT)) { // ドロップを許可 NativeDragManager.acceptDragDrop(this); } } private function onDragDrop(event:NativeDragEvent):void { if(loadEnd) { for(var i:uint = 0; i <= 15; i++) { myImage.removeChild(myImage.getChildByName(String(i))); } } var cb:Clipboard = event.clipboard; file_ary = cb.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array; trace("ファイル名:" + File(file_ary[0]).name); LoaderRequest(); } private function LoaderRequest():void { var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, LoadCompleted); var request:URLRequest = new URLRequest(File(file_ary[0]).url); loader.load(request); } private function LoadCompleted(event:Event):void { // 画像はBitmapでロード var bitmapImage:Bitmap = Bitmap(event.target.loader.content); empty = 15; pieceWidth = bitmapImage.width / 4; pieceHeight = bitmapImage.height / 4; //ピース並べ for(var i:uint = 0; i < 15; i++) { // ピースと同じ大きさのビットマップをつくる var newPieceBitmap:Bitmap = new Bitmap(new BitmapData(pieceWidth, pieceHeight)); // ロードした画像から新しく作ったビットマップにコピー newPieceBitmap.bitmapData.copyPixels(bitmapImage.bitmapData, new Rectangle((i % 4) * pieceWidth, Math.floor(i / 4) * pieceHeight, pieceWidth, pieceHeight), new Point(0, 0)); // ピースの描画 var newPiece:Sprite = new Sprite(); newPiece.addChild(newPieceBitmap); newPiece.width = pieceWidth; newPiece.height = pieceHeight; newPiece.x = (i % 4) * (pieceWidth + 5) + 20; newPiece.y = Math.floor(i / 4) * (pieceHeight + 5) + 30; newPiece.name = String(i); newPiece.addEventListener(MouseEvent.CLICK, click); myImage.addChild(newPiece); } // 空ピースは白い長方形 var emptyPieace:Sprite = new Sprite(); emptyPieace.graphics.beginFill(0xffffff); emptyPieace.x = 3 * (pieceWidth + 5) + 20; emptyPieace.y = Math.floor(3) * (pieceHeight + 5) + 30; emptyPieace.graphics.drawRect(0, 0, pieceWidth, pieceHeight); emptyPieace.graphics.endFill(); emptyPieace.name = String(15); myImage.addChild(emptyPieace); // 完成判定のためIndexをセット for(var j:uint = 0; j <= 15; j++) { myImage.setChildIndex(myImage.getChildByName(String(j)), j); } // ピクチャの大きさに合わせてウィンドウの大きさを変更 nativeWindow.width = bitmapImage.width + 60; nativeWindow.height = bitmapImage.height + 105; loadEnd = true; } // ランダムシャッフル private function shuffle():void { var count:uint = 10000; var imgNum:uint; for(var i:uint = 0; i < count; i++) { imgNum = Math.floor(Math.random() * 15); if(checkMove(imgNum)) { pieceMove(imgNum); } } } // ピースクリック時の処理 private function click(event:MouseEvent):void { //ピースの番号 var pieaceNumber:int = event.currentTarget.name; trace("click:" + pieaceNumber); if(checkMove(pieaceNumber)) { pieceMove(pieaceNumber); } } // ピースが動かせるかチェック private function checkMove(pieaceNumber:int):Boolean { var result:Boolean = false; if((pieaceNumber == (empty - 4)) || (pieaceNumber == (empty + 4))) result = true; else if(((pieaceNumber % 4) != 0) && ((pieaceNumber - 1) == empty)) result = true; else if(((pieaceNumber % 4) != 3) && ((pieaceNumber + 1) == empty)) result = true; return result; } // ピース移動 private function pieceMove(pieaceNumber:int):void { var oldEmpty:int = empty; empty = pieaceNumber; myImage.getChildByName(String(oldEmpty)).x = (pieceWidth + 5) * (pieaceNumber % 4) + 20; myImage.getChildByName(String(oldEmpty)).y = (pieceHeight + 5) * Math.floor(pieaceNumber / 4) + 30; myImage.getChildByName(String(oldEmpty)).name = String(pieaceNumber); myImage.getChildByName(String(pieaceNumber)).x = (pieceWidth + 5) * (oldEmpty % 4) + 20; myImage.getChildByName(String(pieaceNumber)).y = (pieceHeight + 5) * Math.floor(oldEmpty / 4) + 30; myImage.getChildByName(String(pieaceNumber)).name = String(oldEmpty); indexExchange(pieaceNumber); } // Index交換用関数 private function indexExchange(index:int):void { var indexTemp:int; indexTemp = myImage.getChildIndex(myImage.getChildByName(String(index))); myImage.setChildIndex(myImage.getChildAt(myImage.getChildIndex(myImage.getChildByName(String(index)))), myImage.getChildIndex(myImage.getChildByName(String(empty)))); myImage.setChildIndex(myImage.getChildAt(myImage.getChildIndex(myImage.getChildByName(String(empty)))), indexTemp); // ピース合わせ確認 checkComplete(); } // 完成判定関数 private function checkComplete():void { var complete:Boolean = true; for(var i:uint = 0; i < 15; i++) { if(!(i == myImage.getChildIndex(myImage.getChildByName(String(i))))) { // 不一致があった場合 complete = false; } } // 全て一致した場合 if(complete) { trace("Complete!"); var alert:Alert = Alert.show("complete"); alert.isPopUp = false; alert.cacheAsBitmap = true; } } ]]> </mx:Script> </mx:WindowedApplication>
---------------------------------
2009/9/4 追記
AIRファイルのダウンロードは、Ver.0.1を間違えて消してしまったためVer.0.15のみです。
上のリンクからたどるか、こちらからDLできます。
0 件のコメント:
コメントを投稿