paper.jsでライフゲーム2
ライフゲーム
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();