JavaScript значение изменяется, но холст не перерисовывается с обновленными значениями - PullRequest
0 голосов
/ 07 марта 2020

Я пытаюсь реализовать Игру Жизни Джона Конвея в HTML, используя canvas и JavaScript.
. В двумерном массиве я сохраняю положение и состояние ячейки xy (живой или мертвый).
Я избегаю большинство внешних ячеек, чтобы не беспокоиться о граничных условиях.
Используя requestAnimationFrame, я очищаю холст, обновляю ячейки для следующего поколения на основе количества соседей, а затем рисую их.
Я консоль регистрирую состояния ячеек, которые меняются, но по какой-то причине они не обновляются на холсте.
Я уже использовал эту ссылку для справки, но безрезультатно:
Холст: изменение значения X в консоль, но не на холсте

Вот код JavaScript:

var cv = document.querySelector('#cv');
var c = cv.getContext('2d');
var h = cv.height;
var w = cv.width;

//Cell class
function Cell(alive, x, y) {
    this.alive = alive;
    this.x = x;
    this.y = y;

    this.draw = function () {
        //c.beginPath();
        this.x = x;
        this.y = y;
        if(alive == true) {
            c.fillStyle = 'black';
            c.fillRect(this.x, this.y, 10, 10);
        }
        else if(alive == false){
            c.fillStyle = 'white';
            c.fillRect(this.x, this.y, 10, 10);
        }
        //c.stroke();
    }
}


//2d array to contain Cell objects
var cellArray = new Array(100);
for (var i = 0; i < cellArray.length; i++) {
  cellArray[i] = new Array(70);
}
//initial drawing
for(var i = 0; i < cellArray.length; i++) {
    for(var j = 0; j < 100; j++) {
        var b = Math.round(Math.random() - 0.4);
        if(b == 1) {
            cellArray[i][j] = new Cell(true, i * 10, j * 10);
            cellArray[i][j].draw();
        }
        else {
            cellArray[i][j] = new Cell(false, i * 10, j * 10);
            cellArray[i][j].draw();
        }
    }
}

//find number of neghbor cells
function neighborSum(cell, i, j) {
    this.cell = cell;
    this.i = i;
    this.j = j;
    var sum = 0;
    if(cellArray[i - 1][j - 1].alive == true) {
        sum += 1;
    }
    if(cellArray[i][j - 1].alive == true) {
        sum += 1;
    }
    if(cellArray[i - 1][j].alive == true) {
        sum += 1;
    }
    if(cellArray[i + 1][j - 1].alive == true) {
        sum += 1;
    }
    if(cellArray[i - 1][j + 1].alive == true) {
        sum += 1;
    }
    if(cellArray[i + 1][j].alive == true) {
        sum += 1;
    }
    if(cellArray[i][j + 1].alive == true) {
        sum += 1;
    }
    if(cellArray[i + 1][j + 1].alive == true) {
        sum += 1;
    }
    return sum;
}

//animate function
function play() {
    requestAnimationFrame(play);
    c.clearRect(0, 0, w, h);

        //check surrounding neighbor cells
    for(var i = 1; i < cellArray.length - 1; i++) {
        for(var j = 1; j < 70 - 1; j++) {
            if( cellArray[i][j].alive == true &&  (  neighborSum(cellArray[i][j], i, j) > 3 ||   neighborSum(cellArray[i][j], i, j) < 2 )  ) {
                cellArray[i][j].alive = false;
            }
            else if(  cellArray[i][j].alive == true  && ( neighborSum(cellArray[i][j], i, j) == 3 || neighborSum(cellArray[i][j], i, j) == 2 )  ) {
                cellArray[i][j].alive = true;
            }
            else if(cellArray[i][j].alive == false &&  neighborSum(cellArray[i][j], i, j) == 3   ) {
                cellArray[i][j].alive = true;
            }
        }
    }

    //console.log(cellArray)

    //redraw cells alive or dead
    for(var i = 1; i < cellArray.length - 1; i++) {
        for(var j = 1; j < 70 - 1; j++) {
            cellArray[i][j].draw();
        }
    }
}

requestAnimationFrame(play);

Вот JSFiddle: https://jsfiddle.net/ew3046st/1/

1 Ответ

0 голосов
/ 07 марта 2020

Хорошо, я смог решить проблему, удалив функцию draw (), и вместо этого я просто вызвал функцию fillRect () в функции requestAnimationFrame. Также исправлено поведение ячеек, добавив еще один 2d массив того же размера для хранения состояния ячеек для следующего поколения:

...
for(var i = 1; i < cellArray.length - 1; i++) {
        for(var j = 1; j < 70 - 1; j++) {
            //cellArray[i][j].draw();
            c.beginPath();
            //cellArray[i][j].draw();
            if(cellArray[i][j].alive == true) {
                c.fillStyle = 'black';
                c.fillRect(cellArray[i][j].x, cellArray[i][j].y, 10, 10);
            }
            else if(cellArray[i][j].alive == false){
                c.fillStyle = 'white';
                c.fillRect(cellArray[i][j].x, cellArray[i][j].y, 10, 10);
            }
            c.stroke();
        }
    }
...

Вот рабочий jsfiddle: https://jsfiddle.net/e7u19xpq/1/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...