Некорректная работа setInterval

255
21 августа 2017, 11:07

Всем привет! Пытаюсь создать игру(кликер). Кликая на настройки(settings), запускается функция, в которую вложены еще несколько функций. Одна из них - setgsOfSpeed. Функция запускается с заданным интервалом (интервал - глобальная переменная changeSpeed). В этой функции при каждом интервале к переменной con прибавляется 1. И далее - изменение положения блока в зависимости от остатка деления con на 2 (т.е блок перемещается на n пикселей влево, а потом вправо). На этом этапе все работает. Необходимо, чтобы при нажатии на - в строчке Speed, от переменной changeSpeed отнималось 300, чтобы интервал вызова функции был чаще. Это почему-то не работает, но эта не вся проблема. Если забыть про мой вопрос, упомянутый ниже и просто зайти в настройки, а далее - нажать на кнопку Back, то на это событие добавлено действие clearInterval, которое должно осуществить прекращение работы функции setgsOfSpeed. Но это не происходит по непонятным мне причинам. При клике на start, запускается функция position, которая запускается с интервалом, опять же равным changeSpeed. Но происходит что-то непонятное: во-первых, не убирается меню, хотя я указал, что при нажатии на start все элементы принимают значение "none" в display; во-вторых, мой блок circle меняет расположение слишком быстро, хотя changeSpeed = 840(если учитывать, что мы не изменили значение Speed в настройках), т.е складывается ощущение, что блок меняет расположение под влиянием двух интервалов, хотя я добавлял событие clearInterval для первого интервала. В чем может быть проблема? Надеюсь, что объяснил более-менее понятно. Заранее благодарен!

window.onload = function () { 
    var start = document.getElementById("start"), // Меню 
        setgs = document.getElementById("setgs"), 
        back = document.getElementById("back"), 
        exit = document.getElementById("exit"); 
    var divSizePlus = document.getElementById("divSizePlus"), // Настройки 
        divSizeMinus = document.getElementById("divSizeMinus"), 
        divSpeedPlus = document.getElementById("divSpeedPlus"), 
        divSpeedMinus = document.getElementById("divSpeedMinus"); 
    var sizePlus = document.getElementById("sizePlus"), // Кнопки в настройках 
        sizeMinus = document.getElementById("sizeMinus"), 
        speedPlus = document.getElementById("speedPlus"), 
        speedMinus = document.getElementById("speedMinus"); 
    var timer; // Таймер для интервала в настройках 
    var timer1; // Таймер для интервала при нажатии на старт 
    var circle = document.getElementById("circle"); // Сам блок (в виде шара) 
    var score = document.getElementById("score"), // Очки 
        points = document.getElementById("points");  
    var size = document.getElementById("size"); // Для показа размера шара 
    var con = 0; // Используется в функции в настройках для изменения положения шара 
    var changeSpeed = 840; // Значение, указывающие с каким интервалом вызывать функцию. 
 
     
    setgs.onclick = function () { // Запуск функции при нажатии на Settings 
        back.style.margin = "90px 0 0 500px"; 
        divSizePlus.style.display = "block"; 
        divSizeMinus.style.display = "block"; 
        divSpeedPlus.style.display = "block"; 
        divSpeedMinus.style.display = "block"; 
        back.style.display = "block"; 
        circle.style.display = "block"; 
        size.style.display = "block"; 
        start.style.display = "none"; 
        setgs.style.display = "none"; 
         
        var plusSize = 80, 
            minusSize = 80, 
            defSize = 80, 
            sumPlus = 0, 
            sumMinus = 0, 
            radius = 50, 
            counter = 5; 
         
        sizePlus.onclick = function () { // Увеличить размер 
            if (defSize > 120) { 
                plusSize.style.cursor = "none"; 
            } 
            plusSize = defSize; 
            sumPlus = plusSize + counter; 
            circle.style.borderRadius = radius + "px"; 
            circle.style.width = sumPlus + "px"; 
            circle.style.height = sumPlus + "px"; 
            plusSize = sumPlus; 
            defSize = plusSize;  
            radius = radius + counter; 
            size.innerHTML = "(" + defSize + ")"; 
        }; 
     
        sizeMinus.onclick = function () { // Уменьшить размер 
            if (defSize < 20) { 
                minusSize.style.cursor = "none"; 
            } 
            minusSize = defSize; 
            sumMinus = minusSize - counter; 
            circle.style.width = sumMinus + "px"; 
            circle.style.height = sumMinus + "px"; 
            minusSize = sumMinus; 
            defSize = minusSize; 
            size.innerHTML = "(" + defSize + ")"; 
        }; 
         
        speedMinus.onclick = function () { // Увеличить скорость ш 
           changeSpeed = changeSpeed - 300; 
             
        };  
         
        function setgsOfSpeed () { // Функция для изменения положения шара в настройках 
            con++; 
            if ( (con%2) === 1 ) { 
                circle.style.left = -330 + "px"; 
            } 
            else if ( (con%2) === 0 ) { 
                circle.style.left = -160 + "px";     
            } 
        } 
        var timer1 = setInterval(setgsOfSpeed, changeSpeed); // Первый интервал  
    } 
     
    back.onclick = function () { // Кнопка back 
        clearInterval(timer1); // Очистка первого интервала 
        divSizePlus.style.display = "none"; 
        divSizeMinus.style.display = "none"; 
        divSpeedPlus.style.display = "none"; 
        divSpeedMinus.style.display = "none"; 
        circle.style.display = "none"; 
        back.style.display = "none"; 
        size.style.display = "none"; 
        start.style.display = "block"; 
        setgs.style.display = "block"; 
    } 
     
    exit.onclick = function () { // Кнопка выхода из игры 
        clearInterval(timer); // Очиска второго таймера (это значит, что игра завершена и запускать функцию больше не нужно) 
        circle.style.left = -150 + "px"; 
        circle.style.top = 43 + "px"; 
        circle.style.backgroundColor = "aqua"; 
        circle.style.display = "none"; 
        exit.style.display = "none"; 
        points.style.display = "none"; 
        score.style.display = "none"; 
        start.style.display = "block"; 
        setgs.style.display = "block"; 
    } 
     
    start.onclick = function () { // Кнопка start для начала игры 
        start.style.display = "none"; 
        setgs.style.display = "none"; 
        circle.style.display = "block"; 
        exit.style.display = "block"; 
        score.style.display = "block"; 
        points.style.display = "block"; 
        var count = 0; 
        circle.onclick = function () { 
            circle.style.backgroundColor = "hsl(" + getRandom(0,360)+",75%,50%)";  
            count++; 
            score.innerHTML = count; 
        }  
     
        function position () { // Функция для изменения положения шара во время игры 
            var x = window.innerWidth,  
                y = window.innerHeight; 
            x = x - 390; 
            y = y - 100; 
                circle.style.left = getRandom(1, x - 200) + "px"; 
                circle.style.top = getRandom(1, y - 200) + "px"; 
        } 
        timer = setInterval(position, 840); // Второй интервал 
         
        function getRandom(min, max) { 
            return Math.floor(Math.random() * (max - min + 1)) + min; 
        } 
    }      
}
div { 
    position: absolute; 
    margin: 230px 0 0 600px;  
    cursor: pointer; 
} 
 
/* Текст в меню */ 
span {  
    position: absolute; 
    left: 35px; 
    top: 4px; 
    cursor: default; 
} 
 
body { 
    background-image: url(images/fon.jpg); 
    font-family: Arial Black; 
    color: bisque; 
    font-size: 25px; 
} 
 
#circle { 
    left: -160px; 
    top: 53px; 
    width: 80px; 
    height: 80px; 
    background-color: aqua; 
    border-radius: 50px; 
    display: none; 
    cursor: default; 
} 
 
/* меню */ 
#start { 
    top: 10px; 
} 
 
#setgs { 
    top: 30px; 
    padding-top: 25px;   
} 
 
#back { 
    top: 280px; 
    left: 108px; 
    display: none; 
} 
 
#exit { 
    display: none; 
    top: -218px; 
    left: 696px; 
} 
 
#points { 
    left: 8px; 
    top: 10px; 
    display: none; 
} 
 
#score { 
    margin-top: 35px; 
    display: none; 
} 
 
/* блоки с кнопками настроек */ 
#divSizePlus { 
    top: 50px; 
    left: 70px; 
    display: none; 
} 
 
#divSizeMinus { 
    top: 50px; 
    display: none; 
} 
 
#divSpeedPlus { 
    left: 70px; 
    top: 90px; 
    display: none; 
} 
 
#divSpeedMinus { 
    top: 90px; 
    display: none; 
}  
 
/* кнопки + - */ 
input { 
    background-color: burlywood; 
    border: 1px solid burlywood; 
    width: 26px; 
    height: 25px; 
    cursor: pointer; 
} 
 
#size { 
    position: absolute; 
    top: 275px; 
    left: 800px; 
    font-size: 16px; 
    display: none; 
}
<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <meta charset="UTF-8"> 
    <title>Clicker</title> 
    <link href="Test.css" rel="stylesheet" type="text/css" /> 
</head> 
<body> 
 
     
    
    <div id="start">Start</div> 
    <div id="setgs">Settings</div> 
    <div id="back">Back</div> 
    <div id="divSizePlus"><input type="button" value="+" id="sizePlus"><span>Size</span></div> 
    <div id="divSizeMinus"><input type="button" value="-" id="sizeMinus"></div> 
    <div id="divSpeedPlus"><input type="button" value="+" id="speedPlus"><span>Speed</span></div> 
    <div id="divSpeedMinus"><input type="button" value="-" id="speedMinus"></div>  
    <div id="circle"></div> 
    <div id="exit">Exit</div> 
    <span id="points">Очки: </span> <p id="score"></p>  
    <p id="size"></p> 
<script src="Test.js"></script> 
</body> 
</html>

Answer 1

Уберите var из строки

var timer1 = setInterval(setgsOfSpeed, ...

чтобы использовать переменную timer1, декларированную выше.

Частоту запущенного интервала изменить нельзя. Таймер надо очистить и перезапустить с новым значением:

speedMinus.onclick = function () { // Увеличить скорость ш
  changeSpeed = changeSpeed - 300;
  clearInterval(timer1);
  timer1 = setInterval(setgsOfSpeed, changeSpeed);
}; 

Другой вариант - использовать цепочку вызовов setTimeout.

READ ALSO
Вырезать url адрес изображения

Вырезать url адрес изображения

Подскажите регулярку, чтоб вырезать из строки url("/images/imagepng"); ссылку на изображение

244
Firebase. Добавление своих данных

Firebase. Добавление своих данных

Здравствуйте, ребятаУ меня такой вопрос

340
JS AJAX - как узнать, в чем моя ошибка? Возвращает SyntaxError: Unexpected end of JSON input

JS AJAX - как узнать, в чем моя ошибка? Возвращает SyntaxError: Unexpected end of JSON input

Вот код https://jsfiddlenet/f9e0khoo/ Здесь только JS, потому что все равно без БД работать не будет

298
javascript/jquery decode bbcodes to textarea

javascript/jquery decode bbcodes to textarea

есть функция перевода bbcoda в html сущности (php)

236