paper.jsでライフゲーム2

ライフゲーム


paper.jsによるライフゲーム

canvasをクリックで初期状態に。
大きいものが見たい方、cpuコア一個分ぐらい消費してもいい方はこちら

前回からの変更点

  • 前回のライフゲームの計算式が間違っていたので修正
  • 復活時にランダムに輝度を下げる円を作成
  • 動作軽量化のため円の枠線排除、
  • 円の大きさを大きくして表示する数現象
  • 左端など、画面外の部分を計算に含める場合、右端から折り返して計算。


ソース

var width = view.viewSize.width;
var height = view.viewSize.height;
var circleSize = 12;
var widthNum = Math.floor(width/circleSize);
var heightNum = Math.floor(height/circleSize);
var circles = [];
var maxCount  = 32;

function defaultAlign(){
	for( var w =0;w < widthNum;w++){
		for( var h =0;h< heightNum;h++){
			if( !circles[w]){
				circles[w] = new Array();
			}
			circle = new Path.Circle(
				new Point(w*circleSize+circleSize/2,h*circleSize+circleSize/2), circleSize/2-1 );
			//circle.strokeColor = '#fffc';
			//circle.strokeWidth = 1;
			circles[w][h] = circle;
		}
	}
}

function setCircle(){
	for( var w =0;w < widthNum;w++){
		for( var h =0;h< heightNum;h++){
			circles[w][h].fillColor
				= new HsbColor(w*360/widthNum*2,h*1/heightNum,1);
			circles[w][h].visible = Math.floor(Math.random()+0.25) >= 1;
			circles[w][h].preVisible = circles[w][h].visible;
		}
	}
}

function onFrame( event ){
	if( event.count % maxCount !== 0 ) return;

	for( var w =0;w < widthNum;w++){
		for( var h =0;h< heightNum;h++){

			var cal = neibhorCalcuate( w, h );
			if ( circles[w][h].preVisible ){
				if( 2 <= cal.sum && cal.sum < 4){
					circles[w][h].visible =true;
				} else {
					circles[w][h].visible = false;
				}
			} else {
				if( cal.sum === 3){
					circles[w][h].visible =true;
					circles[w][h].fillColor = cal.color;
				}
			}
		}
	}
	for( var w =0;w < widthNum;w++){
		for( var h =0;h< heightNum;h++){
			circles[w][h].preVisible = circles[w][h].visible;
		}
	}

}

function neibhorCalcuate( w, h ){
	var sum = 0;
	var hue = 0;
	var saturation = 0;
	var brightness  = 0;
	for( var x = w-1; x<=w+1;x++){
		for( var y = h-1; y<=h+1;y++){
			if( w == x && h ==y ){
				continue;
			}

			var c = circles[(x+widthNum)%widthNum][(y+heightNum)%heightNum];
			if ( c.preVisible ){
				sum++;
				hue += c.fillColor.hue;
				saturation += c.fillColor.saturation;
				brightness  += c.fillColor.brightness;
			}
		}
	}
	var brh;
	if( Math.random() > 0.8 ){
		brh  = Math.random()+0.5;
	} else{
		brh = brightness /sum;
	}

	return {
		'sum':sum,
		'color': new HsbColor(hue/sum,saturation/sum,brh)
	};
}

function onMouseDown(){
	setCircle();
}

defaultAlign();
setCircle();