Javascript простая бесконечная игра, setTimeout проблемы

Я новичок в JavaScript и в программировании в целом, поэтому не думаю, что я знаю много.

Я создаю простую html5 javascript игру, в которой машины на шоссе приближаются к вам (представленные прямоугольниками холста). Я создаю транспортное средство, порождающее и движущееся в данный момент. Моя цель - чтобы машины появлялись и падали с постоянным интервалом между ними, независимо от того, с какой скоростью они движутся.

То, что у меня есть, работает, за исключением случаев, когда происходит какое-либо отставание и когда переменная скорости установлена ​​на число около четырех и ниже. Я провел некоторое исследование, и я считаю, что это потому, что setTimeout не учитывает отставание. Поскольку я новичок, я не знаю многих функций, я понятия не имею, как это исправить, и я не могу найти решение в Интернете.

Вы можете увидеть рабочую демонстрацию моего кода здесь - возиться с открытием вкладок и другими процессами, вызывающими отставание, и вы можете попробовать установить переменную скорости в число ниже 5, и вы увидите, откуда я иду. Любая помощь приветствуется.

<!DOCTYPE html>
<html>
<body>
<canvas id="ctx" width="480" height="320" style="border:1px solid #000000;"></canvas>
<script>
        var ctx = document.getElementById("ctx").getContext("2d");

            function setIntervalX(callback, delay, repetitions) {
                var x = 0;
                var intervalID = window.setInterval(function () {
                    callback();
                    if (++x === repetitions) {
                       window.clearInterval(intervalID);
                   }
                }, delay);
            }

            var speed = 50


            function game() {
                var yAxis
                var selectType = Math.floor((Math.random()*6)+1)
                switch (selectType){
                    case 1: //semi
                    case 2:
                        yAxis = -80
                        var lane = Math.floor((Math.random()*3)+1)
                            switch (lane)
                                {
                                    case 1: //left lane
                                        setIntervalX(function () {
                                        ctx.fillStyle = "white";
                                        ctx.fillRect(200,yAxis,15,80);
                                        yAxis = yAxis + 2
                                        ctx.fillStyle = "black";
                                        ctx.fillRect(200,yAxis,15,80);
                                        }, speed, 400);
                                    break;
                                    case 2: //middle lane
                                        setIntervalX(function () {
                                        ctx.fillStyle = "white";
                                        ctx.fillRect(230,yAxis,15,80);
                                        yAxis = yAxis + 2
                                        ctx.fillStyle = "black";
                                        ctx.fillRect(230,yAxis,15,80);
                                        }, speed, 400);
                                    break;
                                    case 3: //right lane
                                        setIntervalX(function () {
                                        ctx.fillStyle = "white";
                                        ctx.fillRect(260,yAxis,15,80);
                                        yAxis = yAxis + 2
                                        ctx.fillStyle = "black";
                                        ctx.fillRect(260,yAxis,15,80);
                                        }, speed, 400);
                                    break;
                                }
                        setTimeout(function() {game()}, speed * 80) 
                    break;      
                    case 3: //bike
                        yAxis = -10
                        var lane = Math.floor((Math.random()*3)+1)
                            switch (lane)
                                {
                                    case 1: //left lane
                                        setIntervalX(function () {
                                        ctx.fillStyle = "white";
                                        ctx.fillRect(200,yAxis,10,10);
                                        yAxis = yAxis + 2
                                        ctx.fillStyle = "black";
                                        ctx.fillRect(200,yAxis,10,10);
                                        }, speed, 400);
                                    break;
                                    case 2: //middle lane
                                        setIntervalX(function () {
                                        ctx.fillStyle = "white";
                                        ctx.fillRect(230,yAxis,10,10);
                                        yAxis = yAxis + 2
                                        ctx.fillStyle = "black";
                                        ctx.fillRect(230,yAxis,10,10);
                                        }, speed, 400);
                                    break;
                                    case 3: //right lane
                                        setIntervalX(function () {
                                        ctx.fillStyle = "white";
                                        ctx.fillRect(260,yAxis,10,10);
                                        yAxis = yAxis + 2
                                        ctx.fillStyle = "black";
                                        ctx.fillRect(260,yAxis,10,10);
                                        }, speed, 400);
                                    break;
                                }
                        setTimeout(function() {game()}, speed * 45)     
                    break;  
                    case 4: //car
                    case 5:
                    case 6:
                        yAxis = -20
                        var lane = Math.floor((Math.random()*3)+1)
                        switch (lane)
                                {
                                    case 1: //left lane
                                        setIntervalX(function () {
                                        ctx.fillStyle = "white";
                                        ctx.fillRect(200,yAxis,10,20);
                                        yAxis = yAxis + 2
                                        ctx.fillStyle = "black";
                                        ctx.fillRect(200,yAxis,10,20);
                                        }, speed, 400);
                                    break;
                                    case 2: //middle lane
                                        setIntervalX(function () {
                                        ctx.fillStyle = "white";
                                        ctx.fillRect(230,yAxis,10,20);
                                        yAxis = yAxis + 2
                                        ctx.fillStyle = "black";
                                        ctx.fillRect(230,yAxis,10,20);
                                        }, speed, 400);
                                    break;
                                    case 3: //right lane
                                        setIntervalX(function () {
                                        ctx.fillStyle = "white";
                                        ctx.fillRect(260,yAxis,10,20);
                                        yAxis = yAxis + 2
                                        ctx.fillStyle = "black";
                                        ctx.fillRect(260,yAxis,10,20);
                                        }, speed, 400);
                                    break;
                                }
                        setTimeout(function() {game()}, speed * 50)         
                    break;}
                }           
            game()

    </script>

    </body>
    </html>

1 ответ

У вас должен быть только 1 основной setInterval, который обновляет все.
Лаг не должен быть проблемой, особенно с проектом такого размера.

Другие вопросы по тегам