Beautifl - Flash Gallery

Preview

Xm.as
octech 2009年12月15日 All rights reserved
?
----- Xm.as --- octech 2008 ----- //
      // ----- Xm.as --- octech 2008 ----- //
package {
  import caurina.transitions.Tweener;
  import flash.display.*;
  import flash.filters.GlowFilter;
  import flash.geom.*;
  import flash.text.*;
  import flash.events.*;
  [SWF(frameRate = "24", backgroundColor = "#333333")]
  
  public class Xm extends Sprite {
    static private const  MODE_EDIT:int = 0;
    static private const  MODE_VIEW:int = 1;
    static private const  NUM_MODE:int  = 2;
    static private const  P_SIZE:int      = 12; // パーティクルの一辺の長さ(pixel)
    static private const  GRAVITY_Y:Number  = 1.4;  // パーティクルの基本速度.
    
    private var _mode:int   = 0;  // MODE_EDIT, MODE_VIEW
    private var _scenes:Vector.<Sprite> = null; // _modeに対応
    private var _bitmapdata:BitmapData  = null;
    private var _editRects:Array    = [];
    private var _particles:Array    = [];
    private var _pauseView:Boolean    = false;
    
    // コンストラクタ.
    public function Xm() {
      addEventListener(Event.ADDED_TO_STAGE, init);
    }
    
    // 初期化.
    private function init(e:Event) :void {
      stage.align = "TL";
      stage.scaleMode = "noScale";
      
      _scenes = new Vector.<Sprite>( NUM_MODE );
      
      // draw SKY.
      var g:Graphics  = this.graphics;
      var gm:Matrix = new Matrix();
      gm.createGradientBox( stage.stageWidth, stage.stageHeight, Math.PI / 2, 0, 0 );
      g.beginGradientFill( GradientType.LINEAR, [ 0x000011, 0x333344 ], [1, 1], [0, 255], gm );
      g.drawRect( 0, 0, stage.stageWidth, stage.stageHeight );
      g.endFill();
      
      // シーン作成.
      _scenes[MODE_VIEW]  = new Sprite();
      addChild( _scenes[MODE_VIEW] );
      setupView( _scenes[MODE_VIEW], stage.stageWidth, stage.stageHeight );
      _scenes[MODE_EDIT]  = new Sprite();
      addChild( _scenes[MODE_EDIT] );
      setupEdit( _scenes[MODE_EDIT], stage.stageWidth, stage.stageHeight );
      
      stage.addEventListener( MouseEvent.MOUSE_MOVE, checkModeToEdit );
      stage.addEventListener( Event.MOUSE_LEAVE, checkModeToView );
      
      // パーティクル基本データ作成.
      _bitmapdata = new BitmapData( P_SIZE, P_SIZE, true, 0x00FFFFFF );
    }
    
    private function checkModeToEdit(e:MouseEvent):void {
      setMode( MODE_EDIT );
    }
    
    private function checkModeToView(e:Event):void {
      setMode( MODE_VIEW );
    }
    
    // エディットモードを作成.
    private function setupEdit( s:Sprite, w:int, h:int ) :void {
      var g:Graphics  = s.graphics;
      g.beginFill( 0x663333, 1.0 );
      g.drawRect( 0, 0, w, h );
      
      const EDITAREA_SIZE:Number  = 200;
      const EDITAREA_X0:Number    = stage.stageWidth/2 - EDITAREA_SIZE/2;
      const EDITAREA_Y0:Number    = 10;
      const EDITBOX_SIZE:Number   = EDITAREA_SIZE / P_SIZE; // 一つの矩形のサイズ.
      var   py:int, px:int;
      for ( py = 0; py < P_SIZE; py++) {
        for ( px = 0; px < P_SIZE; px++) {
          s.addChild( 
            addEditRect( EDITAREA_X0 + px * EDITBOX_SIZE, EDITAREA_Y0 + py * EDITBOX_SIZE,
                         EDITBOX_SIZE, EDITBOX_SIZE )
          );
        }
      }
      
      // 初期化X
      if ( P_SIZE == 12 ) {
        for ( py = 0; py < P_SIZE; py++) {
          for ( px = 0; px < P_SIZE; px++) {
            var er:EditRect  = _editRects[py * P_SIZE + px] as EditRect;
            if ( (px == py || px == P_SIZE-py-1) && (px >= 2 && px < 10) ) {
              er.onoff  = true;
            }
            else {
              er.onoff  = false;
            }
          }
        }
      }
      
      // text
      var t:TextField = new TextField();
      s.addChild(t);
      t.text  = "You can draw the snow flake.\n\n"
          +"After drawing,\nmove cursor out from flash area.\n\n"
          + "Xm.as --- octech 2008.\nMerry Christmas !";
      t.selectable  = false;
      t.autoSize = TextFieldAutoSize.LEFT;
      t.setTextFormat(new TextFormat(null, 12, 0xcccccc));
      t.x   = EDITAREA_X0;
      t.y   = EDITAREA_Y0 + EDITBOX_SIZE * P_SIZE + 15;
    }
    
    // エディットモードの一つの箱を配置.
    private function addEditRect( ex:Number, ey:Number, ew:Number, eh:Number ) :EditRect {
      var newEditRect:EditRect  = new EditRect( ew, eh );
      _editRects.push( newEditRect );
      newEditRect.x = ex;
      newEditRect.y = ey;
      return newEditRect;
    }
    
    // ビューモードを作成.
    private function setupView( s:Sprite, w:int, h:int ) :void {
      s.addEventListener( Event.ENTER_FRAME, processView );
      var g:Graphics  = s.graphics;
      
      // draw RAND-TOWN.
      const MAX_X:Number    = stage.stageWidth;
      const MIN_HEIGHT:Number = 10, RAND_HEIGHT:Number  = 20;
      const MIN_WIDTH:Number  = 10, RAND_WIDTH:Number   = 40;
      var accX:Number = 0;
      var curW:Number = 0, curH:Number  = 0;
      const BOTTOM:Number = stage.stageHeight;
      g.beginFill( 0xFFFFFF, 1.0 );
      while ( accX < MAX_X ) {
        curH  = Math.random() * RAND_HEIGHT + MIN_HEIGHT;
        curW  = Math.random() * RAND_WIDTH + MIN_WIDTH;
        g.drawRect( accX, BOTTOM - curH, curW, curH );
        accX  += curW;
      }
      g.endFill();
      
      // draw TREE.
      const TX:Number = stage.stageWidth - 100;
      const TW:Number = 40, TH:Number = 15;
      const TB:Number = BOTTOM - MIN_HEIGHT;
      const TE:Number = 10;
      const TNUM:int  = 4;
      for (var i:int = 0; i < TNUM; i++) {
        g.beginFill( 0xFFFFFF, 1.0 );
          g.moveTo( TX, TB - i * TH );
          g.lineTo( TX + TW, TB - i * TH );
          g.lineTo( TX + TW/2, TB - ((i+1) * TH) - TE );
          g.lineTo( TX, TB - i * TH );
        g.endFill();
      }
      const StarR:Number  = 15;
      var   StartX:Number = TX + TW / 2, StartY:Number = TB - TNUM * TH - TE;
      var VTheta:Vector.<Number>  = Vector.<Number>([
        0.1 * Math.PI, 0.5 * Math.PI, 0.9 * Math.PI, 1.3 * Math.PI, 1.7 * Math.PI ]);
      const VVtx:Vector.<Number>  = Vector.<Number>( [
        StartX + StarR*Math.cos(VTheta[0]), StartY - StarR*Math.sin(VTheta[0]),
        StartX + StarR*Math.cos(VTheta[2]), StartY - StarR*Math.sin(VTheta[2]),
        StartX + StarR*Math.cos(VTheta[4]), StartY - StarR*Math.sin(VTheta[4]),
        StartX + StarR*Math.cos(VTheta[1]), StartY - StarR*Math.sin(VTheta[1]),
        StartX + StarR*Math.cos(VTheta[3]), StartY - StarR*Math.sin(VTheta[3]),
        StartX + StarR*Math.cos(VTheta[0]), StartY - StarR*Math.sin(VTheta[0]) ] );
      g.beginFill( 0xFFFF66, 1.0 );
      g.drawPath( Vector.<int>([1,2,2,2,2,2]), VVtx, "nonZero" );
      g.endFill();
      
      // グロー.
      s.filters = [ new GlowFilter( 0xFFFFFF, 2.0, 16.0, 16.0, 1.0, 2 ) ];
    }
    
    // モード切替.
    private function setMode( mode:int ) :void {
      if( _mode != mode ){
        _mode = mode;
        switch ( _mode ) {
        case MODE_EDIT:
          _pauseView    = true;
          Tweener.addTween( _scenes[MODE_EDIT], { alpha:0.9, time:0.6 } );
          break;
        case MODE_VIEW:
          applyParticle();
          _pauseView    = false;
          Tweener.addTween( _scenes[MODE_EDIT], { alpha:0.0, time:1.2 } );
          break;
        }
      }
    }
    
    // 編集情報を、ビットマップデータに適用.
    private function applyParticle() :void {
      for (var py:int = 0; py < P_SIZE; py++) {
        for (var px:int = 0; px < P_SIZE; px++) {
          var er:EditRect = _editRects[py * P_SIZE + px] as EditRect;
          _bitmapdata.setPixel32( px, py, (er.onoff ? 0xFFFFFFFF : 0x00FFFFFF) );
        }
      }
    }
    
    // ビューモードの毎フレームの処理.
    private function processView( e:Event ) :void {
      if ( _pauseView )
        return; // ポーズ中.
      
      // 新規作成.
      var sView:Sprite  = _scenes[MODE_VIEW];
      var newP:Sprite = createNewParticle();
      if( sView != null && newP != null ){
        sView.addChild( newP );
        newP.x  = Math.random() * sView.width;
        newP.y  = -newP.height;
      }
      
      // 落下.
      for (var i:int = 0; i < _particles.length; i++) {
        var p:Sprite  = _particles[i];
        if ( p == null ) {    continue;    }
        p.x += (Math.random()-0.5) * 0.8;
        p.y += GRAVITY_Y + 0.2*Math.random();
        p.rotation  += 2.0 + (Math.random() * 3.0);
        if ( p.y > stage.stageHeight + p.height ) { // dead.
          sView.removeChild( _particles[i] );
          _particles[i] = null;
        }
      }
    }
    
    // 新しくパーティクルを作成します.
    private function createNewParticle() :Sprite {
      const P_SIZE_HALF:Number  = P_SIZE / 2;
      var newP:Sprite  = new Sprite();
      var pm:Matrix     = new Matrix();
      pm.translate( -P_SIZE_HALF, -P_SIZE_HALF );
      newP.graphics.beginBitmapFill( _bitmapdata, pm );
      newP.graphics.drawRect( -P_SIZE_HALF, -P_SIZE_HALF, P_SIZE, P_SIZE );
      newP.graphics.endFill();
      
      for (var i:int = 0; i < _particles.length; i++) {
        if ( _particles[i] == null ) {
          _particles[i] = newP;  // 空きがあればそこに追加.
          return newP;
        }
      }
      _particles.push( newP );   // 空きがなければ末尾に追加.
      return newP;
    }
  }
}

import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.MouseEvent;
class EditRect extends Sprite {
  
  static private const  MARGIN:Number = 1;
  
  private var _w:Number, _h:Number;
  private var _onoff:Boolean  = true;
  
  public function EditRect( w:Number, h:Number ) {
    _w  = w;    _h  = h;
    onoff = true;
    addEventListener( MouseEvent.ROLL_OVER, checkChange );
    addEventListener( MouseEvent.MOUSE_DOWN, checkChange );
  }
  
  private function checkChange(e:MouseEvent):void {
    switch ( e.type ) {
    case MouseEvent.MOUSE_DOWN:
      toggleOnoff();
      break;
    case MouseEvent.ROLL_OVER:
      if ( e.buttonDown )
        toggleOnoff();
      break;
    }
  }
  
  private function toggleOnoff()  :void { onoff = !onoff; }
  
  public function set onoff( value:Boolean ) :void {
    var g:Graphics  = this.graphics;
    g.clear();
    _onoff  = value;
    if ( _onoff )
      g.beginFill( 0x999999, 1.0 );
    else
      g.beginFill( 0x333333, 0.5 );
    g.drawRect( MARGIN, MARGIN, _w - MARGIN * 2, _h - MARGIN * 2 );
  }
  public function get onoff() :Boolean  { return _onoff;  }
}