首页 > 解决方案 > 使用 requestFrameAnimation 制作的小游戏(参见 codepen)的循环以用户输入的命令延迟执行

问题描述

https://codepen.io/cornel777/pen/GRZWEMq

嗨,谁能告诉我为什么这段代码会延迟运行?

更具体地说,在第一个PROMPT输入方向之后,红色圆圈不会移动(即使控制台日志写入了正确的值 - 减去/添加的播放器元素的顶部/左侧)。

第一个用户输入的方向值(例如左)在下一个被提示并提交后执行。

因此玩家将始终以一个用户输入的命令延迟移动。

    <!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Escape</title>
  <link rel="stylesheet" type="text/css" href="RPG.css">
</head>
<body>

<h1  id="title">Escape!!!</h1>

  <div class="board">
    <div id="player"></div>
    <div id="exitRound"></div>
    <div id="exitTriang"></div>
    <div id="exitSquare"></div>
  </div>


<button onclick="play()" class="restart">START</button>

<script>
    // var board = document.getElementById("board");
    var player = document.getElementById("player");
    // var exit1 = document.getElementById("exitTriang");
    var exit2 = document.getElementById("exitRound");
    // var exit3 = document.getElementById("exitSquare");
// play();
    function play() {

        confirm('ready?');

        var posT = player.offsetTop;
        var posL = player.offsetLeft;
        var posT1 = exit2.offsetTop;
        var posL1 = exit2.offsetLeft;
        var x = player.offsetParent;


        console.log(posT, posL, posT1, posL1);
        console.log("offsetParent is " + x + "because it has position css property, otherwise it is body");



        while (posT !== posT1 && posL !== posL1) {
            console.log(posT !== posT1 && posL !== posL1);
            var direction = prompt("Enter direction:\n left, right, up, down");


            switch (direction) {
                case 'left':
                    player.style.left = (posL - 50) + 'px';
                    console.log(player.style.left = (posL - 50) + 'px');
                    posL = posL - 50;
                    break;
                case 'right':
                    player.style.left = (posL + 50) + 'px';
                    break;
                case 'up':
                    player.style.top = (posT - 50) + 'px';
                    break;
                case 'down':
                    player.style.top = (posT + 50) + 'px';
                    break;
                default:
                    alert("you need to move!");
                    break;
            }
        }

        if (posT === posT1 && posL === posL1) {
            alert("YOU WIN!!!");
        }
    }



</script>

</body>
</html>

标签: javascriptswitch-statementdelayprompt

解决方案


我猜线程被阻塞了,css 没有立即完成执行。

建议的解决方案是这样的:

https://codepen.io/abozanona/pen/oNxZeLY

    // var board = document.getElementById("board");
    var player = document.getElementById("player");
    // var exit1 = document.getElementById("exitTriang");
    var exit2 = document.getElementById("exitRound");
    // var exit3 = document.getElementById("exitSquare");
    // play();


    function gameLoop() {
        var posT = player.offsetTop;
        var posL = player.offsetLeft;
        var posT1 = exit2.offsetTop;
        var posL1 = exit2.offsetLeft;

        var direction = prompt("Enter direction:\n left, right, up, down");
        switch (direction) {
            case 'left':
                player.style.left = (posL - 50) + 'px';
                console.log(player.style.left = (posL - 50) + 'px');
                setTimeout(gameLoop, 500);
                break;
            case 'right':
                player.style.left = (posL + 50) + 'px';
                setTimeout(gameLoop, 500);
                break;
            case 'up':
                player.style.top = (posT - 50) + 'px';
                setTimeout(gameLoop, 500);
                break;
            case 'down':
                player.style.top = (posT + 50) + 'px';
                setTimeout(gameLoop, 500);
                break;
            default:
                alert("you need to move!");
                setTimeout(gameLoop, 500);
                break;
        }
        if (posT === posT1 && posL === posL1) {
            alert("YOU WIN!!!");
            return; // gets out of a loop
        }
    }

我现在使用setTimeout(gameLoop, 500);给主线程 500 毫秒的时间来将 css 更改应用于 DOM,然后再再次阻塞线程。


推荐阅读