#14 Road (flash on 2009-8-29)

by krogue
Road
* 
* 「線は点からできている」と、中学生のときに教わりました。
* そこで、点で道(線)を作ってみることにしました。
* 画面上をドラッグ(クリックしながらマウス移動)で、マウスの通った跡(道)を残します。
* 
* NOTE:
* Vectorのテスト
* パーティクル系?
* 
* @author krogue
♥2 | Line 106 | Modified 2009-08-29 19:27:48 | MIT License
play

ActionScript3 source code

/**
 * Copyright krogue ( http://wonderfl.net/user/krogue )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/2bqY
 */

/**
 * Road
 * 
 * 「線は点からできている」と、中学生のときに教わりました。
 * そこで、点で道(線)を作ってみることにしました。
 * 画面上をドラッグ(クリックしながらマウス移動)で、マウスの通った跡(道)を残します。
 * 
 * NOTE:
 * Vectorのテスト
 * パーティクル系?
 * 
 * @author krogue
 */
package  {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    
    [SWF(width="465", height="465", backgroundColor="0", frameRate="60")]
    public class Main extends Sprite {
        private var road:Road;
        private var isMouseDown:Boolean = false;
        
        public function Main() {
            addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
        }
        
        private function onAddedToStage(event:Event):void {
            removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
            initialize();
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }
        
        private function onEnterFrame(event:Event):void {
            update();
        }
        
        private function initialize():void {
            road = addChild(new Road()) as Road;
            stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
            stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
        }
        
        private function update():void {
            road.draw();
        }
        
        private function onMouseDown(event:MouseEvent):void {
            road.update(event.stageX, event.stageY);
            isMouseDown = true;
        }
        
        private function onMouseUp(event:MouseEvent):void {
            isMouseDown = false;
        }
        
        private function onMouseMove(event:MouseEvent):void {
            if (isMouseDown) {
                road.update(event.stageX, event.stageY);
            }
        }
    }
}

import flash.display.Sprite;
import __AS3__.vec.Vector;
import flash.geom.Point;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.geom.Rectangle;

class Road extends Sprite {
    // 点を設置する際の一回あたりの個数
    private const NUM_SET:int = 15;
    // 点を設置する際の範囲
    private const MAX_RADIUS:int = 10;
    // 点を表示するフレーム数(この値の0.75..1を初期値に設定)
    private const MAX_LIFE:int = 150;
    // 点が移動する速度
    private const MAX_SPEED:Number = 1.1;
    
    // 何度か試したけど、要素数は大体2000個くらいになる
    private var points:Vector.<RoadPoint> = new Vector.<RoadPoint>();
    private var bitmap:Bitmap = addChild(new Bitmap()) as Bitmap;
    private var shape:Shape = addChild(new Shape()) as Shape;
    
    public function Road() {
        bitmap.bitmapData = new BitmapData(465, 465, true, 0xFF000000);
    }
    
    public function draw():void {
        const bmd:BitmapData = bitmap.bitmapData;
        bmd.lock();
        bmd.fillRect(bmd.rect, 0xFF000000);
        // 添字への影響を避けるため逆向きに走査
        for (var i:int = points.length - 1; i >= 0; i--) {
            var pt:RoadPoint = points[i];
            pt.x += pt.vx;
            pt.y += pt.vy;
            bmd.setPixel32(pt.x, pt.y,
                0xFF << 24 | pt.color);
                // (pt.life / MAX_LIFE * 0xFF << 24)
                // フェードアウトしてみたが、イマイチだった
            pt.life--;
            if (pt.life <= 0) {
                points.splice(i, 1);
            }
        }
        bmd.unlock();
    }
    
    public function update(x:Number, y:Number):void {
        for (var i:int = 0; i < NUM_SET; i++) {
            points.push(new RoadPoint(
                x + (MAX_RADIUS * Math.random() - MAX_RADIUS / 2),
                y + (MAX_RADIUS * Math.random() - MAX_RADIUS / 2),
                MAX_SPEED * Math.random() - MAX_SPEED / 2,
                MAX_SPEED * Math.random() - MAX_SPEED / 2,
                0xFFFFFF * Math.random(),
                MAX_LIFE * 3 / 4 + (MAX_LIFE / 4 * Math.random())));
        }
    }
}

class RoadPoint {
    public var x:Number;
    public var y:Number;
    public var vx:Number;
    public var vy:Number;
    public var color:uint;
    public var life:uint;
    
    public function RoadPoint(x:Number, y:Number, vx:Number, vy:Number,
        color:uint, life:uint) {
        this.x = x;
        this.y = y;
        this.vx = vx;
        this.vy = vy;
        this.color = color;
        this.life = life;
    }
}