必须有一个非常简单的解决方案,因为我已经尝试搞乱setInterval(),但似乎无法得到我想要的结果......
我有这个globalTick()
function globalTick(){
ctx.clearRect(0,0,800,800)
if(target){
target.tick();
}
// Move arrows
for(var i = 0; i < spriteList.length; i++){
spriteList[i].tick()
}
window.requestAnimationFrame(globalTick);
}
document.onkeyup = function(e){
// Change gamestate
if(e.which == 13){
$("#state"+gameState).hide()
gameState ++
if(gameState == 6){
// Affect game variables
player = new Player(0);
target = new Target(targetX, targetY)
for(var i = 0; i < player.calculateNotes(); i++){
timerID = setInterval(spawnArrows(), 3000)
}
clearInterval(timerID)
}
// ...
spawnArrows = function(){
// Rabdomize arrows (15 for now)
var dirCode = Math.floor((Math.random() * 8));
spriteList.push(new Arrow(dirCode))
//soundsSequence.push(soundsList[dirCode])
}
然后我在我的精灵上有这个tick()方法,在本例中是一个箭头对象
class Arrow{
constructor(dirCode){
this.dirCode = dirCode;
this.speedX = 1
this.speedY = 1
switch(this.dirCode){
// ...
}
tick(){
ctx.fillStyle = "black"
ctx.fillRect(this.x, this.y, spriteSize, spriteSize)
switch(this.dirCode){
case 0:
this.x += this.speedX
break
case 1:
this.x += this.speedX
this.y -= this.speedY
break
// ...
我已经把你们变量声明给了你们。
我想要的是延迟每个新箭头按照另一个对象中存在的设定时间推入阵列,假设示例中为3秒。甚至可以通过requestAnimationFrame在一个被调用60次左右的globalTick()中减速吗?理想情况下,在纯JS中,除非JQuery是唯一的方法......
非常感谢,希望这很清楚!
答案 0 :(得分:0)
这是使用setTimeout队列的解决方案。
部分应用的> nm -DC /usr/lib64/libc++_shared.so | grep 'std::__1'
=== lots of output ===
> nm -DC /usr/lib64/libc++_shared.so | grep 'std::basic'
=== nothing ===
> nm -DC /usr/lib/gcc/x86_64-pc-linux-gnu/6.2.0/libstdc++.so.6 | grep 'std::__1'
=== nothing ===
> nm -DC /usr/lib/gcc/x86_64-pc-linux-gnu/6.2.0/libstdc++.so.6 | grep 'std::basic'
=== lots of output ===
函数被推入队列。 spawnArrow
从队列中删除第一个函数并调用它。
spawnQueue.shift()();
let notes = ["A", "B", "C", "D", "E"];
let spriteList = [];
let spawnQueue = [];
let delayTime = 500;
function globalTick() {
spriteList.forEach(sprite => sprite.tick());
requestAnimationFrame(globalTick);
}
globalTick();
$('button').click(onButtonClick);
function onButtonClick() {
let kickOffQueue = spawnQueue.length <= 0;
notes.forEach(note =>
spawnQueue.push(() => spawnArrow(note))
);
if (kickOffQueue) {
// here you can set the delay time of the first execution
consumeSpawnQueue(500);
}
}
function consumeSpawnQueue(nextDelayTime) {
if (spawnQueue.length > 0) {
setTimeout(() => {
spawnQueue.shift()();
consumeSpawnQueue(delayTime);
}, nextDelayTime);
}
}
function spawnArrow(note) {
var dirCode = Math.floor((Math.random() * 8));
spriteList.push(new Arrow(dirCode, note));
}
class Arrow {
constructor(dirCode, note) {
this.dirCode = dirCode;
this.x = 0;
this.domEl = $(`<div>${note}${dirCode}</div>`).appendTo('body');
}
tick() {
this.x += 1;
this.domEl.css({
marginLeft: this.x
});
}
}
注意:setTimeout不是非常准确的时间 - 它只能保证最小延迟。如果您需要时间准确性,则需要计算如下所用的时间:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>spawnArrows</button>
在你的globalTick游戏循环中:
const startTime = new Date();
const elapsedTime = () => (new Date() - startTime) / 1000;
在spawnArrow函数中,您可以设置:
if ((elapsedTime() - lastSpawnArrowTime) > delayTime) {
spawnQueue.shift()();
}