ライフゲーム作った
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回くらい呼べばいいかもなーと思いつつそのまま使っています
このように処理と描画を完全に分けて処理しています
他の言語で作成する時は処理ループで処理中は描画しないとか、ロック処理必要かもですね