我正在尝试在网页的 Canvas 中编写 Conway Game of Life 应用程序。但是在编写代码后,我无法让单元格出现在我的 Canvas 元素上。你能告诉我哪里做错了吗?
我的猜测是这与按钮的功能有关 - 我编写的功能应该初始化游戏,但它并没有发生。
<!DOCTYPE html>
<html>
<head>
<script>
var CONWAY = (function() {
var my = {};
var Board = function() { //create a game board object
this.cells = {}; //collection object to hold cell coordinates
};
var Cell = function(x, y, alive) { //create a cell object
this.x = x; //the x coordinate for the cell
this.y = y; //the y coordinate for the cell
this.alive = alive; //state to show if the cell is alive or dead
};
Cell.prototype = { //add isAlive method to the cell object
isAlive: function() {
return this.alive; //return cell's state
}
};
Board.prototype = {
addCell: function(cell) { //the method to add a cell to the board
this.cells[getCellRepresentation(cell.x, cell.y)] = cell;
},
getCellAt: function(x,y) { //returns the value of the specified coordinates
return this.cells[getCellRepresentation(x,y)];
},
getAliveNeighbors: function(cell) { //check nearby cells for states according to the rules
var x = cell.x;
var y = cell.y;
var aliveCells = 0;
for(var i = -1; i < 2; i++) { //look for live cells in the vicinity
for(var j = -1; j < 2; j++) {
if(i === 0 && i === j) {
continue;
}
var currentCell = this.getCellAt(x + i, y + j);
if(currentCell && currentCell.isAlive()) {
aliveCells++;
}
}
}
return aliveCells; //return the number of live cells
},
calculateNextState: function(cell) {
var tempCell = new Cell(cell.x, cell.y, cell.alive);
var livingNeighbors = this.getAliveNeighbors(cell);
if(cell.alive) {
if(livingNeighbors === 2 || livingNeighbors === 3) {
tempCell.alive = true;
}
else {
tempCell.alive = false;
}
}
else {
if(livingNeighbors === 3) {
tempCell.alive = true;
}
}
return tempCell;
},
step: function() {
var cells = this.cells;
var tempBoard = {};
for(var c in this.cells) {
var cell = this.cells[c];
var newCell = this.calculateNextState(cell);
tempBoard[c] = newCell;
}
this.cells = tempBoard;
}
};
function getCellPrepresentation (x,y) {
return "x" + x + "y" + y;
}
var CONWAY_GLOB_MAX_X = 99;
var CONWAY_GLOB_MAX_Y = 23;
var randomInit = function(board) {
for (var y = 0; y <= CONWAY_GLOB_MAX_Y; y++) {
for (var x = 0; x <= CONWAY_GLOB_MAX_X; x++) {
board.addCell(new Cell(x, y, (Math.random() > 0.8)));
}
}
};
var draw = function(board, canvas) {
var output = ' ';
for(var y = 0; y <= CONWAY_GLOB_MAX_X; y++) {
for(var x = 0; x <= CONWAY_GLOB_MAX_Y; x++) {
var cell = board.getCellAt(x,y);
output += cell && cell.isAlive() ? 'o' : ' ';
}
output += '\n\
';
}
canvas.html(output);
};
var doConway = function(body) {
var board = new Board(); //create new board
randomInit(board); //initialize board with random dead and alive cells
draw(board, body); //draw the board
return setInterval(function() { //update every 130 ms
board.step();
draw(board, body);
}, 130);
};
my.initConway = function(id, body) {
clearInterval(id);
return doConway(body);
};
my.resetConway = function(id, body) {
body.empty();
clearInterval(id);
};
var conwayRandIntervalId = null;
var conwayBody = getElementbyId('conway');
var resetGame = function() {
this.resetConway(conwayRandIntervalId, conwayBody);
};
var startGame = function() {
conwayRandIntervalId = this.initConway(conwayRandIntervalId, conwayBody);
}
return my;
}());
</script>
<style type="text/css">
div.conway {
overflow: hidden;
font-family: courier;
float: left;
width: 500px;
height: 288px;
background-color: #000;
font-size: 10px;
color: #fff;
}
</style>
</head>
<body>
<div>
<button id='startCW' onclick="startGame();">Random Conway's Game of Life</button> | <button id='resetCW' onclick="resetGame();">Reset</button>
<div class='conway' id='conway'></div>
</div>
</body>
</html>
最佳答案
我有一点时间,所以我冒昧地修复了这个应用程序。
最初的问题是您没有正确公开函数 startGame,按钮无法触发它。我通过你的CONWAY
曝光了通过将其设置在我的对象上。那么你错过了 document
的一部分 document.getElementById
.接下来你试图调用 getCellRepresentation
, 但它应该是 getCellPrepresentation
.
下一个问题与在加载 dom 之前执行脚本有关。有几种方法可以解决这个问题,例如使用 jquery 文档加载功能并将您的逻辑放在那里,但最简单的方法是将您的脚本标签作为 LAST 标签放在您的正文中。当浏览器遍历 html 时,它会构建 dom 元素,然后执行您的代码,这允许您的 document.getElementById
返回正确的元素。在 dom 加载之前执行此操作将始终返回 null。
我改变了你的canvas.html(output)
至 canvas.innerHTML=output
,因为这是对我机器上没有的 jquery 的依赖。任何一种方式都是可以接受的。
最后我清理了你的输出。在您的版本中,输出全部落在一行中,因为您正在做诸如使用空格和\n 之类的事情。因为我们在一个 html block 中,所以我将输出更改为
的和<br />
的。另一种解决方案是使用 <pre>
元素而不是 div,但我还没有测试过这个。
我的帮助可能有点过头了,如果您只是在寻找没有输出的原因,我们深表歉意。如果您有任何问题,请发表评论:-)
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
div.conway {
overflow: hidden;
font-family: courier;
float: left;
width: 500px;
height: 288px;
background-color: #000;
font-size: 10px;
color: #fff;
}
</style>
</head>
<body>
<div>
<button id='startCW' onclick="CONWAY.startGame();">Random Conway's Game of Life</button> | <button id='resetCW' onclick=" CONWAY.resetGame();">Reset</button>
<div class='conway' id='conway'></div>
</div>
<script type="text/javascript">
var CONWAY = (function () {
var my = {};
var Board = function () { //create a game board object
this.cells = {}; //collection object to hold cell coordinates
};
var Cell = function (x, y, alive) { //create a cell object
this.x = x; //the x coordinate for the cell
this.y = y; //the y coordinate for the cell
this.alive = alive; //state to show if the cell is alive or dead
};
Cell.prototype = { //add isAlive method to the cell object
isAlive: function () {
return this.alive; //return cell's state
}
};
Board.prototype = {
addCell: function (cell) { //the method to add a cell to the board
this.cells[getCellPrepresentation(cell.x, cell.y)] = cell;
},
getCellAt: function (x, y) { //returns the value of the specified coordinates
return this.cells[getCellPrepresentation(x, y)];
},
getAliveNeighbors: function (cell) { //check nearby cells for states according to the rules
var x = cell.x;
var y = cell.y;
var aliveCells = 0;
for (var i = -1; i < 2; i++) { //look for live cells in the vicinity
for (var j = -1; j < 2; j++) {
if (i === 0 && i === j) {
continue;
}
var currentCell = this.getCellAt(x + i, y + j);
if (currentCell && currentCell.isAlive()) {
aliveCells++;
}
}
}
return aliveCells; //return the number of live cells
},
calculateNextState: function (cell) {
var tempCell = new Cell(cell.x, cell.y, cell.alive);
var livingNeighbors = this.getAliveNeighbors(cell);
if (cell.alive) {
if (livingNeighbors === 2 || livingNeighbors === 3) {
tempCell.alive = true;
}
else {
tempCell.alive = false;
}
}
else {
if (livingNeighbors === 3) {
tempCell.alive = true;
}
}
return tempCell;
},
step: function () {
var cells = this.cells;
var tempBoard = {};
for (var c in this.cells) {
var cell = this.cells[c];
var newCell = this.calculateNextState(cell);
tempBoard[c] = newCell;
}
this.cells = tempBoard;
}
};
function getCellPrepresentation(x, y) {
return "x" + x + "y" + y;
}
var CONWAY_GLOB_MAX_X = 99;
var CONWAY_GLOB_MAX_Y = 23;
var randomInit = function (board) {
for (var y = 0; y <= CONWAY_GLOB_MAX_Y; y++) {
for (var x = 0; x <= CONWAY_GLOB_MAX_X; x++) {
board.addCell(new Cell(x, y, (Math.random() > 0.8)));
}
}
};
var draw = function (board, canvas) {
var output = ' ';
for (var y = 0; y <= CONWAY_GLOB_MAX_X; y++) {
for (var x = 0; x <= CONWAY_GLOB_MAX_Y; x++) {
var cell = board.getCellAt(x, y);
output += cell && cell.isAlive() ? 'o' : ' ';
}
output += '<br/>';
}
canvas.innerHTML=(output);
};
var doConway = function (body) {
var board = new Board(); //create new board
randomInit(board); //initialize board with random dead and alive cells
draw(board, body); //draw the board
return setInterval(function () { //update every 130 ms
board.step();
draw(board, body);
}, 130);
};
my.initConway = function (id, body) {
clearInterval(id);
return doConway(body);
};
my.resetConway = function (id, body) {
body.empty();
clearInterval(id);
};
var conwayRandIntervalId = null;
var conwayBody = document.getElementById('conway');
my.resetGame = function () {
this.resetConway(conwayRandIntervalId, conwayBody);
};
my.startGame = function () {
conwayRandIntervalId = this.initConway(conwayRandIntervalId, conwayBody);
}
return my;
}());
</script>
</body>
</html>
关于javascript - Conway 生命游戏 - 细胞不会出现在 Canvas 上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24769530/