forked from:簡単なゲームのサンプル_2011_10_01

by nan05aur forked from forked from:簡単なゲームのサンプル_2011_09_23 (diff: 511)
マウスでクリックしたところから円が広がる
@author shmdmoto
♥0 | Line 794 | Modified 2011-10-04 20:04:59 | MIT License
play

ActionScript3 source code

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

// forked from nan05aur's forked from:簡単なゲームのサンプル_2011_09_23
// forked from nan05aur's forked from:簡単なゲームのサンプル_2011_09_21
// forked from nan05aur's forked from: forked from:的を動かす
// forked from nan05aur's forked from:的を動かす
// forked from nan05aur's forked from: 的に弾が当たった時の演習のサンプル_連射
// forked from shmdmoto's 的に弾が当たった時の演習のサンプル
package 
{
    import flash.display.AVM1Movie;
    import flash.display.Bitmap;
    import flash.system.IME;
    import flash.ui.Keyboard;
    import flash.events.KeyboardEvent;
    
    import frocessing.display.F5MovieClip2D;
    [SWF(width = 465, height = 465, frameRate = 60)]
    /**
     * マウスでクリックしたところから円が広がる
     * @author shmdmoto
     */
    public class miniGame2 extends F5MovieClip2D
    {
        public var posX:Number;
        public var posY:Number;
        public var sparkX:Array;
        public var sparkY:Array;
        public var sparkVX:Array;
        public var sparkVY:Array;
        public var intS:Array;
        public var sparkAlpha:Array;
        public var isContLeft:Boolean; // ←が押し続けられているか
        public var isContRight:Boolean; // →が押し続けられているか
        public var isContUp:Boolean; // ↑が押し続けられているか
        public var isContDown:Boolean; // ↓が押し続けられているか
        public var bulletX:Array; // 弾のX座標
        public var bulletY:Array; // 弾のY座標
        public var bulletFrag:Array;
        public var eBullX:Array; // 弾のX座標
        public var eBullY:Array; // 弾のY座標
        public var eBullVX:Array; // 弾のX座標
        public var eBullVY:Array; // 弾のY座標
        public var eBullV:Number = 3;
        public var eBullFrag:Array;
        public var eBullCount:Array;
        public var targetX:Array; // 的の中心のx座標
        public var targetY:Array; // 的の中心のy座標
        public var targetHit:Array;  // 的に命中したかどうか
        public var targetLife:Array; // 的の体力
        public var targetFrag:Array;
        public var t2X:Array; // 的の中心のx座標
        public var t2Y:Array; // 的の中心のy座標
        public var tVy:Array;
        public var intR:Array;   // 当たった時の演出の円の直径
        public var circX:Array; // 当たった時の演出の円の中心のx座標
        public var circY:Array; // 当たった時の演出の円の中心のy座標
        public var circFrag:Array;
        public var circVal:Array
        public var circRv:Array;
        public var circAlpha:Array;
        public var mN:int = 500;
        public var tMn:int = 10;
        public var sN:int = 20;
        public var pi:Number = 3.14;
        public var t2Theta:Array;
        public var v:Number = 5;
        public var sv:Number = 5;
        public var tCounter:int = 0;
        public var tAlpha:Array;
        public var t2Omega:Array;
        public var t2R:Array;
        public var vNx:Array;
        public var vNy:Array;
        public var vX0:Number = 0;
        public var vY0:Number = 0;
        
        public function miniGame2() {
            super(false);
        }
        public function setup() : void
        {
            colorMode(RGB,255,255,255,255);
            isContLeft  = false;
            isContRight = false;
            isContUp    = false;
            isContDown  = false;
            posX = stage.stageWidth / 2;
            posY = stage.stageHeight - 50;
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
            stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
            // 的の初期設定
            targetX = new Array(tMn);
            targetY = new Array(tMn);
            targetHit = new Array(tMn);
            targetLife = new Array(tMn);
            targetFrag = new Array(tMn);
            t2X = new Array(tMn);
            t2Y = new Array(tMn);
            tAlpha = new Array(tMn);
            t2Theta = new Array(tMn);
            t2Omega = new Array(tMn);
            t2R = new Array(tMn);
            tVy = new Array(tMn);
            // 弾のY座標
            bulletX = new Array(mN);
            bulletY = new Array(mN);
            bulletFrag = new Array(mN);
            eBullX = new Array(mN);
            eBullY = new Array(mN);
            eBullVX = new Array(mN);
            eBullVY = new Array(mN);
            eBullFrag = new Array(mN)
            eBullCount = new Array(mN);
            vNx = new Array(mN);
            vNy = new Array(mN);
            // 当たった時の演出
            intR = new Array(mN);
            circX = new Array(mN);
            circY = new Array(mN);
            circFrag = new Array(mN);
            circVal = new Array(mN);
            circRv = new Array(mN);
            circAlpha = new Array(mN);
            // 破片
            intS = new Array(sN);
            sparkX = new Array(sN);
            sparkY = new Array(sN);
            sparkVX = new Array(sN);
            sparkVY = new Array(sN);
            sparkAlpha = new Array(sN);
            for( var i:int = 0 ; i < tMn ; i++ )
            {
                //targetX[i] = new LFO( 10, stage.stageWidth / 2,
                                       //stage.stageWidth / 2,
                                       //random(2.0));
                //targetX[i].setType(LFO.TRI);
                //targetX[i] = new Number();
                targetY[i] = new Number();
                targetY[i] = random( 10, 300 );
                targetHit[i] = new Boolean();
                targetHit[i] = false;
                targetLife[i] = new Number();
                targetLife[i] = random(1,5);
                targetFrag[i] = new Boolean();
                targetFrag[i] = false;
            }
            for( i = 0 ; i < mN ; i++ )
            {
                //bulletY[i] = new Interpolate(2, posY,0);
                //bulletY[i].pause();
                bulletFrag[i] = new Boolean(); 
                bulletFrag[i] = false;
                eBullFrag[i] = new Boolean();
                eBullFrag[i] = false;
                eBullCount[i] = new int();
                eBullCount[i] = 0;
                //intR[i] = new Interpolate(0.5, 20, 150);
                //intR[i].pause();
                circX[i] = new Number();
                circX[i] = 0.0;
                circY[i] = new Number();
                circY[i] = 0.0;
                circFrag[i] new Boolean();
                circFrag[i] = false;
                circVal[i] = new Number();
                circRv[i] = new Number();
                circAlpha[i] = new Number();
                
            }
            for( i = 0 ; i < sN ; i++ )
            {
                intS[i] = new Boolean;
                intS[i] = false;
                sparkX[i] = new Number();
                sparkX[i] = 0.0;
                sparkY[i] = new Number();
                sparkY[i] = 0.0;
                sparkVX[i] = new Number();
                sparkVX[i] = 0.0;
                sparkVY[i] = new Number();
                sparkVY[i] = 0.0;
                sparkAlpha[i] = new Number();
                sparkAlpha[i] = 0;
            }
        }
        public function draw() : void
        {
            tCounter++;
            if( tCounter > 100 )
            {
                addTarget();
                tCounter = 0;
            }
            initDir( 270 + 3 );
            // 弾の表示
            // 当たった時の演出表示
            drawRing();
            // 的の表示
            //drawTarget();
            drawPlayer();
            //drawBullet();
            drawNway();
            //moveSpark();
            //drawSpark();
            drawSpa2();
            drawT2();
            drawEbullet()
        }
        public function onKeyDown(event:KeyboardEvent) : void
        {
            // 弾を発射中は再度発射できない
            for( var i:int = 0 ; i < mN ; i++ )
            {
                if( !bulletFrag[i] &&
                    event.keyCode == Keyboard.SPACE ) {
                bulletX[i] = posX;
                bulletY[i] = posY-25;
                //for( var j:int = 0 ; j < 3 ; j++ )
                //{
                    initNway( 5, 5 );
                //}
                //bulletFrag[i] = true;
                //break;
                }
            }
            
            if( event.keyCode == Keyboard.LEFT ){isContLeft = true;}
            if( event.keyCode == Keyboard.RIGHT ){isContRight = true;}
            if( event.keyCode == Keyboard.UP ){isContUp = true;}
            if( event.keyCode == Keyboard.DOWN ){isContDown = true;}
        }
        public function onKeyUp(event:KeyboardEvent):void
        {
            if( event.keyCode == Keyboard.LEFT ){isContLeft = false;}
            if( event.keyCode == Keyboard.RIGHT ){isContRight = false;}
            if( event.keyCode == Keyboard.UP ){isContUp = false;}
            if( event.keyCode == Keyboard.DOWN ){isContDown = false;}
        }
        public function drawPlayer():void
        {
            rectMode(CENTER);
            //fill(0);
            noFill();
            stroke(0);
            //noStroke();
            if( isContLeft )posX-=7;
            if( isContRight )posX+=7;
            if( isContUp )posY-=7;
            if( isContDown )posY+=7;
            // 画面隅の接触
            if( posX < 25 ){posX=25;}
            if( posX + 25 > stage.stageHeight ){posX=stage.stageHeight-25;}
            if( posY < 25 ){posY=25;}
            if( posY + 25 > stage.stageHeight ){posY=stage.stageHeight-25;}
            rect(posX, posY, 50, 50);
        }
        public function addTarget():void
        {
            for( var i:int = 0 ; i < tMn ; i++ )
            {
                if( !targetFrag[i] )
                {
                    t2X[i] = new Number();
                    t2Y[i] = new Number();
                    tVy[i] = new Number();
                    t2Omega[i] = new Number();
                    t2R[i] = new Number();
                    targetLife[i] = new Number();
                    t2X[i] = random( 20, 300 );
                    t2Y[i] = random( 10, 200 );
                    t2Theta[i] = 1;
                    t2Omega[i] = 0.07;
                    t2R[i] = 5;
                    //tVy[i] = t2Y[i] + t2R[i] * sin( t2Theta[i] );
                    tAlpha[i] = 0;
                    targetLife[i] = random(1,5);
                    targetFrag[i] = true;
                    break;
                }                
            }
        }
        public function drawT2():void
        {
            for( var i:int = 0 ; i < tMn ; i++ )
            {
                if( targetFrag[i] )
                {
                    stroke( 0, 0, 0, tAlpha[i] );
                    fill( 0, 100+targetLife[i]*30, 0, tAlpha[i] );
                    ellipse( t2X[i], t2Y[i], 50, 50 );
                    tAlpha[i] += 5;
                    if( tAlpha[i] > 255 )
                    {
                        tAlpha[i] = 255;
                    }
                    if( tAlpha[i] == 255 )
                    {
                        t2Theta[i] += t2Omega[i];
                        t2Y[i] = t2Y[i] + t2R[i] * sin( t2Theta[i] );
                        t2X[i]++;
                        eBullCount[i]++;
                        if( eBullCount[i] > 50 )
                        {
                            initEbullet( i );
                            eBullCount[i] = 0;
                        }
                    }
                    //t2Y[i] += tVy[i];
                    //t2Y[i] = t2R[i] * t2Omega[i] * sin( t2Theta[i] );
                    if( targetLife[i] < 0 )
                    {
                        initRing( i );
                        targetFrag[i] = false;
                    }
                    if( delCorner( t2X[i], t2Y[i], 50, 50 ) )
                    {
                        targetFrag[i] = false;
                    }
                }                
            }
        }
        public function drawBullet():void
        {
            for( var i:int = 0 ; i < mN ; i++ )
            {
                if( bulletFrag[i] )
                {
                    noStroke();
                    fill(0,0,255);
                    ellipse( bulletX[i],bulletY[i],10, 10 );
                    bulletY[i] -= v;
                    hitTarget( bulletX[i], bulletY[i], i );
                    //initCircle( bulletX[i], bulletY[i] );
                    //intS[i].start();
                }
                if( delCorner( bulletX[i], bulletY[i], 10, 10 ) )
                {
                    bulletFrag[i] = false;
                }
            }
        }
        public function hitTarget( bX:Number, bY:Number, j:int ):void
        {
            for( var i:int = 0 ; i < tMn ; i ++ )
            {
                if( dist(t2X[i], t2Y[i], bX, bY ) < 30 && targetFrag[i] )
                {
                    //for( var s:int = 0 ; s < 10 ; s++ )
                    //{
                        //initSpark( bulletX[j], bulletY[j] );
                    //}
                    //initCircle( bulletX[j], bulletY[j] );
                    //initCir3( bulletX[j], bulletY[j], 15 );
                    for( var s:int = 0 ; s < sN ; s++ )
                    {
                        initCir2( bulletX[j], bulletY[j], sN );
                    }
                    //intS[i].start();
                    targetLife[i]--;
                    bulletFrag[j] = false;
                }
            }
        }
        public function initRing( t:int ):void
        {
            for( var i:int = 0 ; i < mN ; i++ )
            {
                if( !circFrag[i] )
                {
                    circX[i] = t2X[t];
                    circY[i] = t2Y[t];
                    circVal[i] = 0.0;
                    circRv[i] = 3;
                    circAlpha[i] = 0;
                    circFrag[i] = true;
                    break;
                }
            }
        }
        public function drawRing():void
        {
            for( var i:int = 0 ; i < mN ; i++ )
            {
                if( circFrag[i] )
                {
                    noFill();
                    stroke( circAlpha[i] );
                    ellipse(circX[i], circY[i], circVal[i], circVal[i] );
                    circVal[i] += circRv[i];
                    circRv[i] -= 0.01;
                    circAlpha[i] += 1;
                    if( circRv[i] < 0 )
                    {
                        circRv[i] = 0;
                    }
                    if( circAlpha[i] > 255 )
                    {
                        circFrag[i] = false;
                    }
                }
            }
        }
        public function delCorner( x:Number, y:Number, w:Number, h:Number ):Boolean
        {
            var f:Boolean = false;
            if( x < - w || x > stage.stageWidth + w ||
                y < - h || y > stage.stageHeight + h )
            {
                f = true;
            }
            else
            {
                f = false;
            }
            return f;
        }
        public function drawTarget():void
        {
            for( var i:int = 0 ; i < tMn ; i++ )
            {
                if( !targetHit[i] /*&& targetY[i] < 300*/ ) 
                {
                    stroke(0);
                    fill(100+targetLife[i]*30);
                    ellipse(targetX[i].val(), targetY[i],
                            50, 50);
                    if( targetLife[i] < 0 )
                    {
                        targetHit[i] = true;
                        intR[i].start();    // 当たった時の演出開始
                        circX[i] = targetX[i].val();
                        circY[i] = targetY[i];
                        //circX[i] = bulletX[i];
                        //circY[i] = bulletY[i].val();
                    }
                }
            }
        }       
        public function initCircle(bx:Number,by:Number):void
        {
            var odd:Boolean;
            var radStep:Number = pi * 2 / mN;
            var rad:Number = odd ? radStep / 2 : 0;
            for( var i:int = 0 ; i < mN ; i++ )
            {
                if( !intS[i] )
                {
                    for( var j:int = 0 ; j < sN ; j++, rad += radStep )
                    {
                        sparkX[j] = bx;
                        sparkY[j] = by;
                        sv = random(0.5,9);
                        sparkAlpha[j] = 255;
                        sparkVX[j] = cos( rad ) * sv;
                        sparkVY[j] = sin( rad ) * sv;
                        //intS[j] = true;
                        //break;
                     }
               
                intS[i] = true;
                break;
               }
            }
        }
        public function initCir2( bx:Number, by:Number, bNum:int ):void
        {
            var odd:Boolean;
            var radStep:Number = pi * 2 / bNum;
            var rad:Number = odd ? radStep / 2 : 0;
            for( var i:int = 0 ; i < mN ; i++, rad += radStep )
            {
                if( !intS[i] )
               {
                    sparkX[i] = bx;
                    sparkY[i] = by;
                    sv = random(0.5,9);
                    sparkAlpha[i] = 255;
                    sparkVX[i] = cos( rad ) * sv;
                    sparkVY[i] = sin( rad ) * sv;
                    intS[i] = true;
                    break;
               }
            }
        }
        public function initCir3( bx:Number, by:Number, bNum:int ):void
        {
            var odd:Boolean;
            var radStep:Number = pi * 2 / bNum;
            var rad:Number = odd ? radStep / 2 : 0;
            
            for( var j:int = 0 ; j < bNum ; j++ )
            {
            for( var i:int = 0 ; i < mN ; i++, rad += radStep )
            {
                if( !intS[i] )
               {
                    sparkX[i] = bx;
                    sparkY[i] = by;
                    sv = random(0.5,9);
                    sparkAlpha[i] = 255;
                    sparkVX[i] = cos( rad ) * sv;
                    sparkVY[i] = sin( rad ) * sv;
                    intS[i] = true;
                    break;
               }
            }}
        }
        public function drawSpark():void
        {
           for( var i:int = 0 ; i < mN ; i++ )
           {
               if( intS[i] )
               {
                   for( var j:int = 0 ; j < sN ; j++ )
                   {
                       fill(0,0,255,sparkAlpha[i]/*,intS[i].val()/150*/);
                       //strokeWeight(3);
                       //stroke(255,255,0);
                       noStroke();
                       //noFill()
                       sparkX[j] += sparkVX[j];
                       sparkY[j] += sparkVY[j];
                       sparkAlpha[j] -= 5;
                       ellipse( sparkX[j], sparkY[j], 3,3);
                       //break; 
                       //if( delCorner( sparkX[j], sparkY[j], 3, 3 ) )
                       //{
                           //intS[j] = false;
                       //}
                       if( sparkAlpha[j] < 10 )
                       {
                           intS[j] = false;
                       }
                   }
                }
            }
        }
        public function drawSpa2():void
        {
           for( var i:int = 0 ; i < mN ; i++ )
           {
               if( intS[i] )
               {
                   fill( 0, 0, 255, sparkAlpha[i] );
                   //strokeWeight(3);
                   //stroke(255,255,0);
                   noStroke();
                   //noFill()
                   sparkX[i] += sparkVX[i];
                   sparkY[i] += sparkVY[i];
                   sparkAlpha[i] -= 5;
                   //var val:Number = random( 1, 5 )
                   var val:Number = 3;
                   ellipse( sparkX[i], sparkY[i], val,val );
                   //break; 
                   //if( delCorner( sparkX[j], sparkY[j], 3, 3 ) )
                   //{
                       //intS[j] = false;
                   //}
                   if( sparkAlpha[i] < 10 )
                   {
                       intS[i] = false;
                   }
                }
            }
        }
        public function initSpark(bx:Number,by:Number):void
        {
            for( var i:int = 0 ; i < sN ; i++ )
            {
                if( intS[i] == false ){break;}
            }
            
            if( i != sN )
            {
                sparkX[i] = bx;
                sparkY[i] = by;
                sparkVX[i] = random( 1000 ) - 500;
                sparkVY[i] = random(  500 );
                intS[i] = true;
            }
        }
        public function moveSpark():void
        {
            for( var i:int = 0 ; i < sN ; i++ )
            {
                if( intS[i] == false ){continue;}
                sparkX[i] += sparkVX;
                sparkY[i] += sparkVY;
                if( delCorner( sparkX[i], sparkY[i], 3, 3 ) )
                {
                    intS[i] = false;
                }
            }
        }
        public function initEbullet( j:int ):void
        {
            for( var i:int = 0 ; i < mN ; i++ )
            {
                if( !eBullFrag[i] )
                {
                    eBullX[i] = new Number();;
                    eBullY[i] = new Number();
                    eBullX[i] = t2X[j];
                    eBullY[i] = t2Y[j];
                    initAim( t2X[j], t2Y[j], posX, posY, i );
                    eBullFrag[i] = true;
                    break;
                }
            }
        }
        public function initAim( bX:Number, bY:Number, tX:Number, tY:Number, i:int ):void
        {
            var stX:Number
            var stY:Number
            var sb:Number
            
            stX = tX - bX;
            stY = tY - bY;
            sb = sqrt( stX * stX + stY * stY );
            eBullVX[i] = stX / sb * eBullV;
            eBullVY[i] = stY / sb * eBullV;
        }
        public function drawEbullet():void
        {
            for( var i:int = 0 ; i < mN ; i++ )
            {
                if( eBullFrag[i] )
                {
                    eBullX[i] += eBullVX[i];
                    eBullY[i] += eBullVY[i];
                    fill( 0, 200, 100 );
                    stroke(0);
                    rect( eBullX[i], eBullY[i], 10, 10 );
                    if( delCorner( eBullX[i], eBullX[i], 10, 10 ) )
                    {
                        eBullFrag[i] = false;
                    }
                }
            }
        }
        public function initNway( num:int, nTheta:Number ):void
        {
            var radStep:Number = pi / 180 * nTheta;
            var rad:Number = num % 2 ? -num / 2 * radStep :
                                     ( -num / 2 + 0.5 ) * radStep;
                                     
            for( var i:int = 0 ; i < num ; i++, rad += radStep )
            {
                if( !bulletFrag[i] )
                {
                    var c:Number = cos( rad );
                    var s:Number = sin( rad );
                
                    vNx[i] = new Number();
                    vNy[i] = new Number();
                    vNx[i] = vX0 * c - vY0 * s;
                    vNy[i] = vX0 * s + vY0 * c;
                    
                    bulletFrag[i] = true;
                    
                    break;
                }
            }
        }
        public function drawNway():void
        {
            for( var i:int = 0 ; i < mN ; i++ )
            {
                if( bulletFrag[i] )
                {
                    noStroke();
                    fill(0,0,255);
                    ellipse( bulletX[i],bulletY[i],10, 10 );
                    bulletX[i] += vNx[i];
                    bulletY[i] += vNy[i];
                    hitTarget( bulletX[i], bulletY[i], i );
                }
                if( delCorner( bulletX[i], bulletY[i], 10, 10 ) )
                {
                    bulletFrag[i] = false;
                }
            }
        }
        public function initDir( dTheta:Number ):void
        {
            vX0 = cos( pi / 180 * dTheta ) * v;
            vY0 = sin( pi / 180 * dTheta ) * v;
        }
    }
}

// 以下は,動きを記述するためのクラスですので,編集しないでください.
import flash.utils.getTimer;
import frocessing.math.PerlinNoise;
/**
 * Interpolate:指定した時間で,開始値から終値までの過渡的を
 *             記述するクラス
 */
class Interpolate
{
    private static const NOINIT  :int = 1;
    private static const RUNNING :int = 2;
    private static const WAITING :int = 3;
    private static const STOPPED :int = 4;
    private var duration  :Number;
    private var begin     :Number;
    private var end       :Number;
    private var pow       :Number;
    private var tOffset   :Number;
    private var tElapsed  :Number;
    private var prevVal   :Number;
    private var tRestart  :Number;
    public  var status    :int = NOINIT;
    public function Interpolate( t:Number, s:Number, f:Number,
                                 p:Number = 1) {
        begin = prevVal = s;
        end = f;
        duration = t;
        pow = p;
        tOffset = 0;
        tElapsed = 0;
    }
    public function val() :Number {
        var t :Number;
        if( status == NOINIT){
            tOffset = getTimer()/1000;
            prevVal = begin;
            status = RUNNING;
        } else if( status == RUNNING ) {
            t = getTimer()/1000;
            tElapsed = t -tOffset;
            if( tElapsed < duration ) {
                prevVal = begin + ( end - begin )*Math.pow(tElapsed/duration,pow);
            } else {
                prevVal = end;
                status = STOPPED;
            }
        } else if( status == WAITING){
            t = getTimer()/1000;
            if( t >= tRestart) {
                status = RUNNING;
                tOffset = t - tElapsed;        
            }
        }
        return prevVal;
    }
    public function pause() :void
    {
        status = STOPPED;
    }
    public function cont() :void
    {
        status = RUNNING;
        tOffset = getTimer()/1000-tElapsed;        
    }
    public function start() :void
    {
        status = RUNNING;
        tOffset = getTimer()/1000;                
    }
    public function wait( waitTime :Number ) :void
    {
        status = WAITING;
        tRestart = getTimer() + waitTime;
    }
    
    public function isRunning() :Boolean
    {
        if( status == RUNNING ) {
            return true;
        } else {
            return false;
        }
    }
    public function isStopped() :Boolean
    {
        if( status == STOPPED ) {
            return true;
        } else {
            return false;
        }
    }
    public function isEnd() :Boolean
    {
        if( prevVal >= end) {
            return true;
        } else {
            return false;
        }
    }
}
/**
 * LFO:指定した時間での周期的変動を記述するクラス
 */
class LFO {
    public static const SIN    :int = 1;
    public static const COS    :int = 2;
    public static const SAW    :int = 3;
    public static const TRI    :int = 4;
    public static const SQR    :int = 5;
    public static const ABSSIN :int = 6;
    public static const NOISE  :int = 7;
    private static const NOINIT  :int = 1;
    private static const RUNNING :int = 2;
    private static const WAITING :int = 3;
    private static const STOPPED :int = 4;
    private var period    :Number;
    private var amplitude :Number;
    private var phase     :Number;
    private var offset    :Number;
    private var type      :int = SIN;
    private var isStart   :Boolean;
    private var t_offset  :Number;
    private var status    :int = NOINIT;
    
    public function LFO( prd :Number, amp :Number,
                         of :Number = 0, ph :Number = 0)
    {
        period    = prd;
        amplitude = amp;
        offset    = of;
        phase     = ph;
    }
    public function setPeak( min :Number, max :Number) :void
    {
        offset = (min + max) / 2;
        if( min < max ) {
            amplitude    = (max - min) / 2;
        } else {
            amplitude    = (min - max) / 2;
        }        
    }
    public function setType( t :int ) :void
    {
        type = t;
    }
    public function val( mul :Number=1.0 ) :Number {
        if(status == NOINIT) {
            status = RUNNING;
            t_offset = getTimer() / 1000.0;
            return val();
        } else if(status == RUNNING ) {
            var t :Number = getTimer() / 1000.0 - t_offset;
            var temp :Number;
            switch(type) {
                case SIN :
                    return  offset + mul * amplitude * 
                    Math.sin(2.0 * Math.PI *( t/period + phase) );
                case COS :
                    return  offset + mul * amplitude *
                    Math.cos(2.0 * Math.PI *( t/period + phase) );
                case SAW :
                    temp = t / period + 0.5 + phase - 
                    Math.floor( t / period + 0.5 + phase ) - 0.5;
                    return  offset + 2.0 * mul * amplitude * temp;
                case TRI :
                    temp = t / period + phase - 
                    Math.floor (t / period + phase );
                    if( 0.0 <= temp && temp < 0.25 ) {
                        return offset + mul * amplitude * 4.0 * temp;
                    } else if( temp < 0.75 ) {
                        return offset + mul * amplitude * (  2.0 - 4.0 * temp);
                    } else {
                        return offset + mul * amplitude * ( -4.0 + 4.0 * temp);
                    }
                case SQR :
                    temp = t/period + phase - 
                    Math.floor( t / period + phase);
                    if( temp < 0.5 ){
                        return offset + mul * amplitude;
                    } else {
                        return offset - mul * amplitude;
                    }
                case ABSSIN :
                    return  offset + 
                    Math.abs(mul * amplitude * Math.sin(2.0*Math.PI *( t/period + phase)));
                case NOISE :
                    var p :PerlinNoise = new PerlinNoise(); 
                    return offset -mul * amplitude + 2.0 * mul * amplitude * p.noise(t/period+phase,1);
                default :
                    return 0.0;
            }
        } else {
            return 0.0;
        }        
    }
}    

Forked