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

#17 Hanabi ( flash on 2009-9-5 )

#17 Hanabi
* 
* BitmapData#fillRectではなくBitmapData#colorTransformを用いる実験。
* 作っているうちにHANABIぽくなくなってしまったけれど、綺麗なのでよしとします。
* 
* 操作:
* ・クリック: クリック位置に点を生成
* 
* 参考:
* ・HANABI
*   http://wonderfl.net/code/13dbc50eb48b0bfd6920540c228e8ba9ae75b601
* 
* @author krogue
Get Adobe Flash player
by krogue 05 Sep 2009
    Embed
/**
 * Copyright krogue ( http://wonderfl.net/user/krogue )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/sFKK
 */

/**
 * #17 Hanabi
 * 
 * BitmapData#fillRectではなくBitmapData#colorTransformを用いる実験。
 * 作っているうちにHANABIぽくなくなってしまったけれど、綺麗なのでよしとします。
 * 
 * 操作:
 * ・クリック: クリック位置に点を生成
 * 
 * 参考:
 * ・HANABI
 *   http://wonderfl.net/code/13dbc50eb48b0bfd6920540c228e8ba9ae75b601
 * 
 * @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 frame:int = 0;
        private var hanabi:Hanabi;
        private var isMouseDown:Boolean;
        
        public function Main()
        {
            addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        }
        
        private function addedToStageHandler(event:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
            initialize();
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }
        
        private function enterFrameHandler(event:Event):void
        {
            update();
        }
        
        private function initialize():void
        {
//            addChild(new Stats());
            hanabi = addChild(new Hanabi()) as Hanabi;
            stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
            stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
        }
        
        private function update():void
        {
            if (isMouseDown)
                hanabi.shoot(mouseX, mouseY);
            hanabi.update();
            frame = (frame + 1 == 60 ? 0 : frame + 1);
        }
        
        private function mouseDownHandler(event:MouseEvent):void
        {
            isMouseDown = true;
        }
        
        private function mouseUpHandler(event:MouseEvent):void
        {
            isMouseDown = false;
        }
    }
}

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.display.Sprite;
import flash.geom.ColorTransform;
import flash.geom.Point;

class Hanabi extends Sprite
{
    private static const ACCELERATION:Number = 0.01;
    private static const ANGULAR_VELOCITY:Number = 0.02;
    private static const MAX_SPEED:Number = 2; // 初期速度の最高値
    private static const MIN_SPEED:Number = 0.5; // 初期速度の最低値
    private static const NUM_SHOOT:int = 8; // shoot一回で生成される点の数
    
    private const bitmap:Bitmap = addChild(new Bitmap()) as Bitmap;
    private const colorTransform:ColorTransform =
            new ColorTransform(0.8, 0.9, 0.8); // 尾の長さに影響
    private const pixels:Array /* of Pixel */ = [];
    
    public function Hanabi()
    {
        bitmap.bitmapData = new BitmapData(465, 465, false, 0x000000);
    }
    
    public function update():void
    {
        const bmd:BitmapData = bitmap.bitmapData;
        bmd.lock();
        
        // Array#spliceの都合で逆向きに走査
        for (var i:int = pixels.length - 1; i >= 0; i--)
        {
            var pixel:Pixel = pixels[i];
            pixel.angle += ANGULAR_VELOCITY;
            pixel.speed *= 1 + ACCELERATION;
            pixel.x += Math.cos(pixel.angle) * pixel.speed;
            pixel.y += Math.sin(pixel.angle) * pixel.speed;
            bmd.setPixel(pixel.x, pixel.y, 0xFFFFFF);
            if (!bmd.rect.contains(pixel.x, pixel.y))
                pixels.splice(i, 1);
        }
        bmd.colorTransform(bmd.rect, colorTransform);
        
        bmd.unlock();
    }
    
    public function shoot(x:Number, y:Number):void
    {
        const n:int = NUM_SHOOT;
        for (var i:int = 0; i < n; i++)
        {
            var pixel:Pixel = new Pixel();
            pixel.x = x;
            pixel.y = y;
            pixel.angle = Math.random() * Math.PI * 2;
            // intの場合はfloor(rand * (max - min + 1)) + min
            pixel.speed = Math.random() * (MAX_SPEED - MIN_SPEED) + MIN_SPEED;
            pixels.push(pixel);
        }
    }
}

class Pixel
{
    public var x:Number;
    public var y:Number;
    public var angle:Number;
    public var speed:Number;
}