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

    var direction=true; //true=right false =left
    var active=true;     //if true run the cycle,false stops the cycle
    function startSnow() {

var _snowflakes = new Array(30);    
var wid=50;                       //distance from a snowflake to another
var counterX;                     //var for editing the x position
var counterY;                     //var for editing the y position
for (var i=0; i< 30; i++)         //cycle that initializes snowflakes
{
    _snowflakes[i] = document.createElement("img");   
    _snowflakes[i].setAttribute("src","snowflake.png"); // setting the image
    _snowflakes[i].setAttribute("class", "snowflake"); //setting the css style
    _snowflakes[i].style.visibility ="inherit";       //when the function is running snowflakes have to be visible, when it finishes they have to be invisible
    _snowflakes[i].style.right = (wid*i)+"px";        //set the distance from the left margin
    _snowflakes[i].style.top = "30px";           // set the distance from the top
    document.getElementById("background").appendChild(_snowflakes[i]);
}
while(active)
{
        move();
}
function move()  //function that moves the snowflake
        {
            for(;;)
        {
            if(counterY>=600)   //when the snowflake reaches 600px from the top the function has to stop and hide snowflakes
            {
                for(var i=0;i<30;i++)
                    _snowflakes[i].style.visibility = "hidden";
                active=false;
                break;
            }                
             else
            {
                if ((counterY%50)==0)
                    {
                        direction=!direction   //every 50 Y pixels the snoflake change direction
                    }
                counterY++;
                for(var i=0;i<30;i++)
                    {
                        _snowflakes[i].style.top = counterY+"px";       //Y movement     
                        if (direction==true)
                            {
                                _snowflakes[i].style.right = (_snowflakes[i].offsetLeft+counterX) + "px";      //x right movement
                                counterX++;
                            }
                        else
                            {
                                _snowflakes[i].style.right = (_snowflakes[i].offsetLeft+counterX) + "px";      //x left movement
                                counterX--;
                            }
                    }
            }
        }
    }

}

0
Mattia 27 Окт 2019 в 21:53

1 ответ

Лучший ответ

Действительно, ваш код попадает в бесконечный цикл, потому что ваша переменная counterY не инициализирована и поэтому имеет значение undefined. Добавление единицы к undefined дает NaN, и поэтому вы никогда не дойдете до этого оператора break.

Но что еще более важно, вам нужен другой подход, потому что даже если вы исправите это, вы никогда не увидите анимации. Чтобы действительно увидеть анимацию, вам нужно дать браузеру время обновить отображение. Так что о циклах while и for(;;) не может быть и речи.

Вместо этого вызовите move один раз, а внутри этой функции в блоке else вызовите requestAnimationFrame(move). Это даст браузеру время на перерисовку до того, как move будет называться выигрышем. Удалите петлю for(;;) и удалите break.

Также есть логическая ошибка в том, как вы двигаетесь по горизонтали. Когда вы читаете текущий offsetLeft, нет смысла увеличивать counterX, так как это приведет к увеличению (относительных) скачков вправо (или влево). Вместо этого вы должны просто добавить (или вычесть) 1 к offsetLeft - вы можете избавиться от counterX. Кроме того, не назначайте это для style.right, а для style.left.

Итак, все вместе (см. Комментарии, где есть изменения):

var direction=true;
var active=true;

function startSnow() {    
    var _snowflakes = new Array(30);    
    var wid=50;
    // var counterX = 0; -- not used.
    var counterY = 0; // Need to initialise!
    for (var i=0; i< 30; i++) {
        _snowflakes[i] = document.createElement("img");   
        _snowflakes[i].setAttribute("src", "snowflake.png");
        _snowflakes[i].setAttribute("alt", "❄"); // added for when image not found
        _snowflakes[i].setAttribute("class", "snowflake");
        _snowflakes[i].style.visibility = "inherit";
        _snowflakes[i].style.left = (wid*i)+"px"; // assign to style.left
        _snowflakes[i].style.top = "30px";
        document.getElementById("background").appendChild(_snowflakes[i]);
    }

    // No while loop. Just call move    
    move();
    
    function move() {
        //No for (;;) loop
        if (counterY>=600) {
            for (var i=0;i<30;i++) {
                _snowflakes[i].style.visibility = "hidden"; // you forgot the underscore
            }
            active=false;
            // No break -- function will just return
        } else {
            if ((counterY%50)==0) {
                direction=!direction
            }
            counterY++;
            for (var i=0;i<30;i++) {
                _snowflakes[i].style.top = counterY+"px";
                if (direction==true) {
                    // assign to style.left, 
                    _snowflakes[i].style.left = (_snowflakes[i].offsetLeft+1) + "px"; // add 1
                } else {
                    _snowflakes[i].style.left = (_snowflakes[i].offsetLeft-1) + "px"; // sub 1
                }
            }
            requestAnimationFrame(move); // schedule next run of this function
        }
    }
}
 
startSnow(); // Need to start it!
#background { width: 800px; height: 800px }
.snowflake { position: absolute; font-size: 40px }
<div id="background">
</div>
1
trincot 27 Окт 2019 в 22:57