我正在学习javascript OOP,因此决定实施Langstons蚂蚁。我在使用html5画布时遇到了麻烦。当我运行此命令时,Ant.js中的调试警报会按预期方式弹出,但只有在完成这些操作后,画布才会出现在我的浏览器(chrome)中。然后看起来它应该处于循环结束的状态。 为什么是这样? 在此先感谢。
这是我的代码;
langstonsAnt.html
details {
border-bottom: 1px solid #3C3C3B;
max-width: 80%;
}
details summary {
outline: none;
font-weight: 600;
padding: 10px 0px;
cursor: pointer;
}
details summary::-webkit-details-marker {
background: url(https://image.flaticon.com/icons/svg/3/3907.svg) center no-repeat;
color: transparent;
width: 30px;
/* known value*/
height: 20px;
float: right;
}
details[open] summary::-webkit-details-marker {
background: url(https://image.flaticon.com/icons/svg/3/3581.svg) center no-repeat;
color: transparent;
width: 30px;
height: 20px;
float: right;
}
summary+* {
padding-right: 30px;
/* known value */
}
antGame.js
<details>
<summary>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor. Lorem ipsum dolor sit amet </summary>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation</p>
</details>
Ant.js
<!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>
AntWorld.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;
}
}
}
答案 0 :(得分:0)
您所做的(在删除警报并取消注释sleep()
之后)是busy 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
这两个链接只是示例,可能会有更好的教程。
答案 1 :(得分:0)
如果您想在浏览器中使用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