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

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

色変更中のクリック制御などはしていません。テストなので。
/**
 * Copyright keno42 ( http://wonderfl.net/user/keno42 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/saM7
 */

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

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

*/

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 $delay:Number;
		protected var $blockList:Array;	// ブロック管理
		protected var $endList:Array;	// チェック済みブロック
		protected var $hitList:Array;	// 同じ色だったブロックのリスト
		
		/**************************
		* コンストラクタ
		*/
		public function Hirogari(){
			super();

			ColorShortcuts.init();
			$blockList = [];
			
			// ブロックの作成
			for( var y:int=0; y<H; y++ ){
				$blockList[y] = [];
				
				for( var x:int=0; x<W; x++ ){
					var block:Block = new Block();
					
					block.init( x, y );
					block.addEventListener( MouseEvent.CLICK, ___onClick );
					
					$blockList[y][x] = block;
					addChild( block );
				}
			}
			
		}
		
		/**************************
		* クリックされた
		*/
		protected function ___onClick( e:MouseEvent ):void{
			var clickX:int = e.target._posX;
			var clickY:int = e.target._posY;
			var color:Number = e.target._color;	// クリックしたブロックの色
			
			$endList = [];	// チェック完了したものを入れる
			$hitList = [];	// 同じ色のブロックを入れる
			$delay = 0;
			
			// 周囲をチェック
			___checkAround( [{x:clickX, y:clickY}], color, 0 );

			// 2つ以上連続している場合のみ処理
			if( $hitList.length >= 2 ){
				___changeColor();
			}
		}
		
		/**************************
		* 周囲をチェック
		*/
		protected function ___checkAround( xyObjs:Array, color:Number, d:int ):void{
			var nextObjs:Array = []; // 次の距離のブロックのリスト
                        var count:int = xyObjs.length; // 等距離ブロックのリスト
                        d++; // 距離

                        for( var i:int = 0; i < count; i++){
                            var x:int = xyObjs[i].x;
                            var y:int = xyObjs[i].y;
                            
    			    // ダブリチェックの内容に一度処理したものは格納しておく
			    // 位置を数値に変換して保存
			    var posId:int = (y*W) + x;
			    $endList[posId] = true;

    			    $hitList.push( {x:x, y:y, d:d} );
    			    // 未チェックブロックで、同じ色だけチェック対象にする
			    // 左
			    if( x>0 && $endList[posId-1] != true ){
				if( color == $blockList[y][x-1]._color ){
            			    $endList[posId-1] = true;
				    nextObjs.push({x:x-1, y:y});
				}
			    }
			    // 右
			    if( x<W-1 && $endList[posId+1] != true ){
				if( color == $blockList[y][x+1]._color ){
            			    $endList[posId+1] = true;
				    nextObjs.push({x:x+1, y:y});
				}
			    }
			    // 上
			    if( y>0 && $endList[posId-W] != true ){
				if( color == $blockList[y-1][x]._color ){
            			    $endList[posId-W] = true;
			            nextObjs.push({x:x, y:y-1});
				}
                            }
			    // 下
			    if( y<H-1 && $endList[posId+W] != true  ){
				if( color == $blockList[y+1][x]._color ){
            			    $endList[posId+W] = true;
				    nextObjs.push({x:x, y:y+1});
				}
			    }
                        }
                        if( nextObjs.length ) ___checkAround( nextObjs, color, d );
		}
		
		/**************************
		* 連続したブロックの色を変更
		*/
		protected function ___changeColor():void{
			var x:int, y:int;
			var block:Block;
			
			// 該当ブロックを対象に色を変更
			for( var i:int=0; i<$hitList.length; i++ ){
				x = $hitList[i].x;
				y = $hitList[i].y;
				block = $blockList[y][x];
				// 距離dに応じてdelay
				Tweener.addTween( block, {_brightness:block.brightness, time:0.5, delay:$hitList[i].d*0.1} );
			}
		}
		
	}
	
}

import flash.display.Sprite;

/**************************
* ブロックのクラス
*/

class Block extends Sprite{
	
	public static const COLOR:Array		= [ 0x33ccff, 0xffcc33 ];
	
	public var _posX:int;			// 配列上の位置
	public var _posY:int;
	public var _color:Number;

	protected var $brightness:Number;	// 明るさ

	/********************
	* 明るさの取得と変更
	*/
	public function get brightness():Number{
		$brightness += 0.5;
		return $brightness;
	}
	
	/********************
	* 初期化
	*/
	public function init( myX:int, myY:int ):void{
		$brightness = 0;
		_color = COLOR[ Math.floor(Math.random()*COLOR.length)];
		
		this.graphics.lineStyle( 1, 0x999999 );
		this.graphics.beginFill( _color );
		this.graphics.drawRect( 0, 0, Hirogari.SIZE, Hirogari.SIZE );
		this.graphics.endFill();
		
		this.x = myX * Hirogari.SIZE;
		this.y = myY * Hirogari.SIZE;
		
		this._posX = myX;
		this._posY = myY;

		this.useHandCursor = true;
		this.buttonMode = true;
	} 
}