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: 質問:探索順を波紋のようにしたい

色が変更される順番を、クリック箇所を中心に波紋が広がるようにしたいのですが、
どのようにしたらよいでしょう?

色変更中のクリック制御などはしていません。テストなので。

-----
MobileHackerz/MIRO
はじめてのActionScriptいじりちゅう。
資料も見ずにベースのコードだけを参考にみようみまねで書いてみました。
元のコードとはだいぶ構造を変えて、各ブロックが自律的に動くような感じになっています。

クリックされたブロックは自分に対して「色を変えろ」と指示を出します。
「色を変えろ」と指示されたブロックは、自分の周囲のブロック(Neighbors)に対しても
同じように「色を変えろ」と指示を出します。その連鎖で色が変化していきます。
/**
 * Copyright MobileHackerz ( http://wonderfl.net/user/MobileHackerz )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/pZts
 */

// forked from dada_sygnas's 質問:探索順を波紋のようにしたい
/*
色が変更される順番を、クリック箇所を中心に波紋が広がるようにしたいのですが、
どのようにしたらよいでしょう?

色変更中のクリック制御などはしていません。テストなので。

-----
MobileHackerz/MIRO
はじめてのActionScriptいじりちゅう。
資料も見ずにベースのコードだけを参考にみようみまねで書いてみました。
元のコードとはだいぶ構造を変えて、各ブロックが自律的に動くような感じになっています。

クリックされたブロックは自分に対して「色を変えろ」と指示を出します。
「色を変えろ」と指示されたブロックは、自分の周囲のブロック(Neighbors)に対しても
同じように「色を変えろ」と指示を出します。その連鎖で色が変化していきます。
*/

package{	
	import flash.display.MovieClip;	
	import flash.display.Sprite;
	import flash.events.*;
	import caurina.transitions.Tweener;
	import caurina.transitions.properties.ColorShortcuts;
	
    [SWF(backgroundColor="#FFFFFF", frameRate=25)]
	
	public class Hirogari extends MovieClip{
	    
		public static const W:int		= 20;
		public static const H:int		= 20;
		public static const SIZE:int	= 15;
		
		protected var blockList:Array;	// ブロック管理
		
		/**************************
		* コンストラクタ
		*/
		public function Hirogari(){
		    var block:Block;
		    var x:int;
		    var y:int;
		    
			super();

			ColorShortcuts.init();
			blockList = [];
			
			// ブロックの作成
			for( y=0; y<H; y++ ){
				blockList[y] = [];
				
				for( x=0; x<W; x++ ){
					block = new Block( x, y, SIZE );
					blockList[y][x] = block;
					addChild( block );
				}
			}
			// ブロックの隣接リンク関係の作成
			for( y=0; y<H; y++ ){
			    for( x=0; x<W; x++ ){
			        block = blockList[y][x];
			        block.Neighbors = [];
			        if ( x>0     ) { block.Neighbors.push( blockList[y][x-1] ); }
			        if ( y>0     ) { block.Neighbors.push( blockList[y-1][x] ); }
			        if ( x<(W-1) ) { block.Neighbors.push( blockList[y][x+1] ); }
			        if ( y<(H-1) ) { block.Neighbors.push( blockList[y+1][x] ); }
			    }
			}			
		}
	}
}


/**************************
* ブロックのクラス
*/
import flash.display.Sprite;

class Block extends Sprite{
    import flash.events.*;
    import caurina.transitions.Tweener;

    // 色候補	
    private static const COLOR:Array		= [ 0x33ccff, 0xffcc33 ];

    // 隣接関係
    public var      Neighbors:Array;

    // 自分の属性
    private var     posX:int;
    private var     posY:int;
    private var     color:Number;
    private var     brightness:Number;
    private var     sequenceNum:int;

	/********************
	* コンストラクタ
	*/
	public function Block( myX:int, myY:int, size:int ):void{
		brightness = 0;
		color = COLOR[ Math.floor(Math.random()*COLOR.length)];
		
		graphics.lineStyle( 1, 0x999999 );
		graphics.beginFill( color );
		graphics.drawRect( 0, 0, size, size );
		graphics.endFill();
		
		x = myX * size;
		y = myY * size;
		sequenceNum = 0;
		
		posX = myX;
		posY = myY;

		useHandCursor = true;
		buttonMode = true;
		addEventListener( MouseEvent.CLICK, onClick );
	}
	
	/********************
	* 隣接ブロック数をカウントする
	*/
	public function countNeighbor( col:Number, num:int, seq:int ):int {
	    var block:Block;
 
	    if ((col == color) && (seq>sequenceNum)) {
	        // 自分自身を数える
	        num = num + 1;
	        // 重複処理しないよう現処理が完了したことを記録
	        sequenceNum = seq;
	        // 隣接もチェック
	        for each (block in Neighbors) {
	            num = block.countNeighbor(col,num,seq);
	        }
	    }
	    return num;
	}

	/********************
	* 隣接ブロックの色を変える
	*/
    public function changeColor( col:Number, x:int, y:int, seq:int ):void {
        var block:Block;
        var delay:Number;
        
        if ((col == color) && (seq>sequenceNum)) {
	        // delayを計算
	        delay = Math.sqrt((x-posX)*(x-posX)+(y-posY)*(y-posY)) / 10;
	        // brightness(元処理から変更)
            if (brightness < 0.1) {
                brightness = 0.5;                
            } else {
                brightness = 0;
            }
    		Tweener.addTween( this, {_brightness:brightness, time:0.5, delay:delay} );
	        // 重複処理しないよう現処理が完了したことを記録
	        sequenceNum = seq;
	        // 隣接チェック
	        for each (block in Neighbors) {
	            block.changeColor(col,x,y,seq);
	        }
	    }
	}

	/********************
	* クリックされた!
	*/
	protected function onClick( e:MouseEvent ):void{
	    if (countNeighbor(color,0,sequenceNum+1)>=2) {
	        changeColor(color,posX,posY,sequenceNum+1);
	    }
	}
}