Запускать и останавливать один и тот же интервал несколько раз - PullRequest
1 голос
/ 10 ноября 2019

Я впервые испытываю движения игровых персонажей. Я успешно сделал кнопку, которая позволяет персонажу двигаться, когда кнопка нажата, и останавливается, когда кнопка отпущена. Моя проблема в том, что это работает только один раз. Если я нажму кнопку еще раз, персонаж больше не будет двигаться вперед. Я проверил консоль на наличие ошибок, но их не было. Вот мой код:

var sonic = document.getElementById('sonic');
var left = 0
var forward;
var add;
sonic.style.position = "absolute";

function move() {
  forward = setInterval(forward, 10);
  add = setInterval(add, 10);
}

function add() {
  left = left + 10;
}

function forward() {
  sonic.style.left = left;
}

function stop() {
  clearInterval(forward);
  clearInterval(add);
}
<button onmousedown="move()" onmouseup="stop()">Move Forward</button>
<br>
<br>
<img width="150px" id="sonic" src="https://www.sccpre.cat/mypng/full/338-3383227_sonic-running-png-sonic-1-sonic-sprite.png" />

Я надеюсь, что персонаж сможет двигаться, когда пользователь удерживает кнопку, а не один раз.

Ответы [ 2 ]

1 голос
/ 10 ноября 2019
  • Вместо того, чтобы возиться с несколькими setIntervals, используйте один window.requestAnimationFrame().
  • Кнопка On (или даже клавиша) манипулирует объектом keys, чтобы отслеживать, какая клавиша нажата
  • Внутри функции keysController() преобразуйте нажатую клавишу (если она существует) в *Преобразование 1009 * (позиция) по оси x (и позже даже по оси y).
  • Внутри функции move() напишите код, который перемещает ваш элемент. Предпочтительно использовать GPU-ускоренное свойство CSS transform.
  • Внутри цикла engine просто вызовите все ваши функции

const EL = sel => document.querySelector(sel);

const sonic = EL('#sonic');
const left  = EL('#left');
const right = EL('#right');

const keys = {}; // you have buttons, but let's call it keys
const pos  = {x: 0, y: 0} // one day you could control the y axis too

function move() {
  sonic.style.transform = `translate(${pos.x}px, ${pos.y}px)`;
}

function keysController () { // convert pressed keys to position
  if (keys.right) pos.x += 10;
  if (keys.left)  pos.x -= 10;
}

(function engine () {
  keysController();
  move();
  requestAnimationFrame(engine)
}());

left.addEventListener('mousedown',  () => keys.left = true );
left.addEventListener('mouseup',    () => delete keys.left );
right.addEventListener('mousedown', () => keys.right = true );
right.addEventListener('mouseup',   () => delete keys.right );
#sonic {
  width: 150px;
  position: absolute;
}
<button id="left">&larr;</button>
<button id="right">&rarr;</button>
<br>
<br>
<img id="sonic" src="https://imgur.com/mYRJad0.png" />
0 голосов
/ 10 ноября 2019

Первая проблема - это путаница имен переменных. У вас есть то же имя для индекса интервала, что и для функции - так что это путается. Видите, я немного дифференцировался ниже, и теперь он движется вперед каждый раз, когда вы нажимаете кнопку:

<button onmousedown="move()" onmouseup="stop()">Move Forward</button>
<br>
<br>
<img width="150px" id="sonic" src="https://www.sccpre.cat/mypng/full/338-3383227_sonic-running-png-sonic-1-sonic-sprite.png" />
<script>
var sonic = document.getElementById('sonic');
var left = 0
var forwardInt;
var addInt;
sonic.style.position = "absolute";
function move(){
   forwardInt = setInterval(forwardFn, 10);
   addInt = setInterval(addFn, 10);
}
function addFn(){ 
   left = left + 10; 
}
function forwardFn(){
   sonic.style.left = left;
}
function stop(){
   clearInterval(forwardInt);
   clearInterval(addInt);
}
</script>

Однако я все еще не думаю, что это вполне соответствует тому, что вы хотели (непрерывное движение, удерживая нажатой клавишукнопка). Я правильно понимаю?

Я внес некоторые коррективы для достижения этой цели, как показано ниже. Я объединил две функции и учел край окна. Я также добавил механизм блокировки / разблокировки для запуска и остановки. Забавно заставить маленького парня уходить! Возвращает меня.

<button onmousedown="move()" onmouseup="stop()">Move Forward</button>
<br>
<br>
<img width="150px" id="sonic" src="https://www.sccpre.cat/mypng/full/338-3383227_sonic-running-png-sonic-1-sonic-sprite.png" />
<script>
var sonic = document.getElementById('sonic');
var left = 0;
var forwardInt;
var addInt;
var lock = false;
sonic.style.position = "absolute";
sonic.style.left=0;
var rect = sonic.getBoundingClientRect();
function move(){
  lock = false;
  forwardInt = setInterval(forwardFn, 10);
}
function forwardFn(){
  if(!lock&&rect.right<window.innerWidth){
    sonic.style.left = rect.left+10;
    rect = sonic.getBoundingClientRect();
  }else{
    clearInterval(forwardInt);
  }
}
function stop(){
  lock = true;
}
</script>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...