HTML5 で導入された要素 Canvas には自由に図形を描画でき、JavaScript と組み合わせることでリアルタイムに書き換えることができます。
そこで練習も兼ねて HTML5 + JavaScript でシンプルなライフゲームを作ってみました。
・html 部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <! DOCTYPE html> < html > < head > < title >Game of Life</ title > < meta charset = "utf-8" > < script src = "lifegame.js" ></ script > </ head > < body > < div style = "margin: 1em 0;" > < form > < input type = "button" value = "Random" id = "buttonRandom" > < input type = "button" value = "Start" id = "buttonStart" > < input type = "button" value = "Reset" id = "buttonReset" > </ form > </ div > < canvas id = "lifegame" width = "320" height = "320" ></ canvas > </ body > </ html > |
・スクリプト部分(lifegame.js)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | var canvas; var ctx; var cellSize = 8; // セル1マスのサイズ var cols; var rows; var cells = new Array(); var buttonStart; var buttonRandom; var buttonReset; var timer1; var running = false ; window.onload = function () { canvas = document.getElementById( 'lifegame' ); ctx = canvas.getContext( '2d' ); cols = Math.floor(canvas.width / cellSize); rows = Math.floor(canvas.height / cellSize); initCells(); buttonStart = document.getElementById( 'buttonStart' ); buttonRandom = document.getElementById( 'buttonRandom' ); buttonReset = document.getElementById( 'buttonReset' ); buttonStart.addEventListener( 'click' , onStart, false ); buttonRandom.addEventListener( 'click' , randomCells, false ); buttonReset.addEventListener( 'click' , initCells, false ); canvas.addEventListener( 'click' , canvasClick, false ); }; // 開始 function onStart(){ if (running){ clearInterval(timer1); buttonStart.value = "Start" ; running = false ; } else { nextGeneration(); timer1 = setInterval( "nextGeneration()" , 100); buttonStart.value = "Stop" ; running = true ; } } // 初期化 function initCells(){ ctx.fillStyle = 'rgb(60, 60, 60)' ; ctx.fillRect(0,0, canvas.width, canvas.height); for (col=0;col<cols;col++){ cells[col] = new Array(); for (row=0;row<rows;row++){ cells[col][row] = 0; } } redraw(); } // ランダムに埋める function randomCells(){ for (col=0;col<cols;col++){ cells[col] = new Array(); for (row=0;row<rows;row++){ cells[col][row] = Math.round( Math.random()); } } redraw(); } // 全体を再描画 function redraw(){ for (col=0;col<cols;col++){ for (row=0;row<rows;row++){ drawCell(col, row); } } } // セルを描画 function drawCell(x, y){ var value = cells[x][y]; var style = value ? "rgb(156, 255,0)" : "rgb(40,40,40)" ; ctx.fillStyle = style; ctx.fillRect(x * cellSize, y * cellSize, cellSize - 1, cellSize - 1); } // 世代を進行させる function nextGeneration(){ var tmpCells = new Array(); for (col=0;col<cols;col++){ tmpCells[col] = new Array(); for (row=0;row<rows;row++){ var count = countAround(col, row); if (cells[col][row]){ if (count == 2 || count == 3){ tmpCells[col][row] = 1; } else { tmpCells[col][row] = 0; } } else { if (count == 3){ tmpCells[col][row] = 1; } else { tmpCells[col][row] = 0; } } } } cells = tmpCells; redraw(); } // 周囲の生存セルを数える function countAround(x, y){ var count = 0; for (i=-1;i<=1;i++){ for (j=-1;j<=1;j++){ if ( (i != 0 || j != 0) && x + i >= 0 && x + i < cols && y + j >= 0 && y + j < rows ) { count += cells[x + i][y + j]; } } } return count; } // Canvasクリック function canvasClick(e){ var x = e.clientX - canvas.offsetLeft; var y = e.clientY - canvas.offsetTop; var col = Math.floor(x / cellSize); var row = Math.floor(y / cellSize); cells[col][row] = !cells[col][row]; drawCell(col, row); } |
ランダムボタンでランダムにセルを埋めるかマウスクリックでセルの ON/OFF を設定してスタートボタンで開始します。
セルの周囲に2~3の生存セルが隣接している場合生き残り、過疎(1以下)や過密(4以上)の場合消滅します。
死んでいるセルの周囲にちょうど3つの生存セルが隣接している場合生きているセルが発生します。
Similar Posts:
- [HTML5+JS+Canvas, PHP]アナログ時計の作り方
- [JS]Javascriptを使ったタイピングゲーム
- [PHP]ライフゲームを作る
- [PHP]マスク画像で写真を好きな形に切り抜く(クリッピングマスク)
- [PHP]GDで図形を描画する際のジャギーを軽減する(アンチエイリアス)
- [JS]画像ファイルアップロード前にプレビューを表示する
- CSS3を使ったアニメーションの作り方
- [JS]アニメーション付きで要素の上下を入れ替える