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

forked from: [セルフフォーク]ひだまりスケッチの星 を飛び散るようにしてみた

some minor optimisation to cpu and mem
added a gravity-like behavior

ひだまりスケッチ ほしみっつ の星 を飛び散るようにしてみた
@author Hiiragi

セルフフォーク
作らなきゃいけないコンテンツを作る気が起きなかったので
なんとなく思いついて、違うことをしてみました。 

OPのサビ前に、星がバシバシ飛び散るのを再現してみました。
ステージをクリックすると星が飛び散ります。

本当は、写真を読み込んで、それをクリックしたときに
ガーッと揺れ動くというか拡大するというか
そういうのをやりたかったんですが、上手くいかなかったので終了。

FlashCampで話が出た「cacheAsBitmap」と「オブジェクトプール」を
試してみた感じです。確かにSpriteをガシガシ作ってるけど、
ガベージコレクションがかからない感じ。

最初に720個の星と初期設定をしてるので、最初若干重いです。
// forked from Hiiragi's [セルフフォーク]ひだまりスケッチの星 を飛び散るようにしてみた
//
// some minor optimisation to cpu and mem
// added a gravity-like behavior

package 
{
    import flash.display.*;
    import flash.events.*;
    import flash.geom.Matrix;
    import flash.net.FileReference;
    import flash.utils.Timer;
    
    import com.bit101.components.PushButton;
    
    /**
     * ひだまりスケッチ ほしみっつ の星 を飛び散るようにしてみた
     * @author Hiiragi
     * 
     * セルフフォーク
     * 作らなきゃいけないコンテンツを作る気が起きなかったので
     * なんとなく思いついて、違うことをしてみました。 
     * 
     * OPのサビ前に、星がバシバシ飛び散るのを再現してみました。
     * ステージをクリックすると星が飛び散ります。
     * 
     * 本当は、写真を読み込んで、それをクリックしたときに
     * ガーッと揺れ動くというか拡大するというか
     * そういうのをやりたかったんですが、上手くいかなかったので終了。
     * 
     * FlashCampで話が出た「cacheAsBitmap」と「オブジェクトプール」を
     * 試してみた感じです。確かにSpriteをガシガシ作ってるけど、
     * ガベージコレクションがかからない感じ。
     * 
     * 最初に720個の星と初期設定をしてるので、最初若干重いです。
     * 
     */
    
    [SWF(width = 465, height = 465, frameRate = 60, backgroundColor = 0xFFAAAA)]
    public class Main extends Sprite 
    {
        private var _fr:FileReference;
        private var _loadBtn:PushButton;
        private var _loader:Loader;
        private var _loadImageSp:Sprite;
        
        private var _timer:Timer;
        private var _backSp:Sprite;
        
        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            start();
            // entry point
            //_fr = new FileReference();
            //_fr.addEventListener(Event.SELECT, fileSelectedHandler);
            //
            //_loadImageSp = new Sprite();
            //
            //_loader = new Loader();
            //_loadBtn = new PushButton(this, 0, 0, "load Image", loadImage);
            //_loadBtn.x = this.stage.stageWidth / 2 - _loadBtn.width / 2;
            //_loadBtn.y = this.stage.stageHeight / 2 - _loadBtn.height / 2;
        }
        
        //public function loadImage(e:MouseEvent):void
        //{
            //_fr.browse();
        //}
        //
        //private function fileSelectedHandler(e:Event):void 
        //{
            //trace("test");
            //_fr.addEventListener(ProgressEvent.PROGRESS,onProgress);
            //_fr.addEventListener(Event.COMPLETE,onComplete);
            // _fr.addEventListener(Event.OPEN, onOpen);
            // _fr.addEventListener(IOErrorEvent.IO_ERROR, onIoError);
            //_fr.load(); // 読み込み処理を開始
        //}
        //
        //private function onProgress(e:ProgressEvent):void
        //{
            //trace("読み込んだバイト数:" + e.bytesLoaded + "、 全体のバイト数:" + e.bytesTotal);
        //}
        //
        //private function onComplete(e:Event):void
        //{
            //_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoadComplete);
            //_loader.loadBytes(_fr.data);
            //
            // fr.type を参考にオブジェクト変換する等の処理を記述
            // fr.removeEventListener(...)
        //}
        //
        //private function imgLoadComplete(e:Event):void 
        //{
            //trace("enemyImage Load Completed");
            //
            //var loadImage:Bitmap = new Bitmap(imageSizeCompressor(Bitmap(_loader.content).bitmapData, this.stage.stageWidth, this.stage.stageHeight));
            //
            //_loadImageSp.addChild(loadImage);
            //
            //_loadImageSp.x = this.stage.stageWidth / 2 - _loadImageSp.width / 2;
            //_loadImageSp.y = this.stage.stageHeight / 2 - _loadImageSp.height / 2;
            //
            //this.addChild(_loadImageSp);
            //
            //start();
        //}
        //
        ///**
         //* 指定のBitmapDataを、幅と高さの比率をそのままに、閾値に合わせて拡大縮小します。
         //* 
         //* @param    inputBitmapData    拡大・縮小したいBitmapData
         //* @param    maxWidth        幅の閾値
         //* @param    maxHeight        高さの閾値
         //* @return    閾値に合わせて拡大・縮小したBitmapData
         //*/
        //private function imageSizeCompressor(inputBitmapData:BitmapData, maxWidth:int, maxHeight:int):BitmapData
        //{
            //var ratio:Number;    //どれくらい拡大・縮小するか
            //var fixWidth:int;    //拡大・縮小したときの幅
            //var fixHeight:int;    //拡大・縮小したときの高さ
            //
            //var returnBitmapData:BitmapData;
            //
            //maxWidth * maxHeightの範囲内に最大限に収める
            //横長の場合
            //if (inputBitmapData.width / inputBitmapData.height >=  maxWidth / maxHeight)
            //{
                //横長なので、横の大きさを閾値に合わせ、その比率分、高さを拡大縮小して、縦横の比率をそのままにサイズ変更する。
                //ratio = maxWidth / inputBitmapData.width;
                //fixWidth = maxWidth;
                //fixHeight = inputBitmapData.height * ratio;
            //}
            //縦長の場合
            //else if (inputBitmapData.width / inputBitmapData.height <  maxWidth / maxHeight)
            //{
                //ratio = maxHeight / inputBitmapData.height;
                //fixWidth = inputBitmapData.width * ratio;
                //fixHeight = maxHeight;
            //}
            //
            //returnBitmapData = new BitmapData(fixWidth, fixHeight, true, 0x0);
            //returnBitmapData.draw(inputBitmapData, new Matrix(ratio, 0, 0, ratio));
            //
            //return returnBitmapData;
        //}
    
        private function start():void 
        {
            //_timer = new Timer(33, 10);
            //_timer.addEventListener(TimerEvent.TIMER, shakeDisplayObject);
            //_timer.addEventListener(TimerEvent.TIMER_COMPLETE, shakeDisplayObjectComplete);
            
            var mtx:Matrix = new Matrix();
            mtx.createGradientBox(this.stage.stageWidth, this.stage.stageHeight, Math.PI / 2);
            var g:Graphics = this.graphics;
            g.beginGradientFill(GradientType.LINEAR, [0xFFEEEE, 0xFFFFFF], [1, 1], [0, 255], mtx);
            g.drawRect(0, 0, this.stage.stageWidth, this.stage.stageHeight);
            g.endFill();
            
            var burst:HidamariStarBurst = new HidamariStarBurst(this.stage.stageWidth, this.stage.stageHeight);
            this.addChild(burst);
            
            this.stage.addEventListener(MouseEvent.MOUSE_DOWN, burst.burst);
            //_loadImageSp.addEventListener(MouseEvent.CLICK, burst.burst);
            //_loadImageSp.addEventListener(MouseEvent.CLICK, startShakeDisplayObject);
        }
        
        //private function startShakeDisplayObject(e:MouseEvent):void 
        //{
            //if (_timer.running) _timer.stop();
            //_timer.reset();
            //_timer.start();
        //}
        //private function shakeDisplayObject(e:TimerEvent):void 
        //{
            //_loadImageSp.x = Math.random() * 30 - 15;
            //_loadImageSp.y = Math.random() * 30 - 15;
        //}
        //
        //private function shakeDisplayObjectComplete(e:TimerEvent):void 
        //{
            //_loadImageSp.x = _loadImageSp.y = 0;
        //}
    }
    
}



import flash.display.*;
import flash.events.*;
import flash.filters.*;
import flash.geom.Matrix;
import flash.geom.Point;

class HidamariStarBurst extends Sprite
{
    private const STAR_MAX:uint = 90;
    private const BURST_NUM:int = 15;
    
    private var _sw:int;
    private var _sh:int;
    
    private var _starPool:Array;
    private var _activeStars:Array;
    
    private var _burstFlag:Boolean;
    static public const secondStarBevelFilter:BevelFilter = new BevelFilter(2, -45, 0x996666, 1, 0, .3, 2, 2, 1, 2, BitmapFilterType.OUTER, false);
    static public const centerStarBevelFilter:BevelFilter = new BevelFilter(2, -45, 0x996666, 1, 0, .5, 2, 2, 1, 2, BitmapFilterType.OUTER, false);
    
    private var _clickPoint:Point;
    
    public function HidamariStarBurst(stageWidth:int, stageHeight:int)
    {
        _sw = stageWidth;
        _sh = stageHeight;
        
        _starPool = [];
        _activeStars = [];
        
        var star:HidamariStarExtend;
        var absX:Number;
        var absY:Number;
        
        for (var i:int = 0; i < STAR_MAX; i++) 
        {
            star = new HidamariStarExtend(Math.random() * 30 + 20);
            
            star.visible = false;
            star.vx = Math.random() * 50 - 25;
            star.vy = Math.random() * 50 - 25;
            
            absX = Math.abs(star.vx);
            absY = Math.abs(star.vy);
            
            if (absX + absY < 10)
            {                if (absX >= absY)
                {
                    if (star.vx >= 0) star.vx += 25;
                    else star.vx -= 25;
                }
                else
                {
                    if (star.vy >= 0) star.vy += 25;
                    else star.vy -= 25;
                }
            }
            star.rotation = i;
            
            star.cacheAsBitmap = true;
            
            this.addChild(star);
            _starPool[i] = star;
        }
        
        this.addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
    }
    
    public function velocityCompressor(velocity:Number):Number
    {
        if (velocity < 2 && velocity > -2)
        {
            if (velocity > 0)    velocity += 2;
            else                velocity -= 2;
        }
        
        return velocity;
    }
    
    public function burst(e:MouseEvent):void 
    {
        _burstFlag = true;
        _clickPoint = new Point(e.stageX, e.stageY);
    }
    
    private function burstStarProcess():void
    {
        var star:HidamariStarExtend;
        for (var i:int = 0; i < BURST_NUM; i++) 
        {
            star = _starPool.shift();
            star.visible = true;
            star.x = _clickPoint.x;
            star.y = _clickPoint.y;
            star.vx = Math.random() * 50 - 25;
            star.vy = Math.random() * 50 - 25;            
            _activeStars.push(star);
        }
    }
    
    private function onEnterFrameHandler(e:Event):void 
    {
        var len:int = _activeStars.length;
        var star:HidamariStarExtend;
        var deleteFlag:Boolean;
        
        for (var i:int = len - 1; i >= 0; i--) 
        {
            deleteFlag = false;
            
            star = _activeStars[i];
            star.x += star.vx;
            star.y += star.vy;
            star.vy += 1;
            
            if (star.x < -star.width * .5)
            {
                deleteFlag = true;
            }
            else if (star.x > _sw + star.width * .5)
            {
                deleteFlag = true;
            }
            
            if (star.y < -star.height * .5)
            {
                deleteFlag = true;
            }
            else if (star.y > _sh + star.height * .5)
            {
                deleteFlag = true;
            }
            
            if (deleteFlag)
            {
                _activeStars.splice(i, 1);
                _starPool.push(star);
                star.visible = false;
            }
        }
        
        if (_burstFlag)
        {
            burstStarProcess();
            _burstFlag = false;
        }
    }
}


class HidamariStar extends Sprite
{
    private var _cx:Number;
    private var _cy:Number;
    private var _radius:Number;
    private var _insideRatio:Number;
    
    private var _secondStar:Shape;
    private var _centerStar:Shape;
    
    private var _secondStarBevelFilter:BevelFilter;
    private var _centerStarBevelFilter:BevelFilter;
    
    public function HidamariStar(radius:Number,
                                 cx:Number = 0, 
                                 cy:Number = 0, 
                                 insideRatio:Number = 0.5) 
    {
        _radius = radius;
        _cx = cx;
        _cy = cy;
        _insideRatio = insideRatio;
        
        _secondStar = new Shape();
        _centerStar = new Shape();
        this.addChild(_secondStar);
        this.addChild(_centerStar);
        
        _secondStar.filters = [HidamariStarBurst.secondStarBevelFilter];
        _centerStar.filters = [HidamariStarBurst.centerStarBevelFilter];
        
        draw();
    }
    
    public function draw():void 
    {
        var mtx:Matrix = new Matrix();
        
        var g:Graphics = this.graphics;
        g.clear();
        
        g.beginFill(0xFFFFFF);
        g.lineStyle(10, 0xFFFFFF);
        drawStar(g, _radius);
        g.endFill();
        
        g = _secondStar.graphics;
        g.clear();
        mtx.createGradientBox(_radius * 2, _radius * 2, -Math.PI / 4, -_cx -_radius, -_cy - _radius);
        g.beginGradientFill(GradientType.LINEAR, [0xf0ac96, 0x780100], [1, 1], [0, 255], mtx);
        drawStar(g, _radius * .95);
        g.endFill();
        
        g = _centerStar.graphics;
        g.clear();
        mtx.createGradientBox(_radius * 2, _radius * 2, -Math.PI / 4, -_cx -_radius, -_cy - _radius);
        g.beginGradientFill(GradientType.LINEAR, [0xfdf9fa, 0xfdae10], [1, 1], [0, 255], mtx);
        drawStar(g, _radius * 0.8);
        g.endFill();
        
    }
    
    private function drawStar(g:Graphics, radius:Number):void
    {
        g.moveTo(_cx, _cy - radius);
        
        var diffRad:Number = Math.PI / 5;
        var rad:Number = -Math.PI * .5;
        var tempRadius:Number;
        
        for (var i:int = 1; i <= 10; i++)
        {
            rad += diffRad;
            tempRadius = (i % 2 == 1) ? tempRadius = radius * _insideRatio : tempRadius = radius;
            g.lineTo(Math.cos(rad) * tempRadius + _cx, Math.sin(rad) * tempRadius + _cy);
        }
    }
    
    public function get radius():Number { return _radius; }
    
    public function set radius(value:Number):void 
    {
        _radius = value;
        draw();
    }
    
    public function get insideRatio():Number { return _insideRatio; }
    
    public function set insideRatio(value:Number):void 
    {
        _insideRatio = value;
        draw();
    }
    
}


class HidamariStarExtend extends HidamariStar
{
    private var _vx:Number;
    
    public function get vx():Number { return _vx; }
    
    public function set vx(value:Number):void 
    {
        _vx = value;
    }
    
    private var _vy:Number;
    public function get vy():Number { return _vy; }
    
    public function set vy(value:Number):void 
    {
        _vy = value;
    }
    
    public function HidamariStarExtend(radius:Number,
                                 cx:Number = 0, 
                                 cy:Number = 0, 
                                 insideRatio:Number = 0.5) 
    {
        super(radius, cx, cy, insideRatio);
        this.mouseEnabled = false;
    }
}