LoginSignup
2
2

javascriptでライフゲーム作った

Posted at

ライフゲーム作った

javascript でライフゲーム作りました

ライフゲーム
https://ikuo0.github.io/lifegame-js/

ソースコード
https://github.com/ikuo0/lifegame-js

ライフゲームとは

wiki見ましょう
https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B2%E3%83%BC%E3%83%A0

解説とか

ライフゲームについて今更ここで解説することも無いのでjavascriptでゲームの下地を作成した際の工夫点を書いていきます

以下メインループのソース部分を抜粋します

    self.MainProcess = function() {
        //var g = new MoveTest();
        var g = new LifeGameGame(128, 128, 10);
        var t = performance.now();
        var fpst = t;
        var framen = 0;
        var framerec = 0;
        var gameInput = new GameInput();
        var updatelimit = 0;
        var mainLoop = function() {
            var timestamp = performance.now();
            if((timestamp - fpst) > 1000) {
                fpst = timestamp;
                framerec = framen;
                framen = 0;
            }
            if(timestamp >= updatelimit) {
                updatelimit = timestamp + 15;
                self.deviceToInput(gameInput, self.keyCodes, self.keyEvents);
                self.keyCodes = [];
                self.keyEvents = [];
                //g.main(gameInput);
                g.update();
                framen += 1;
            }
            while(1) {
                var event = app.popEvent();
                if(event === undefined) {
                    break;
                } else {
                    var [eventName, eventData] = event;
                    if(eventName == "change-config") {
                        g = new LifeGameGame(eventData["size"], eventData["size"], eventData["speed"]);
                    }
                }
            }
            setTimeout(mainLoop);
        }
        var drawLoop = function() {
            var canvas = document.getElementById("main_canvas");
            var ctx = canvas.getContext("2d");
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            //Draw(ctx, g.drawData());
            DrawLifeGame(ctx, g.drawData());
            ctx.font = '20px sans-serif';
            ctx.fillText(String(framerec) + "fps", 0, 32);
            requestAnimationFrame(drawLoop);
        }
        mainLoop();
        drawLoop();
    }

処理ループの実装

            if(timestamp >= updatelimit) {
                updatelimit = timestamp + 15;
                /* 省略 */
        setTimeout(mainLoop);

setTimeout(mainLoop); でループをして timestamp >= updatelimit の判定で概ね60fpsにしようとしています、実際には 55fps 程度です、これ以上精度を上げられませんでした
setTimeout でループを作成する事によりCPU使用率を7~10%に抑えられます、while(1) で素直にループを作成した場合はCPU使用率が100%になります、当然whileにしたほうがフレーム精度は上がりますが
今回は1フレームを競うようななにかではないのでCPU使用率低いほうが良いだろうということでこの実装です

描画ループの実装

var drawLoop = function() {
  /* 省略 */
  requestAnimationFrame(drawLoop);
}

requestAnimationFrame(drawLoop); でループを作成しています
requestAnimationFrame はモニタのリフレッシュレート毎に呼び出してくれる関数です
CPU使用率結構上がってしまうので2回に1回くらい呼べばいいかもなーと思いつつそのまま使っています

このように処理と描画を完全に分けて処理しています
他の言語で作成する時は処理ループで処理中は描画しないとか、ロック処理必要かもですね

2
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2