使用setInterval中的setTimeout,对象移动会降低速度

时间:2017-06-17 20:08:58

标签: javascript

我正在测试我正在进行的练习游戏的动作,我尝试使用的是一个循环,它将运行两次(因为对象是一只兔子)一个间隔,以便物体不会在连续的圆圈中移动,并且它具有唯一性。我如何执行它是间隔将每1500毫秒运行,超时(在间隔内)将运行一半的时间来创建兔子在一个方向上移动两次而不是一次。问题是,经过一段时间后,兔子将采取更大的步骤,并做得更快。我不完全确定问题是什么,谢谢你看这个。继承我的代码



var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

var wabbits = {
  wabbit1: {
    x: 200,
    y: 200,
    w: 10,
    h: 10,
    speed: 2,
    moving: "",
    dead: false,
    updateInterval: 2000
  }
};
  //make it easier to type out the object
  var bunny = wabbits.wabbit1;

var movement = ["up", "down", "left", "right"];
var left = "left";
var up = "up";
var down = "down";
var right = "right";

var update = setInterval(function(){
  draw();
}, 1);

canvas.style.backgroundColor = "green";

function draw(){
  context.clearRect(0, 0, canvas.width, canvas.height);
  context.fillStyle = "grey";
  context.fillRect(bunny.x, bunny.y, bunny.w, bunny.h);
  context.fill();
  border();
}

function border(){
  if(bunny.x <= 0){
    bunny.x += bunny.speed * 2;
  }
  if(bunny.x >= 490){
    bunny.x -= bunny.speed * 2;
  }
  if(bunny.y <= 0){
    bunny.y += bunny.speed * 2;
  }
  if(bunny.y >= 490){
    bunny.y -= bunny.speed * 2;
  }
}

function bunny1move(){
	if(!wabbits.wabbit1.dead){
		var randM = Math.floor(Math.random() * 3) + 0;
		wabbits.wabbit1.moving = movement[randM];
		function mv(){
			switch(wabbits.wabbit1.moving){
				case "up":
					wabbits.wabbit1.y -= wabbits.wabbit1.speed;
				break;
				case "down":
					wabbits.wabbit1.y += wabbits.wabbit1.speed;
				break;
				case "left":
					wabbits.wabbit1.x -= wabbits.wabbit1.speed;
				break;
				case "right":
					wabbits.wabbit1.x += wabbits.wabbit1.speed;
				break;
				default: 
					console.log("something in bunny1.mv() is not working properly, err: " + wabbits.wabbits1.moving);
				break;
			};
			if(wabbits.wabbit1.y <= 0){
				wabbits.wabbit1.y += wabbits.wabbit1.speed * 2;
				wabbits.wabbit1.moving = down;
			}
			if(wabbits.wabbit1.y >= 758){
				wabbits.wabbit1.y -= wabbits.wabbit1.speed * 2;
				wabbits.wabbit1.moving = up;
			}
			if(wabbits.wabbit1.x <= 0){
				wabbits.wabbit1.x += wabbits.wabbit1.speed * 2;
				wabbits.wabbit1.moving = right;
			}
			if(wabbits.wabbit1.x >= 1356){
				wabbits.wabbit1.x -= wabbits.wabbit1.speed * 2;
				wabbits.wabbit1.moving = left;
			}
      //make mv repeat twice
			this.setTimeout(mv, wabbits.wabbit1.updateInterval / 2);
		}
		mv();
		
	}
}
//update the movement function
setInterval(bunny1move, wabbits.wabbit1.updateInterval);
&#13;
<canvas id="canvas" height="500px" width="500px"></canvas>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

你在bunny1move中创建它之后立即调用mv,但是在每次调用mv之后它会设置一个超时,以便在一秒后再次调用它自己。在再次调用之后,它会设置一个新的超时,以便在下一秒后调用自身,依此类推。这一系列的呼叫无限延伸。

这本身并不会太糟糕,实际上它似乎就是你想要的,让mv每秒都会调用。当你每两秒调用一次bunny1move时会出现问题,这些重复调用bunny1move会创建一个新的mv链,并且它们都堆叠在前面的链之上。

所以并不是说兔子在每次迭代中都移动得越来越远,而是正在创建越来越多的mv链,并且它们都被同步调用,使它看起来像一个更长的跳跃,而实际上它只是很多更多的小跳跃。

如果你在mv的末尾放置一个console.log语句,你可以看到随着时间推移mv调用的增加。

你应该能够完全摆脱mv,然后每隔一秒就在bunny1move上调用setInterval:

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

var wabbits = {
  wabbit1: {
    x: 200,
    y: 200,
    w: 10,
    h: 10,
    speed: 2,
    moving: "",
    dead: false,
    updateInterval: 2000
  }
};
  //make it easier to type out the object
  var bunny = wabbits.wabbit1;

var movement = ["up", "down", "left", "right"];
var left = "left";
var up = "up";
var down = "down";
var right = "right";

var update = setInterval(function(){
  draw();
}, 1);

canvas.style.backgroundColor = "green";

function draw(){
  context.clearRect(0, 0, canvas.width, canvas.height);
  context.fillStyle = "grey";
  context.fillRect(bunny.x, bunny.y, bunny.w, bunny.h);
  context.fill();
  border();
}

function border(){
  if(bunny.x <= 0){
    bunny.x += bunny.speed * 2;
  }
  if(bunny.x >= 490){
    bunny.x -= bunny.speed * 2;
  }
  if(bunny.y <= 0){
    bunny.y += bunny.speed * 2;
  }
  if(bunny.y >= 490){
    bunny.y -= bunny.speed * 2;
  }
}

function bunny1move(){
	if(!wabbits.wabbit1.dead){
		var randM = Math.floor(Math.random() * 3) + 0;
		wabbits.wabbit1.moving = movement[randM];
		switch(wabbits.wabbit1.moving){
			case "up":
				wabbits.wabbit1.y -= wabbits.wabbit1.speed;
			break;
			case "down":
				wabbits.wabbit1.y += wabbits.wabbit1.speed;
			break;
			case "left":
				wabbits.wabbit1.x -= wabbits.wabbit1.speed;
			break;
			case "right":
				wabbits.wabbit1.x += wabbits.wabbit1.speed;
			break;
			default: 
				console.log("something in bunny1.mv() is not working properly, err: " + wabbits.wabbits1.moving);
				break;
		};
		if(wabbits.wabbit1.y <= 0){
			wabbits.wabbit1.y += wabbits.wabbit1.speed * 2;
			wabbits.wabbit1.moving = down;
		}
		if(wabbits.wabbit1.y >= 758){
			wabbits.wabbit1.y -= wabbits.wabbit1.speed * 2;
			wabbits.wabbit1.moving = up;
		}
		if(wabbits.wabbit1.x <= 0){
			wabbits.wabbit1.x += wabbits.wabbit1.speed * 2;
			wabbits.wabbit1.moving = right;
		}
		if(wabbits.wabbit1.x >= 1356){
			wabbits.wabbit1.x -= wabbits.wabbit1.speed * 2;
			wabbits.wabbit1.moving = left;
		}
	}
}
//update the movement function
setInterval(bunny1move, wabbits.wabbit1.updateInterval / 2);
<canvas id="canvas" height="500px" width="500px"></canvas>

顺便说一句,您应该考虑在https://codereview.stackexchange.com/上发布此内容。他们应该就设计程序的更好方法提出一些建设性的意见,以获得更大的灵活性,可扩展性,可读性等。