【问题标题】:While loop breaking html canvas game虽然循环破坏html画布游戏
【发布时间】:2021-06-16 09:17:25
【问题描述】:

所以我正在尝试使用 html canvas 和 js 制作游戏,并且我在角色/项目中生成,但有时它们会聚集在一起,所以我写了一点 while 循环来不断重新生成它们直到它们之间有一定的差距。但是,每当我插入 while 循环时,游戏/浏览器就会冻结/崩溃。我做错了吗?

我的代码:

let mx = Math.floor(Math.random() * (Math.floor(1536) - Math.ceil(512)) + Math.ceil(512));
let m = new Image;
m.src = "./Mushroom.png";

let bx = Math.floor(Math.random() * (Math.floor(3072) - Math.ceil(512)) + Math.ceil(512));
let b = new Image;
b.src = "./Bee.png";

let cx = Math.floor(Math.random() * (Math.floor(4608) - Math.ceil(512)) + Math.ceil(512));
let c = new Image;
c.src = "./Coin.png";

while (true) {
  if (mx - bx < 128 || mx - cx < 128 || bx - mx < 128 || bx - cx < 128 || cx - mx < 128 || cx - bx < 128) {
    mx = Math.floor(Math.random() * (Math.floor(1536) - Math.ceil(512)) + Math.ceil(512));
    bx = Math.floor(Math.random() * (Math.floor(3072) - Math.ceil(512)) + Math.ceil(512));
    cx = Math.floor(Math.random() * (Math.floor(4608) - Math.ceil(512)) + Math.ceil(512));
  } else {
    break;
  };
};

【问题讨论】:

  • 在该循环运行时不会发生其他任何事情,因此如果需要数百万次迭代才能到达 else 子句并跳出循环,它的行为将与您描述的差不多。 (我还没有完成重要的数学运算来弄清楚达到所有这些条件的几率。)
  • Math.floor(1536)Math.ceil(512) 不要做任何事情,你可以写 1536512
  • @RobinZigmond - 按照目前的写法,几率正好是 0。看我的回答。
  • @Vilx- - 谢谢,我现在明白了(在发表评论之前我没有非常仔细地分析if 条件,因为它看起来太像工作了!但现在我看到它确实很明显.)

标签: javascript html canvas html5-canvas


【解决方案1】:

您创建了一个永不中断的无限循环,因为 if 条件始终为真(请参阅 Vilx 的答案)。

while (true) {
  if (true)
    ...
  } else {
    break;
  };
}

这会导致浏览器冻结。

一般来说:创建一个确保距离的函数,并在您的项目/角色每次移动后调用它。 确保不要在无限循环中计算你的物品/角色的移动,而是使用setInterval 来调用a) 计算移动和b) 确保你的物品分离的函数。

示例(这仍然在做一些奇怪的事情,但至少可以正常工作) - 不知道您的最终目标是什么。我还更正了其他一些小错误。享受吧!

<html>
<head>
<script type="text/javascript" type="text/javascript">   
function nextMove() {
let mx = Math.floor(Math.random() * (Math.floor(1536) - Math.ceil(512)) + Math.ceil(512));
let m = new Image();
m.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABySURBVDhP7ZFLDsAgCES9/7V6MDpkUBFJ1HbRTV9i5DPPjUUyyoQtRuKU0WuCcwtVhj7VPMHvzdIk3rdq0yTN1+vIJPTfyQ9MouYvH6Dmd/+Mc+rTVIsX2PSbCXoFlr43wdAArNMnOLdQJfaEUY8tPCI3hStcGseO1cgAAAAASUVORK5CYII=";

let bx = Math.floor(Math.random() * (Math.floor(3072) - Math.ceil(512)) + Math.ceil(512));
let b = new Image();
b.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABySURBVDhP7ZFLDsAgCES9/7V6MDpkUBFJ1HbRTV9i5DPPjUUyyoQtRuKU0WuCcwtVhj7VPMHvzdIk3rdq0yTN1+vIJPTfyQ9MouYvH6Dmd/+Mc+rTVIsX2PSbCXoFlr43wdAArNMnOLdQJfaEUY8tPCI3hStcGseO1cgAAAAASUVORK5CYII=";

let cx = Math.floor(Math.random() * (Math.floor(4608) - Math.ceil(512)) + Math.ceil(512));
let c = new Image();
c.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABySURBVDhP7ZFLDsAgCES9/7V6MDpkUBFJ1HbRTV9i5DPPjUUyyoQtRuKU0WuCcwtVhj7VPMHvzdIk3rdq0yTN1+vIJPTfyQ9MouYvH6Dmd/+Mc+rTVIsX2PSbCXoFlr43wdAArNMnOLdQJfaEUY8tPCI3hStcGseO1cgAAAAASUVORK5CYII=";

  if (mx - bx < 128 || mx - cx < 128 || bx - mx < 128 || bx - cx < 128 || cx - mx < 128 || cx - bx < 128) {
    mx = Math.floor(Math.random() * (Math.floor(1536) - Math.ceil(512)) + Math.ceil(512));
    bx = Math.floor(Math.random() * (Math.floor(3072) - Math.ceil(512)) + Math.ceil(512));
    cx = Math.floor(Math.random() * (Math.floor(4608) - Math.ceil(512)) + Math.ceil(512));
  }

let myCanvas = document.getElementById('myCanvas');
myCanvas.appendChild(m); 
myCanvas.appendChild(b); 
myCanvas.appendChild(c); 

m.style.marginLeft = mx;
m.style.martinTop = 100;
b.style.marginLeft = bx;
b.style.martinTop = 100;
c.style.marginLeft = cx;
c.style.martinTop = 100;
}

var myIntervalTimer = setInterval(nextMove, 100); // call every 100 milliseconds
</script>
<body id='myCanvas'>
</body>
</html>

【讨论】:

  • 这不是这里的问题。有一个break 语句在正常情况下会在几次迭代后停止循环。不幸的是,if 语句中的条件是错误的,并且永远不会达到break
  • @Vilx:我同意。我会更新我的答案 - 谢谢!
【解决方案2】:

循环将是无限的,因为它永远不会到达break。那是因为您的 if 语句将始终采用第一个分支。考虑:

if ( a-b < 128 || b-a < 128 ) {
    console.log("yay");
}

ab 中的值无关紧要,条件始终为真。

你想要的是:

if ( Math.abs(a-b) < 128 ) {
    console.log("yay");
}

【讨论】:

  • 非常感谢。这对我帮助很大!
猜你喜欢
  • 1970-01-01
  • 2021-12-14
  • 2018-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多