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

CharacterSprite Viewer

キャラクターチップ(歩行グラフィック)を取り込んで表示する、簡易ビューワーです。 
各パラメータをもとに、カーソルキーで操作できるキャラクタースプライトを生成します。

各コンポーネントの役割
-importボタン キャラクターチップの読み込み
-元画像の表示倍率を変更
-透過色を指定するピッカー(元画像にマウスを乗せると、マウス位置にある色がピックアップされるので、透過させたい色のところでクリックで決定)
-アニメーション列の分割数
-方向行を、プリセットまたは個別に指定
-フレームレートの変更
-キャラクターの移動量の変更

まとめ
http://d.hatena.ne.jp/nenjiru/20110914/charachip_viewer
/**
 * Copyright nenjiru ( http://wonderfl.net/user/nenjiru )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/gZyx
 */

package 
{
    import com.bit101.components.ComboBox;
    import com.bit101.components.NumericStepper;
    import com.bit101.components.PushButton;
    import com.bit101.components.Style;
    import flash.display.Bitmap;
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.net.FileFilter;
    import flash.net.FileReference;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;
    
    [SWF(frameRate="60", width="465", height="465")]
    
    /**
     * キャラクタースプライト簡易ビューワー
     * 
     * @author nenjiru
     */
    public class CharacterSpriteViewer extends Sprite 
    {
        private static const URL:String = "http://assets.wonderfl.net/images/related_images/c/c7/c7e1/c7e1afcd9030542ec89c8639ee2acc9d529d0cea";
        private static const PRESET_A:Vector.<String> = Vector.<String>(["front", "left", "right", "back"]);
        private static const PRESET_B:Vector.<String> = Vector.<String>(["back", "right", "front", "left"]);
        
        private var rowIndex:Vector.<String>;
        
        private var source:Bitmap;
        private var canvas:GridCanvas;
        private var character:Player;
        
        private var colStepper:NumericStepper;
        private var rowPreset:ComboBox;
        private var rowSelector:Vector.<RowSelectButton>;
        private var zoom1:PushButton;
        private var zoom2:PushButton;
        private var colorChip:ColorChip;
        private var colorMonitor:ColorMonitor;
        private var frameRate:NumSlider;
        private var speedRate:NumSlider;
        
        public function CharacterSpriteViewer():void 
        {
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.align = StageAlign.TOP_LEFT;
            
            //Style.BUTTON_DOWN = 0xBCBCBC;
            
            var loader:Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);
            loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, trace);
            loader.load(new URLRequest(URL), new LoaderContext(true));
            
            var file:FileReference = new FileReference();
            file.addEventListener(Event.COMPLETE, function (event:Event):void 
            {
                loader.loadBytes((event.currentTarget as FileReference).data);
            });
            file.addEventListener(Event.SELECT, function (event:Event):void 
            {
                file.load();
            });
            
            var importButton:PushButton = new PushButton(this, 5, 5, "import");
            importButton.setSize(70, 16);
            importButton.addEventListener(MouseEvent.CLICK, function ():void 
            {
                file.browse([new FileFilter("Image", "*.jpg;*.jpeg;*.gif;*.png")]);
            });
            
            init();
        }
        
        /**
         * コンポーネント系の初期化
         */
        private function init():void 
        {
            zoom1 = new PushButton(this, 81, 5, "x1");
            zoom1.toggle = true;
            zoom1.setSize(30, 16);
            zoom1.addEventListener(MouseEvent.CLICK, function (e:MouseEvent):void 
            {
                source.scaleX = source.scaleY = 1;
                canvasUpdate();
                zoom2.selected = false;
            });
            
            zoom2 = new PushButton(this, 110, 5, "x2");
            zoom2.toggle = true;
            zoom2.setSize(30, 16);
            zoom2.addEventListener(MouseEvent.CLICK, function (e:MouseEvent):void 
            {
                source.scaleX = source.scaleY = 2;
                canvasUpdate();
                zoom1.selected = false;
            });
            
            colorChip = addChild(new ColorChip()) as ColorChip;
            
            colorMonitor = addChild(new ColorMonitor()) as ColorMonitor;
            colorMonitor.addEventListener(Event.CHANGE, colorHandler);
            colorMonitor.x = 74;
            colorMonitor.y = 35;
            
            colStepper = new NumericStepper(this, 5, 56);
            colStepper.setSize(60, 16);
            colStepper.minimum = 1;
            colStepper.addEventListener(Event.CHANGE, colStepHandler);
            
            rowSelector = Vector.<RowSelectButton>([
                new RowSelectButton(this, 5, 80, rowSelectHandler),
                new RowSelectButton(this, 5, 100, rowSelectHandler),
                new RowSelectButton(this, 5, 120, rowSelectHandler),
                new RowSelectButton(this, 5, 140, rowSelectHandler)
            ]);
            
            rowPreset = new ComboBox(this, 70, 56, "PRESET A", ["PRESET A", "PRESET B"]);
            rowPreset.setSize(70, 16);
            rowPreset.addEventListener(Event.SELECT, rowPresetHandler);
            rowPreset.numVisibleItems = 2;
            
            frameRate = addChild(new NumSlider("FPS ", 1, 60)) as  NumSlider;
            frameRate.addEventListener(Event.CHANGE, frameRateHandler);
            frameRate.x = 30;
            frameRate.y = 165;
            
            speedRate = addChild(new NumSlider("SPEED ", 1, 10)) as  NumSlider;
            speedRate.addEventListener(Event.CHANGE, speedRateHandler);
            speedRate.x = 30;
            speedRate.y = 180;
            
            canvas = addChild(new GridCanvas()) as GridCanvas;
            canvas.x = 150;
            canvas.y = 5;
            
            canvas.addEventListener(MouseEvent.MOUSE_OVER, colorPickerEnable);
            canvas.addEventListener(MouseEvent.MOUSE_OUT, colorPickerEnable);
            canvas.addEventListener(MouseEvent.MOUSE_MOVE, colorPickerHandler);
            canvas.addEventListener(MouseEvent.MOUSE_DOWN, getMaskColor);
        }
        
        /**
         * 画像の読み込み完了
         */
        private function loaded(event:Event):void 
        {
            var loaderInfo:LoaderInfo = event.target as LoaderInfo;
            
            colStepper.value = 3;
            colorMonitor.value = 0xFF99CC33;
            frameRate.value = 12;
            speedRate.value = 4;
            
            source = loaderInfo.content as Bitmap;
            canvas.setBitmap(source);
            canvasUpdate();
            
            zoom2.selected = true;
            zoom2.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
            
            colStepper.maximum = source.width / 4;
            rowPreset.selectedIndex = 0;
        }
        
        /**
         * グリッドと塗りを更新
         */
        private function canvasUpdate():void 
        {
            canvas.drawGrid(source.width, source.height, 4, colStepper.value);
        }
        
        /**
         * キャラクターの生成
         */
        private function createCharacter():void 
        {
            var posX:Number, posY:Number;
            
            if (character)
            {
                character.stop();
                stage.removeEventListener(KeyboardEvent.KEY_DOWN, character.keyDownHandler);
                stage.removeEventListener(KeyboardEvent.KEY_UP, character.keyUpHandler);
                removeChild(character);
                posX = character.x;
                posY = character.y;
            }
            
            var chip:CharacterBitmap = new CharacterBitmap(source.bitmapData, 4, colStepper.value, colorMonitor.value);
            
            character = new Player(chip, frameRate.value, rowIndex, speedRate.value);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, character.keyDownHandler);
            stage.addEventListener(KeyboardEvent.KEY_UP, character.keyUpHandler);
            character.x = posX || (465 - character.width) >> 1;
            character.y = posY || (465 - character.height) >> 1;
            character.start();
            
            addChild(character);
        }
        
        /**
         * 列変更
         */
        private function colStepHandler(event:Event):void 
        {
            canvasUpdate();
            createCharacter();
        }
        
        /**
         * 行プリセット
         */
        private function rowPresetHandler(event:Event):void 
        {
            switch (rowPreset.selectedIndex) 
            {
                case 0:
                    rowIndex = PRESET_A;
                    rowSelector[0].selectIndex = 0;
                    rowSelector[1].selectIndex = 1;
                    rowSelector[2].selectIndex = 2;
                    rowSelector[3].selectIndex = 3;
                break;
                case 1:
                    rowIndex = PRESET_B;
                    rowSelector[0].selectIndex = 3;
                    rowSelector[1].selectIndex = 1;
                    rowSelector[2].selectIndex = 2;
                    rowSelector[3].selectIndex = 0;
                break;
            }
            
            createCharacter();
        }
        
        /**
         * 行設定のトグル変更
         */
        private function rowSelectHandler(target:RowSelectButton):void 
        {
            var index:Array = [];
            
            for (var i:int = 0, n:int = rowSelector.length; i < n; i++) 
            {
                if (target !== rowSelector[i] && target.selectIndex === rowSelector[i].selectIndex)
                {
                    rowSelector[i].selectIndex = target.changeBeforeIndex;
                }
                
                index.push(rowSelector[i].selectLabel);
            }
            
            rowIndex = Vector.<String>(index);
            createCharacter();
        }
        
        /**
         * スライダーハンドラ
         */
        private function frameRateHandler(event:Event):void 
        {
            character.frameRate = frameRate.value;
        }
        
        /**
         * スライダーハンドラ
         */
        private function speedRateHandler(event:Event):void 
        {
            character.speed = speedRate.value;
        }
        
        /**
         * 透過色変更
         */
        private function colorHandler(event:Event):void 
        {
            createCharacter();
        }
        
        /**
         * カラーピッカー表示切り替え
         */
        private function colorPickerEnable(event:MouseEvent):void 
        {
            if (event.type == MouseEvent.MOUSE_OVER)
            {
                stage.addChild(colorChip);
            }
            else
            {
                stage.removeChild(colorChip);
            }
        }
        
        /**
         * カラーピッカー
         */
        private function colorPickerHandler(event:MouseEvent):void 
        {
            colorChip.x = stage.mouseX + 16;
            colorChip.y = stage.mouseY;
            colorChip.color = source.bitmapData.getPixel32(event.localX / source.scaleX, event.localY / source.scaleY);
        }
        
        /**
         * 透過色を決定
         */
        private function getMaskColor(event:MouseEvent):void 
        {
            colorMonitor.value = colorChip.color;
            createCharacter();
        }
    }
}

import com.bit101.components.HSlider;
import com.bit101.components.InputText;
import com.bit101.components.Label;
import com.bit101.components.PushButton;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObjectContainer;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.ui.Keyboard;

/**
 * グリッドキャンバス
 */
class GridCanvas extends Sprite 
{
    private var _grid:Shape;
    private var _pallet:BitmapData;
    
    public function GridCanvas() 
    {
        _grid = addChild(new Shape()) as Shape;
        _pallet = new BitmapData(16, 16);
        _pallet.fillRect(new Rectangle(0, 0, 8, 8), 0xFFCCCCCC);
        _pallet.fillRect(new Rectangle(8, 8, 8, 8), 0xFFCCCCCC);
    }
    
    public function setBitmap(target:Bitmap):void 
    {
        if (numChildren > 1)
        {
            removeChildAt(0);
        }
        
        addChildAt(target, 0);
    }
    
    public function drawGrid(width:int, height:int, row:int, col:int):void 
    {
        graphics.clear();
        graphics.beginBitmapFill(_pallet);
        graphics.drawRect(0, 0, width, height);
        graphics.endFill();
        
        _grid.graphics.clear();
        _grid.graphics.lineStyle(0, 0x4AFFFF);
        verticalLine(col + 1, height, --width / col);
        horizontalLine(row + 1, width, --height / row);
    }
    
    private function verticalLine(col:int, canvasHeight:int, equalWidth:Number):void 
    {
        for (var i:int = 0; i < col; i++) 
        {
            _grid.graphics.moveTo(equalWidth * i, 0);
            _grid.graphics.lineTo(equalWidth * i, canvasHeight);
        }
    }
    
    private function horizontalLine(row:int, canvasWidth:int, equalHeight:Number):void 
    {
        for (var i:int = 0; i < row; i++) 
        {
            _grid.graphics.moveTo(0, equalHeight * i);
            _grid.graphics.lineTo(canvasWidth, equalHeight * i);
        }
    }
}

/**
 * スライダー
 */
class NumSlider extends Sprite 
{
    private var _label:String;
    private var _field:Label;
    private var _slider:HSlider;
    
    public function set value(value:int):void
    {
        _slider.value = value;
        updateLabel();
    }
    
    public function get value():int
    {
        return int(_slider.value);
    }
    
    public function NumSlider(labeling:String, min:Number, max:Number) 
    {
        _label = labeling;
        _field = new Label(this, 0, 0);
        
        _slider = new HSlider(this, 50, 5);
        _slider.addEventListener(Event.CHANGE, sliderHandler);
        _slider.setSize(60, 10);
        _slider.setSliderParams(min, max, 0);
    }
    
    private function sliderHandler(event:Event):void 
    {
        updateLabel();
        dispatchEvent(new Event(Event.CHANGE));
    }
    
    private function updateLabel():void 
    {
        _field.text = _label + String(value);
    }
}

/**
 * カラーチップ
 */
class ColorChip extends Sprite 
{
    private var _fill:uint;
    private var _chip:BitmapData;
    
    public function get color():uint 
    {
        return _fill;
    }
    
    public function set color(value:uint):void 
    {
        _fill = value;
        
        graphics.clear();
        graphics.lineStyle(0, (value === 0xFF999999) ? 0x0 : 0x999999);
        graphics.drawRect(0, 0, 15, 15);
        
        _chip.fillRect(_chip.rect, value);
    }
    
    public function ColorChip() 
    {
        _chip = new BitmapData(14, 14, true, 0x0);
        
        var colorChip:Bitmap = new Bitmap(_chip);
        colorChip.x = colorChip.y = 1;
        addChild(colorChip);
    }
}

/**
 * カラーピッカー
 */
class ColorMonitor extends Sprite 
{
    private var _color:uint;
    private var _tmpValue:String;
    private var _chip:ColorChip;
    private var _label:InputText;
    
    public function get value():uint 
    {
        return _color;
    }
    
    public function set value(value:uint):void 
    {
        _color = value;
        _chip.color = _color;
        _label.text = value.toString(16).substring(2).toUpperCase() || "------";
    }
    
    public function ColorMonitor() 
    {
        graphics.beginFill(0xCCCCCC);
        graphics.drawRect(0, 0, 8, 8);
        graphics.drawRect(8, 8, 8, 8);
        graphics.lineStyle(0, 0x999999);
        graphics.drawRect(0, 0, 15, 15);
        graphics.endFill();
        
        _chip = addChild(new ColorChip()) as ColorChip;
        
        _label = new InputText(this, 16, 0, "------", changeHandler);
        _label.addEventListener(FocusEvent.FOCUS_IN, focusInHandler);
        _label.addEventListener(FocusEvent.FOCUS_OUT, focusOutHandler);
        _label.setSize(50, 16);
        _label.restrict = "0123456789ABCDEF";
        _label.maxChars = 6;
        
        addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
    }
    
    private function changeHandler(event:Event):void 
    {
        event.stopImmediatePropagation();
    }
    
    private function focusInHandler(event:Event):void 
    {
        _tmpValue = _label.text;
    }
    
    private function focusOutHandler(event:Event):void 
    {
        if (_label.text.length !== 6)
        {
            _label.text = _tmpValue;
        }
        else if (_label.text !== _tmpValue)
        {
            value = uint("0xFF" + _label.text);
            dispatchEvent(new Event(Event.CHANGE));
        }
    }
    
    private function keyDownHandler(event:KeyboardEvent):void 
    {
        if (event.keyCode === Keyboard.ENTER)
        {
            stage.focus = stage;
        }
    }
}

/**
 * 行編集ボタン
 */
class RowSelectButton extends Sprite
{
    private var _selectedIndex:int;
    private var _beforeIndex:int;
    private var _callbackHandler:Function;
    
    public function get selectIndex():int 
    {
        return _selectedIndex;
    }
    
    public function set selectIndex(value:int):void 
    {
        _setIndex(value);
    }
    
    public function get selectLabel():String 
    {
        return (getChildAt(_selectedIndex) as PushButton).label.toLowerCase();
    }
    
    public function get changeBeforeIndex():int 
    {
        return _beforeIndex;
    }
    
    public function RowSelectButton(parent:DisplayObjectContainer, x:Number, y:Number, callbackHandler:Function) 
    {
        parent.addChild(this);
        this.x = x;
        this.y = y;
        _callbackHandler = callbackHandler;
        
        var front:PushButton = new PushButton(this, 0, 0, "Front", _onClickHandler);
        front.setSize(35, 16);
        front.toggle = true;
        front.selected = true;
        
        var left:PushButton = new PushButton(this, 34, 0,"Left", _onClickHandler);
        left.setSize(35, 16);
        left.toggle = true;
        
        var right:PushButton = new PushButton(this, 68, 0, "Right", _onClickHandler);
        right.setSize(34, 16);
        right.toggle = true;
        
        var back:PushButton = new PushButton(this, 101, 0, "Back", _onClickHandler);
        back.setSize(34, 16);
        back.toggle = true;
        
        graphics.beginFill(0xBCBCBC);
        graphics.drawRect(0, 0, 135, 16);
        graphics.endFill();
    }
    
    private function _onClickHandler(event:MouseEvent):void 
    {
        var index:int = getChildIndex(event.target as PushButton);
        
        if (_selectedIndex === index)
        {
            (getChildAt(index) as PushButton).selected = true;
        }
        else
        {
            _setIndex(index);
            _callbackHandler(this);
        }
    }
    
    private function _setIndex(index:int):void 
    {
        _beforeIndex = _selectedIndex;
        _selectedIndex = index;
        
        (getChildAt(_beforeIndex) as PushButton).selected = false;
        (getChildAt(_beforeIndex) as PushButton).getChildAt(1).alpha = 1;
        (getChildAt(_selectedIndex) as PushButton).selected = true;
        (getChildAt(_selectedIndex) as PushButton).getChildAt(1).alpha = 0;
    }
}

/**
 * キャラクター表示
 */
class CharacterBitmap extends Bitmap
{
    private var _row:int;
    private var _pattern:int;
    private var _col:int;
    private var _frame:int;
    
    private var _width:int;
    private var _height:int;
    private var _point:Point;
    private var _crop:Rectangle;
    
    private var _source:BitmapData;
    
    public function get frame():int 
    {
        return _frame;
    }
    
    public function set frame(value:int):void 
    {
        if (0 <= value)
        {
            _frame = value;
        }
    }
    
    public function get pattern():int 
    {
        return _pattern;
    }
    
    public function set pattern(value:int):void 
    {
        if (0 <= value && _row > value)
        {
            _pattern = value;
        }
    }
    
    public function CharacterBitmap(source:BitmapData, row:int, col:int, maskColor:uint = 0)
    {
        _row = row;
        _col = col;
        _width = source.width / col >> 0;
        _height = source.height / row >> 0;
        _point = new Point();
        _crop = new Rectangle(0, 0, _width, _height);
        
        _source = new BitmapData(source.width, source.height, true, 0);
        _source.draw(source);
        _source.threshold(_source, _source.rect, _point, "==", maskColor, 0, 0xFFFFFF);
        
        bitmapData = new BitmapData(_width, _height);
        bitmapData.copyPixels(_source, _crop, _point);
    }
    
    public function update():void 
    {
        _crop.x = (_frame++ % _col) * _width;
        _crop.y = _pattern * _height;
        bitmapData.copyPixels(_source, _crop, _point);
    }
}

/**
 * キャラクタースプライト
 */
class CharacterSprite extends Sprite
{
    protected var _frameRate:Number;
    protected var _frameSpan:Number;
    protected var _updateTarget:Number;
    
    protected var _front:int;
    protected var _left:int;
    protected var _right:int;
    protected var _back:int;
    
    protected var _source:CharacterBitmap;
    
    public function get frameRate():Number 
    {
        return _frameRate;
    }
    
    public function set frameRate(value:Number):void 
    {
        _frameRate = value;
        _frameSpan = 1000 / _frameRate;
        _updateTarget = 0;
        _source.frame = 0;
    }
    
    public function CharacterSprite(source:CharacterBitmap, frameRate:Number, direction:Vector.<String>)
    {
        _source = addChild(source) as CharacterBitmap;
        
        _front = direction.indexOf("front");
        _left = direction.indexOf("left");
        _right = direction.indexOf("right");
        _back = direction.indexOf("back");
        
        this.frameRate = frameRate;
    }
    
    public function start():void 
    {
        addEventListener(Event.ENTER_FRAME, enterFrameHandler);
    }
    
    public function stop():void 
    {
        removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
    }
    
    protected function enterFrameHandler(event:Event):void 
    {
        var now:Number = new Date().getTime();
        
        if (now > _updateTarget)
        {
            _updateTarget = now + _frameSpan;
            _source.update();
        }
    }
}

/**
 * キー操作できるキャラクター
 */
class Player extends CharacterSprite
{
    public var speed:int;
    
    private var _right_key:Boolean;
    private var _left_key:Boolean;
    private var _up_key:Boolean;
    private var _down_key:Boolean;
    
    public function Player(source:CharacterBitmap, frameRate:Number, direction:Vector.<String>, speed:int)
    {
        this.speed = speed;
        super(source, frameRate, direction);
    }
    
    public function keyDownHandler(event:KeyboardEvent):void 
    {
        switch (event.keyCode)
        {
            case Keyboard.RIGHT:
                _right_key = true;
                _source.pattern = _right;
            break;
            case Keyboard.LEFT:
                _left_key = true;
                _source.pattern = _left;
            break;
            case Keyboard.UP:
                _up_key = true;
                _source.pattern = _back;
            break;
            case Keyboard.DOWN:
                _down_key = true;
                _source.pattern = _front;
            break;
        }
    }
    
    public function keyUpHandler(event:KeyboardEvent):void 
    {
        switch (event.keyCode)
        {
            case Keyboard.RIGHT:
                _right_key = false;
            break;
            case Keyboard.LEFT:
                _left_key = false;
            break;
            case Keyboard.UP:
                _up_key = false;
            break;
            case Keyboard.DOWN:
                _down_key = false;
            break;
        }
        
        if (_up_key) _source.pattern = _back;
        if (_right_key) _source.pattern = _right;
        if (_down_key) _source.pattern = _front;
        if (_left_key) _source.pattern = _left;
    }
    
    override protected function enterFrameHandler(event:Event):void 
    {
        if (_left_key) x -= speed;
        if (_right_key) x += speed;
        if (_up_key) y -= speed;
        if (_down_key) y += speed;
        
        super.enterFrameHandler(event);
    }
}