簡體   English   中英

在HTML5游戲中實現計時器

[英]Implement a Timer in HTML5 Game

我正在嘗試在HTML5畫布上構建一個小型游戲,嘗試在游戲中設置1分鍾倒數計時器時遇到了麻煩。

以下代碼包含timeKeeper函數和animate循環。

計時員

function timeKeeper(width, font, posX, posY, text) {
    this.width = width;
    this.x = posX;
    this.y = posY;
    this.font = font;
    this.text = text;
    this.numSeconds = 0;
    this.time = 0;

    this.draw = () => {
        c.font = this.width + " " + this.font;
        c.fillStyle = "white";
        c.fillText(this.text, this.x, this.y);
    }

    this.update = () => {
        setInterval(() => {
            this.text -= 1;
        },1000)
        this.draw();
    }

}

活躍

// Animation Loop
function animate() {
    requestAnimationFrame(animate)
    c.clearRect(0, 0, canvas.width, canvas.height)
    timeBoard.update()
    //Move enemies
    enemies.forEach((enemy) => {
        //update score and time
        scoreBoard.draw();

        //draw labels
        scoreLabel.draw();
        timeLabel.draw();

        //update enemies
        enemy.update();
        enemy.checkBoundary();
        if (enemy.isTrue == true) {
            enemies.splice(enemies.indexOf(enemy), 1);
            // console.log(enemies);
        }

        if (enemies.length == 0) {
            setTimeout(initEnemies(), 200)
        }

        //collision detection by checking color
        if (enemy.color == "#2185C5") {
            if (getDistance(enemy.x, enemy.y, ship[0].x, ship[0].y) < enemy.radius + ship[0].radius) {
                enemy.color = "#FF00FF"
                scoreBoard.update();
            }
        }
    });
    //create one particle
    ship[0].update();
}

我認為這里發生的是timeBoard.update()函數每幀都會調用一次,從而導致倒數真的非常快。

誰能幫我解決這個問題?

提前致謝。

您需要使計數器在動畫幀循環方法之外運行。 您可以在函數內添加某種計時器來補償幀(60fps意味着animate()大約每隔16.667ms運行一次),但是requestAnimationFrame()並不總是以60fps運行。 如果瀏覽器無法以這種速度渲染,則會降低幀循環的速度。 因此,制作一個與requestAnimationFrame();有關的計時器不是一個好主意requestAnimationFrame();

而是在函數外部創建一個計數器。 理想情況下,請在開始動畫循環之前立即使用setInterval() 時間間隔可能看起來像這樣...

var counter = 0;
var timer = window.requestAnimationFrame(function(){
  timeBoard.update();
  if(counter+1 == 60){
    //a minute has passed, clear the interval:
    clearInterval(timer);
  }else{
    counter++;
  }
},1000);

如果您在問題詳細信息中包含啟動動畫循環的代碼,那么我可以幫助您確切地說明如何實現它。 另外,您沒有提及是否需要計數器可重復使用。 這些都是要考慮的事情。 如果需要可重用,則可以考慮使用面向對象的解決方案。

setInterval函數堆棧,這意味着它將繼續創建setInterval實例。 通過重復調用timeBoard.update(),您將創建許多setInterval實例,從而使計時器運行得更快。 您可以將update方法更改為init ,然后在動畫循環之外調用該方法。

在動畫循環中調用timeBoard.draw()以便繪制計時器。 然后在動畫循環之外調用setInterval()函數。

謝謝大家〜:)

function animate() {
    requestAnimationFrame(animate)
    c.clearRect(0, 0, canvas.width, canvas.height)
    timeBoard.draw()
    //Move enemies
    enemies.forEach((enemy) => {
        //update score and time
        scoreBoard.draw();

        //draw labels
        scoreLabel.draw();
        timeLabel.draw();

        //update enemies
        enemy.update();
        enemy.checkBoundary();
        if (enemy.isTrue == true) {
            enemies.splice(enemies.indexOf(enemy), 1);
            // console.log(enemies);
        }

        if (enemies.length == 0) {
            setTimeout(initEnemies(), 200)
        }

        //collision detection by checking color
        if (enemy.color == "#2185C5") {
            if (getDistance(enemy.x, enemy.y, ship[0].x, ship[0].y) < enemy.radius + ship[0].radius) {
                enemy.color = "#FF00FF"
                scoreBoard.update();
            }
        }
    });
    //create one particle
    ship[0].update();
}

//Run Timer
setInterval(() => {
    timeBoard.update()
}, 1000)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM