JavaScriptでライフゲームを作ってみた


クリックでパターンを作れます。

JavaScriptを始めてから5時間くらいで作れました。
練習用の課題としてライフゲームの実装はとても適してるのではないでしょうか。
BloggerでJavaScript貼り付ければ動いてくれるのは便利です。

自動セミコロン挿入は驚きましたが、気にせずセミコロンを書けばいいことがわかったので問題ありませんでした。
ブロックスコープじゃないのも戸惑いました。こっちはまだちゃんと理解できてないのではないかと思います。

参考にしたサイト
とほほのJavaScriptリファレンス
JavaScriptの自動セミコロン挿入-本の虫
http://noidgames.web.fc2.com/lifegame.html

一応コードも貼っておきます。

<style type="text/css">
#canvas1 {
 display: block;
 width:320px;
 background-color:black;
}
</style>
<script type="text/javascript">

//明示的にグローバル変数を宣言
var canvas1;
var ctx;
var field = new Array(32); // フィールド情報
var isMove = 0;
for(i=0;i<field.length;i++){
    field[i] = new Array(32);
    for(j=0;j<field[i].length;j++){
        field[i][j] = 0;
    }
}

window.onload = function() {
    canvas1 = document.getElementById('canvas1');
    ctx1 = canvas1.getContext('2d');
    canvas1.addEventListener('click',clickfunc,true);
};
function clickfunc(event) {
    var rect = event.target.getBoundingClientRect();
    var x = Math.floor((event.clientX - rect.left)/10);
    var y = Math.floor((event.clientY - rect.top)/10);
    ctx1.fillStyle = "rgb(0,255,0)";
    ctx1.fillRect(x*10,y*10,10,10);
    field[x][y] = 1;
}
function move(){
    isMove = 1;
    nextFrame();
}
function stop(){
    isMove = 0;
}
function reset(){
    isMove = 0;
    ctx1.clearRect(0, 0, 320, 320); 
    for(i=0;i<field.length;i++){
        for(j=0;j<field[i].length;j++){
            field[i][j] = 0;
        }
    }
}
function nextFrame(){
    var n;
    var tempField = new Array(32);
    if(!isMove){
        return;
    }
    for(i=0;i<tempField.length;i++){
        tempField[i] = new Array(32);
        for(j=0;j<tempField[i].length;j++){
            tempField[i][j] = 0;
        }
    }
    for(i=0;i<field.length;i++){
        for(j=0;j<field[i].length;j++){
            n=0;
            for(k=i-1;k<=i+1;k++){
                for(l=j-1;l<=j+1;l++){
                    if (k==i && l==j){
                        continue;// 自身はカウントしない
                    } 
                    if(0<=k&&k<32&&0<=l&&l<32){
                        if(field[k][l]){
                            n++;
                        }
                    }
                }
            }
            if(field[i][j]&&(n==2||n==3)){
                tempField[i][j] = 1;
            }else if(!field[i][j]&&n==3){
                tempField[i][j] = 1;
            }else{
                tempField[i][j] = 0;
            }
        }
    }
    field = tempField;
    
    draw();
    setTimeout(nextFrame, 1000/5);
}
function draw(){
    ctx1.clearRect(0, 0, 320, 320); 
    for(i=0;i<field.length;i++){
        for(j=0;j<field[i].length;j++){
            if(field[i][j]){
                ctx1.fillStyle = "rgb(0,255,0)";
                ctx1.fillRect(i*10,j*10,10,10);
            }
        }
    }
}
</script>

<canvas id="canvas1" width="320" height="320"> </canvas>
<button onclick="move()" type="button">
Move
</button>
<button onclick="stop()" type="button">
Stop
</button>
<button onclick="reset()" type="button">
  Reset
</button>

コメント

このブログの人気の投稿

2次元配列のコピー::JavaScript

iframeの利点と欠点

Cocos2d-x 3.4でandroid向けにビルドする