javascript - Conway 生命游戏 - 细胞不会出现在 Canvas 上

标签 javascript html css

我正在尝试在网页的 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 中,所以我将输出更改为 &nbsp;的和<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' : '&nbsp;';
                }
                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/

相关文章:

javascript - jQuery 设置对象中元素的值

JavaScript 函数无法从 HTML 文本区域检索字符串

Javascript 提交页面上的所有表单

javascript - 如何访问嵌套数组内对象的属性?

javascript - 如何使用 url 中的 "#q"重定向 "?q"

php - 投资组合类别 - 如何更改它们在投资组合页面(WordPress 网站)上的显示顺序

css - html5 流畅的视频解决方案

html - Internet Explorer 站点兼容性

html - 如何让 div 向下延伸到固定的页脚

php - 如果 MSSQL 表列为 NULL,如果语句不起作用,则使用 PHP 使用 JS 更改 CSS 样式