Javascript 动画和递归

标签 javascript animation recursion

我编写了一个 Javascript 程序,它使用隐性技术来解决益智游戏。

也就是说,函数 solvePuzzle() 调用函数 solvePuzzle() 来解决更简单的难题,直到找到解决方案。它改变了棋盘对象中的数据。

我还有一个函数 board.draw() 可以显示拼图的状态

它按照我的预期绘制了初始游戏板,一旦我单击按钮(触发 solvePuzzle() 的执行),它就会按照我的预期再次绘制已解决的游戏板。

但是,我想展示中间的谜题状态。

最初,我在 solvePuzzle() 函数中插入了对 board.draw() 的调用,但这没有执行任何操作。

研究 Javascript 动画让我创建并执行这个函数

function animationLoop(timestamp) {
    // 1 - Clear
    ctx.clearRect(0, 0, c.width, c.height);

    // 2 Draw
    board.draw();
    pieces.draw();

    // call again mainloop after 16.6 ms (60 frames/s)
    requestId = requestAnimationFrame(animationLoop);
}   

requestId = requestAnimationFrame(animationLoop);

我相信这是有效的,因为这是我现在调用 board.draw() 的唯一地方,它显示初始状态,并在我按下求解按钮后切换到显示已求解的状态,但是......仍然没有显示中间状态.

然后我假设问题是解决方案太快了,以至于它发生在帧之间,但通过将这个“延迟”放在solvePuzzle 中来打消这一点

    if (solutionCount%1000 == 0) {
        confirm("Are you sure you wish to continue?");
    };

我现在假设solvePuzzle 必须在animationLoop 进行之前运行完成。

这个假设正确吗?

如果是这样,我该如何解决我的问题?

我想我需要在每个状态下不断结束和恢复我的隐居功能,但无法弄清楚我该如何做到这一点。

注意:我确信动画正常工作的另一个原因是,如果我用类似

的语句从控制台更改棋盘
board.layout[7].available = true;

对显示进行了预期的更改

最佳答案

JavaScript 是单线程的,并且与 UI 更新共享该线程。因此,当一个函数从顶层启动时,浏览器不会执行任何其他操作,直到该函数退出。这包括动画帧 - 只要页面线程空闲并且可以安排动画,动画就会发生,但在代码执行时则不能。

如果你的计算需要时间,你需要将其分成离散的部分,如果你想更新 UI,则需要让浏览器在中间呼吸(通常使用 setTimeout(f, 0),或者在 >requestAnimationFrame 处理程序)。

另一种可能性是使用 Web Workers。它们是一种在单独的线程中启动 JavaScript 的方法。然而,它们根本无法与 DOM 交互,只能通过消息进行通信。因此,您可以在 Web Worker 中启动计算,然后从 Worker 定期向您的主 JS 代码发送消息,以便使其根据结果(临时结果和最终结果)更新 DOM。

感谢 Alexander O'Mara 和 Kaiido 让我涵盖了我忘记的案例。

关于Javascript 动画和递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33772511/

相关文章:

javascript - 使用javascript在字符串中查找顺序

javascript - 如何在 atom 中格式化 React Native 的代码

javascript - Eternicode Bootstrap 日期选择器 : how do you pass options when you are using show event?

javascript - 脚本运行多次

ios - 获取 SKPhysicsBody 以在纹理动画时更新 (Swift)

iOS - 仅针对特定 View 翻转动画

jquery - 为什么我无法在不破坏代码的情况下阻止动画队列堆叠?

arrays - 列出字符串数组中所有元组的算法

algorithm - 递归如何在排列中工作?

c++ - 递归算法的迭代版本较慢