多次启动和停止相同的时间间隔

我第一次尝试游戏角色移动。我已经成功制作了一个按钮,当按下按钮时角色可以移动,释放按钮时角色可以停止。我的问题是,这只能工作一次。如果我第二次按下按钮,角色将不再前进。我检查了控制台是否有错误,但没有任何错误。这是我的代码:

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" />

我希望角色能够在用户按住按钮时移动,而不仅仅是一次。

x357904377 回答:多次启动和停止相同的时间间隔

  • 使用一个window.requestAnimationFrame()来代替混乱多个setInterval。
  • 在按钮(甚至键)上操作keys对象,以跟踪按下的键
  • keysController()函数内部,将按下的键(如果存在)转换为pos(甚至以后的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" />

,

第一个问题是变量名的混乱。间隔索引的名称与函数的名称相同-导致混淆。请参阅下面的“我有区别”,每次单击按钮时,它就会向前移动:

<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>
本文链接:https://www.f2er.com/3130641.html

大家都在问