Мой холст в моем коде отображается только после цикла for.Я после эффекта анимации - PullRequest
1 голос
/ 17 июня 2019

Я изучаю javascript ООП и решил внедрить муравейник Langstons.У меня проблемы с холстом HTML5, хотя.Когда я запускаю это, мои сообщения об отладке в Ant.js всплывают, как и ожидалось, но только после того, как они все сделали, холст появляется в моем браузере (chrome).Затем это выглядит как состояние, которое должно быть в конце цикла.Почему это?Заранее спасибо ..

Вот мой код;

langstonsAnt.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Langstons Ant</title>
<script defer src="antGame.js"></script>
<script src="Ant.js"></script>
<script src="AntWorld.js"></script>
</head>
<body>
<canvas id="antboard" width="700" height="700" style="border: 5px solid black; background-size: 100%;">
    Canvas not supported
</canvas>
</body>

</html>

antGame.js

let c = document.getElementById("antboard");
let ctx = c.getContext("2d");
startGame(ctx);

function startGame(ctx)
{
    for (let x=0; x<100; x++)
    {
        for (let y=0; y<100; y++)
        {
            ctx.fillStyle = "red";
            ctx.fillRect(7 * x, 7 * y, 7, 7);
        }
    }
}

// create antWorld board
let world = new AntWorld(100, ctx);

// create the ant
let ant = new Ant(world.board);

// place the ant on the board
world.setAntPos(ant.getAntX(), ant.getAntY());


// THIS IS THE LOOP I AM REFERRING THAT CALLS THE ALERTS.
for (let i=0; i<16; i++)
{
    ant.moveForward();
    world.setAntPos(ant.getAntX(),ant.getAntY());
    //sleep(100);
}

function sleep(milliseconds) {
    let start = new Date().getTime();
    for (let i=0; i<1e7; i++) {
        if ((new Date().getTime() - start) > milliseconds){
            break;
        }
    }
}

Ant.js

class Ant
{
    constructor(board)
    {
        this.board = board;
        this.antX = 50;
        this.antY = 35;
        this.NORTH = 0;
        this.EAST = 1;
        this.SOUTH = 2;
        this.WEST = 3;
        this.antDirection = this.NORTH;
    }

    getAntX()
    {
        return this.antX;
    }

    getAntY()
    {
        return this.antY;
    }

    moveForward()
    {
        switch (this.antDirection)
        {

            case this.NORTH:
                // change direction and colour the square based on rules
                if (this.board[this.antY][this.antX] === 0) // if sqr is white
                {
                    this.board[this.antY][this.antX] = 1;
                    alert('About to fillRect');
                    ctx.fillStyle = "black";
                    ctx.fillRect(7 * this.antX, 7 * this.antY, 7, 7);
                    this.antDirection = this.WEST;
                } else { // if sqr is black
                    this.board[this.antY][this.antX] = 0;
                    alert('About to fillRect');
                    ctx.fillStyle = "white";
                    ctx.fillRect(7 * this.antX, 7 * this.antY, 7, 7);
                    this.antDirection = this.EAST;
                }
                // move ant forward
                this.antY--;
                break;
            case this.SOUTH:
                // then colour the new square based on rules
                if (this.board[this.antY][this.antX] === 0)
                {
                    this.board[this.antY][this.antX] = 1;
                    alert('About to fillRect');
                    ctx.fillStyle = "black";
                    ctx.fillRect(7 * this.antX, 7 * this.antY, 7, 7);
                    this.antDirection = this.EAST;
                } else {
                    this.board[this.antY][this.antX] = 0;
                    alert('About to fillRect');
                    ctx.fillStyle = "white";
                    ctx.fillRect(7 * this.antX, 7 * this.antY, 7, 7);
                    this.antDirection = this.WEST;
                }
                // move ant forward
                this.antY++;
                break;
            case this.EAST:
                // then colour the new square based on rules
                if (this.board[this.antY][this.antX] === 0)
                {
                    this.board[this.antY][this.antX] = 1;
                    alert('About to fillRect');
                    ctx.fillStyle = "black";
                    ctx.fillRect(7 * this.antX, 7 * this.antY, 7, 7);
                    this.antDirection = this.NORTH;
                } else {
                    this.board[this.antY][this.antX] = 0;
                    alert('About to fillRect');
                    ctx.fillStyle = "white";
                    ctx.fillRect(7 * this.antX, 7 * this.antY, 7, 7);
                    this.antDirection = this.SOUTH;
                }
                // move ant forward
                this.antX++;
                break;
            case this.WEST:
                // then colour the new square based on rules
                if (this.board[this.antY][this.antX] === 0)
                {
                    this.board[this.antY][this.antX] = 1;
                    alert('About to fillRect');
                    ctx.fillStyle = "black";
                    ctx.fillRect(7 * this.antX, 7 * this.antY, 7, 7);
                    this.antDirection = this.SOUTH;
                } else {
                    this.board[this.antY][this.antX] = 0;
                    alert('About to fillRect');
                    ctx.fillStyle = "white";
                    ctx.fillRect(7 * this.antX, 7 * this.antY, 7, 7);
                    this.antDirection = this.NORTH;
                }
                // move ant forward
                this.antX--;
                break;
        }
    }
}

AntWorld.js

class AntWorld
{
    constructor(size)
    {
        this.board = Array(size).fill(0).map(()=>Array(size).fill(0));
    }

    setAntPos(antX, antY)
    {
        this.board[antY][antX] = 1;
        ctx.fillStyle = "black";
        ctx.fillRect(7 * antX, 7 * antY, 7, 7);
    }
}

Ответы [ 2 ]

0 голосов
/ 17 июня 2019

Если вы хотите сделать анимацию на JavaScript в браузере, вы действительно должны использовать requestAnimationFrame и правильно структурировать свой код.

, который сказал, если вы просто хотите взломатьВы можете использовать async / await в вашем цикле.Сначала нам нужна функция, которая будет ждать некоторое время

function sleep(ms = 0) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

Затем нам нужно поместить цикл в функцию async и вызвать sleep с ключевым словом await.

async function loop() {
  for (let i=0; i<16; i++)
  {
      ant.moveForward();
      world.setAntPos(ant.getAntX(),ant.getAntY());
      await sleep(100);  // pause 100 milliseconds
  }
}
loop();

Вот пример

function sleep(ms = 0) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function loop() {
  for (let i=0; i<16; i++)
  {
      console.log(i);
      await sleep(1000);  // pause 1000 milliseconds
  }
}
loop();

Для получения дополнительной информации см .: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await

0 голосов
/ 17 июня 2019

То, что вы делаете (после удаления оповещений и раскомментирования sleep()), это занятый сон . Это означает, что во время сна Javascript постоянно занят. Нет времени делать что-либо еще, например, рендеринг холста, потому что он зацикливается.

Вам нужно использовать системные события для выполнения следующего действия. Обычно это будет нажатие клавиши пользователем или таймером.

Итак, давайте перекодируем этот бит кода, используя таймер:

for (let i=0; i<16; i++)
{
    ant.moveForward();
    world.setAntPos(ant.getAntX(),ant.getAntY());
    sleep(100);
}

С таймером, который станет:

function moveTheAnt()
{
    ant.moveForward();
    world.setAntPos(ant.getAntX(),ant.getAntY());
    stepCount++;
    if (stepCount > 16) clearInterval(stepTimer);
}

let stepCount = 0;
let stepTimer = setInterval(moveTheAnt, 100);

Вы можете увидеть это в действии здесь: JSFiddle

Для получения дополнительной информации о таймере Javascript см .: https://www.w3schools.com/js/js_timing.asp

Для получения информации о событиях в целом см .: https://www.w3schools.com/JS/js_events.asp

Обе ссылки являются лишь примерами, возможно, есть лучшие уроки.

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