In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

ナンバーパズル

Get Adobe Flash player
by yamadori 03 Dec 2010
/**
 * Copyright yamadori ( http://wonderfl.net/user/yamadori )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/pRru
 */

/*
数字を順番に並べ替えるあのパズルです。
空白に隣接してるパネルをクリックすると移動します。
また、NumericStepperで縦横の数を調整出来ます。
(縦横ともに最小2、最大5)
RESETボタンで配置し直します。
*/

package
{
    import flash.display.Sprite;
    import com.bit101.components.NumericStepper;
    import com.bit101.components.Label;
    import com.bit101.components.PushButton;
    import flash.events.Event;

    public class Main extends Sprite
    {
        private var board:Board;
        
        private var wNum:NumericStepper;
        private var hNum:NumericStepper;
        
        public function Main()
        {
            graphics.beginFill(0xFFFFFF);
            graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
            board = new Board();
            addChild(board);
            board.x = 20;
            board.y = 20;
            
            wNum = new NumericStepper(this, 20);
            hNum = new NumericStepper(this);
            wNum.scaleX = wNum.scaleY = hNum.scaleX = hNum.scaleY = 1.2;
            hNum.x = wNum.x + wNum.width*wNum.scaleX + 20;
            wNum.y = hNum.y = stage.stageHeight - wNum.height*wNum.scaleY - 20;
            wNum.minimum = hNum.minimum = 2;
            wNum.maximum = hNum.maximum = 5;
            
            var wLabel:Label = new Label(this, 20, 0, "wNum");
            var hLabel:Label = new Label(this, hNum.x, 0, "hNum");
            wLabel.scaleX = wLabel.scaleY = hLabel.scaleX = hLabel.scaleY = 1.5;
            wLabel.y = hLabel.y = wNum.y - wLabel.height*wLabel.scaleY;
            
            var button:PushButton = new PushButton(this, 0, 0, "RESET", reset);
            button.scaleX = button.scaleY = 1;
            button.x = hNum.x + hNum.width*hNum.scaleX + 20;
            button.y = stage.stageHeight - button.height*button.scaleY - 20;
        }
        
        private function reset(e:Event = null):void
        {
            board.wNum = wNum.value;
            board.hNum = hNum.value;
            board.init();
        }
    }
}

import flash.display.Sprite;
import flash.filters.BevelFilter;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.events.MouseEvent;
import frocessing.math.Random;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.tweens.ITween;
import com.bit101.components.Label;
import flash.events.Event;

class Board extends Sprite
{
    public var wNum:int = 4;
    public var hNum:int = 4;
    
    private var tiles:Array;
    private var clickable:Boolean;
    private var playable:Boolean;
    
    public function Board()
    {
        init();
    }
    
    public function init():void
    {
        playable = false;
        
        graphics.clear();
        graphics.beginFill(0xC0C0C0);
        graphics.drawRect(0,0,Tile.SIZE*wNum, Tile.SIZE*hNum);
        
        while(numChildren > 0)
        {
            removeChild(getChildAt(0));
        }
        
        tiles = [];
        for(var i:int = 0; i<hNum; i++)
        {
            tiles[i] = [];
            for(var j:int = 0; j<wNum; j++)
            {
                if(!(i == hNum-1 && j == wNum-1))
                {
                    var tile:Tile = new Tile(i*wNum+(j+1));
                    tile.x = j*Tile.SIZE;
                    tile.y = i*Tile.SIZE;
                    addChild(tile);
                    tiles[i][j] = tile;
                }
            }
        }
        
        shuffle(wNum*hNum*3);
        
        playable = true;
        clickable = true;
        
        addEventListener(MouseEvent.CLICK, onClick);
    }
    
    private function onClick(e:MouseEvent):void
    {
        if(!clickable) return;
        
        var tx:int = mouseX/Tile.SIZE;
        var ty:int = mouseY/Tile.SIZE;
        
        if(!onBoard(tx, ty) || tiles[ty][tx] == null) return;
        
        searchArround(tx,ty)
    }
    
    // (x, y)がboard上にあるか
    private function onBoard(x:int, y:int):Boolean
    {
        if(x<0 || wNum<=x || y<0 || hNum<=y) return false;
        return true;
    }
    
    // (x, y)の上下左右に空白があるか調べる
    private function searchArround(x:int, y:int):void
    {
        if(searchSpace(x, y-1)) changePosition(x, y, x, y-1);
        if(searchSpace(x+1, y)) changePosition(x, y, x+1, y);
        if(searchSpace(x, y+1)) changePosition(x, y, x, y+1);
        if(searchSpace(x-1, y)) changePosition(x, y, x-1, y);
    }
    
    // (x, y)が空白か
    private function searchSpace(x:int, y:int):Boolean
    {
        if(!onBoard(x, y)) return false;
        if(tiles[y][x] == null) return true;
        return false;
    }
    
    // (x, y)と空白(tx, ty)を入れ替える
    private function changePosition(x:int, y:int, tx:int, ty:int):void
    {
        clickable = false;
        
        if(playable)
        {
            var t:ITween = BetweenAS3.tween(tiles[y][x], {x:tx*Tile.SIZE, y:ty*Tile.SIZE}, null, 0.1);
            t.play();
            t.onComplete = onComplete;
        }
        // shuffleではtweenさせない
        else
        {
            tiles[y][x].x = tx*Tile.SIZE;
            tiles[y][x].y = ty*Tile.SIZE;
        }
        tiles[ty][tx] = tiles[y][x];
        tiles[y][x] = null;
    }
    
    // times回shuffle
    private function shuffle(times:int):void
    {
        const DIR:Array = [
                           [0, -1],
                           [1, 0],
                           [0, 1],
                           [-1, 0],
                          ];
        // 空白の初期値
        var x:int = wNum-1;
        var y:int = hNum-1;
        
        for(var i:int = 0; i<times; i++) {
            
            var random:Array = Random.shakedIntegers(4);
            
            // 空白を基準にrandomで上下左右調べ、そこがboard上であれば入れ替える
            for(var j:int = 0; j<random.length; j++)
            {
                var dx:int = DIR[random[j]][0];
                var dy:int = DIR[random[j]][1];
                
                if(!onBoard(x+dx, y+dy)) continue;
                changePosition(x+dx, y+dy, x, y);
                x = x+dx;
                y = y+dy;
                break;
            }
        }
    }
    
    // 順番が正しいか
    private function checkCorrect():Boolean
    {
        if(!(tiles[hNum-1][wNum-1] == null)) return false;
        for(var i:int = 0; i<hNum; i++)
        {
            for(var j:int = 0; j<wNum; j++)
            {
                if(i == hNum-1 && j == wNum-1) continue;
                if(!(tiles[i][j].number == i*wNum+(j+1))) return false;
            }
        }
        return true;
    }
    
    private function onComplete():void
    {
        clickable = true;
        
        if(checkCorrect())
        {
            clickable = false;
            trace("GAME CLEAR!");
            var txt:Label = new Label(this, 0, 0, "GAME CLEAR!");
            txt.scaleX = txt.scaleY = 5;
            txt.x = this.parent.width/2 - txt.width/2*txt.scaleX - 10;
            txt.y = this.parent.height/2 - txt.height/2*txt.scaleY - 10;
        }
    }
}

class Tile extends Sprite
{
    public static const SIZE:int = 70;
    public var number:int;
    
    public function Tile(number:int)
    {
        this.number = number;
        
        graphics.beginFill(0xEEEEEE);
        graphics.drawRect(0, 0, SIZE, SIZE);
        graphics.endFill();
        
        var tf:TextField = new TextField();
        tf.defaultTextFormat = new TextFormat("_ゴシック", 36);
        tf.text = String(number);
        tf.autoSize = "left";
        tf.selectable = false;
        //tf.border = true;
        addChild(tf);
        tf.x = SIZE/2 - tf.width/2;
        tf.y = SIZE/2 - tf.height/2 - 2;
        
        this.filters = [new BevelFilter(5, 45, 0xFFFFFF, 0.5, 0x0, 0.5, 5, 5, 1, 3)];
    }
}