読者です 読者をやめる 読者になる 読者になる

FOR SE

文系の学部から新卒でメーカー系のSIerに就職。技術・スキルがないためブログを通して勉強。その後、IT業界の業界知識が活かせる人材業界に就職

このエントリーをはてなブックマークに追加

【HTML5・javascript】ライフゲームより簡単なサンプルを作る

【今回の紹介】

以下のサイトでHTML5javascriptでできるライフゲームに興味を持った。


参考:ライフゲーム



今回は、そのライフゲームで行っている処理のうち、以下のような部分を切り出して
サンプルを作ったので紹介。
 ①キャンパス内にセルを敷き詰める考え方をする
 ②セルごとに描くかどうかの判定する値を設定すること
 ③②で設定した値をもとにセルごとに描くかどうか判定、描画すること




ざっくりですが、実際のライフゲームのソースをみる限り、以下のようなことを行っているようです。
 ①初期設定
  ・キャンパスのサイズ設定
  ・キャンバスのobjを取得
  ・キャンバス内に敷き詰める総セル分の配列を作成
  ・配列に初期値を設定
 
 ②更新処理
  ・現在の総セル野配列を取得
  ・対象セルに対し、以下の生か死の判定処理
   ・8方向のセルの情報を取得(異なる行・列を取得できるようなfor文)
   ・縦と横の壁判定
   ・自分は対象にならない判定
  ・総セルに対して、生か死の判定処理が終わったら描画処理にわたす
  ・更新処理と描画処理の再起処理

 ③描画処理
  ・②でセットされた値を描画する

【内容】

上でも紹介しているが、実際には以下のようなことを行い、ライフゲームより簡単な
キャンパス内をまだら模様に着色するサンプルを作成しました。


 ①キャンパス内にセルを敷き詰める考え方をする
 ②セルごとに描くかどうかの判定する値を設定すること
 ③②で設定した値をもとにセルごとに描くかどうか判定、セルごとに描くこと



【メモ】

①ある領域に着色したいときの考えがおもしろい

  きっと当たり前なのかもしれないけど、
  ある領域に
   ①配列を敷き詰める
   ②それぞれの添字に値を持たせる
   ③値をもとに着色するかを判定、着色
  という処理が学べておもしろかった。この考え方は汎用的で他の部分でもつかわれているんだろうなと、
  ちなみにライフゲームになると
   ・再起処理
   ・着色判定が複雑になる(周りのセルの値を取得し、判定する)
  なる印象。


②複雑にしている部分を削ぎ落として、シンプルなサンプルを作ること

  
   ・コピーペですれば、動く
   ・処理の流れが追えばわかる(なにもみないでかけるではなく、なんとなくやっていることはわかる程度)
  では、やはり理解不足だし、応用が利かない気がする
  
複雑にしている部分を削ぎ落として、シンプルなサンプルを自分で作ってみることで、
   ・この1行はなんためにやっているか理解がすすむ
   ・この部分を変更したら、こういう変化が起きるということをつかめるようになるし、
    この部分を変更してこうしたいというのも出てきやすい気がする。
  

③ロジックを考える部分がおもしろい

  
  自分はまだまだ未熟だし、参考ソースのロジックを考えるのにも考えてしまうが、ロジックを考えているのは楽しい。
  同じようなロジックを参考のライフゲームサイトで実装しているが今回はなるべくみないように作った。
  「まだらにするには」、「セル座標とその着色面積は」とか考え、ロジックにおとして、思い通りになる瞬間は
  気持ちよい。

【参考ソース】

<html>
<head>
<meta charset='utf-8'>
</head>
<title>HTML5</title>
<body>
<h1>キャンバス</h1>
<canvas id='canvas'></canvas>

<script>
var SCREEN_SIZE = 600; // キャンバスの幅
var SIDE_CELLS = 30; // 一辺のセルの数
var CELL_SIZE = SCREEN_SIZE / SIDE_CELLS; // セルの幅
var canvas; //= document.getElementById('world');
var context; //= canvas.getContext('2d');

//読み込み後、行う処理
window.onload = function() {
	canvas=$("canvas");
	canvas.width = canvas.height = SCREEN_SIZE; // キャンバスのサイズを設定
    default_set();
	}

//キャンパス内の配列に初期値を設定する//
//まだら模様にするために1行ごとに初期設定が変える//
function default_set(){
	var sum_cell= new Array(CELL_SIZE*CELL_SIZE);
	for(var i=0;i<sum_cell.length;i++){
		if(Math.floor(i/CELL_SIZE)%2==0){

			if(i%2==1){
				sum_cell[i]=1;}
			else{
				sum_cell[i]=0;
			}
		}
		else{
			if(i%2==0){
				sum_cell[i]=1;}
			else{
				sum_cell[i]=0;
			}
		}

	}
	draw(sum_cell);
}



//描画処理
function draw(sum_cell) {
		context=canvas.getContext('2d');
		context.fillStyle='#FFF000';

	//1セルごとに座標を取得し、着色判定
	for(var i=0;i<sum_cell.length;i++){
		var x=i%CELL_SIZE*CELL_SIZE;
		var y=Math.floor(i/CELL_SIZE)*CELL_SIZE;
		if(sum_cell[i]==1){
			context.fillRect(x,y,CELL_SIZE,CELL_SIZE);

		}
	}
	}


//DOMobjを取得する処理
function $(id){
	return document.getElementById(id);
}

</script>
</body>
</html>
.hatena-module:nth-of-type(10) { background: transparent; } .hatena-module:nth-of-type(10) .hatena-module-title{ display: none; } .hatena-module:nth-of-type(10) .hatena-module-body { padding: 0; }