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);
}
}
}