簡體   English   中英

為什么在canvas上繪制很多元素時頁面開始卡頓?

[英]Why does the page start to lag when drawing many elements on the canvas?

我正在創建一個游戲,我需要在<canvas>的頂部繪制一些元素,但是出現的元素越多,頁面本身的滯后性就越大。 我發現這個例子中出現了很多圓圈,但一切正常 - JSFiddle 有人可以告訴我如何優化我的案例嗎?

"use strict";

/*Determing canvas*/
window.onload = () => {
    const canvas = document.getElementById("canvas"),
        ctx = canvas.getContext('2d'),
        endTitle = document.getElementById('gameover');
    let spawnRate = 300,
        lastspawn = -1;

    class Wall {
        /*Getting values*/
        constructor(x, y, width, height, speed) {
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
            this.speed = speed;
        }
        /*Draw rectangle*/
        draw() {
            ctx.beginPath();
            ctx.fillStyle = "#000000";
            ctx.fillRect(this.x, this.y, this.width, this.height)
        }
    }

    /*Making walls*/
    let walls = [];

    /*Spawn walls endlessly*/
    function spawnWalls() {
        const wall_x = Math.floor(Math.random() * (canvas.width - 20)) + 10
        const wall_y = 0
        for (let i = 0; i < 200; i++) {
            walls.push(new Wall(wall_x, wall_y, 10, 10, 10))
        }
    }
    
    /*Update game*/
    function refresh() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        let time = Date.now()
        if (time > (lastspawn + spawnRate)) {
            lastspawn = time;
            spawnWalls();
            spawnRate -= 10;
        }
        walls.forEach(wall => wall.draw())
        for (let j of walls) {
            j.y += j.speed;
            j.draw();
        };
    };
    let interval = setInterval(refresh, 50);                                                                                                   

Walls太大了。

看起來您永遠不會移除舊牆,因此在將它們從 canvas 中移除后,它們會繼續被很好地繪制。 在您的 Refresh function 中,檢查牆壁是否已通過 canvas 大小,如果是,請將其從walls陣列中刪除。

編輯:

我已經從評論中添加了您的“刪除”代碼。

另一個簡單的勝利是停止使用new Date()因為誰知道什么,可能是時區和本地化,日期實例化非常昂貴。 然而,現代瀏覽器提供了 API 的性能,它可以告訴您自頁面加載以來的時間,這似乎對您現有的性能有很大的改進。

 "use strict"; /*Determing canvas*/ window.onload = () => { const canvas = document.getElementById("canvas"), ctx = canvas.getContext('2d'), endTitle = document.getElementById('gameover'); let spawnRate = 300, lastspawn = -1; endTitle.style.display = "none"; canvas.width = window.innerWidth; canvas.height = window.innerHeight; /*Classes*/ class Player { /*Get player info*/ constructor(x, y, width, height, speed) { this.x = x; this.y = y; this.width = width; this.height = height; this.speed = speed; } /*Draw player*/ draw() { ctx.beginPath(); ctx.fillStyle = "#000000"; ctx.fillRect(this.x, this.y, this.width, this.height); } /*Move player*/ move() { } }; class Wall { /*Getting values*/ constructor(x, y, width, height, speed) { this.x = x; this.y = y; this.width = width; this.height = height; this.speed = speed; } /*Draw rectangle*/ draw() { ctx.beginPath(); ctx.fillStyle = "#000000"; ctx.fillRect(this.x, this.y, this.width, this.height) } } /*Defining players*/ let player_01 = new Player(20, 70, 20, 20, 10); let player_02 = new Player(50, 500, 20, 20, 10); let players = []; players.push(player_01); /*Making walls*/ let walls = []; /*Spawn Walls for infinity*/ function spawnWalls() { const wall_x = Math.floor(Math.random() * (canvas.width - 20)) + 10 const wall_y = 0 for (let i = 0; i < 200; i++) { walls.push(new Wall(wall_x, wall_y, 10, 10, 10)) } } /*Update game*/ function refresh() { ctx.clearRect(0, 0, canvas.width, canvas.height); let time = performance.now() if (time > (lastspawn + spawnRate)) { lastspawn = time; spawnWalls(); spawnRate -= 10; } walls.forEach(wall => wall.draw()) outOfWindow() for (let i of players) { i.draw(); }; for (let j of walls) { if (jy > canvas.height) { walls.shift(j) } jy += j.speed; j.draw(); if (player_01.height + player_01.y > jy && j.height + jy > player_01.y && player_01.width + player_01.x > jx && j.width + jx > player_01.x) { clearInterval(interval); endTitle.style.display = "flex"; }; }; }; let interval = setInterval(refresh, 50); /*Move players on keypress*/ for (let i of players) { window.addEventListener("keydown", (event) => { let key = event.key.toLowerCase(); if (key == "w") iy -= i.speed; else if (key == "s") iy += i.speed; else if (key == "a") ix -= i.speed; else if (key == "d") ix += i.speed; }) } /*Check if player out of the window*/ function outOfWindow() { for (let i of players) { if (ix < 0) ix = 0; else if (ix + i.width > canvas.width) ix = canvas.width - i.width; else if (iy < 0) iy = 0; else if (iy + i.height > canvas.height) iy = canvas.height - i.height; } } }
 #gameover { position: absolute; width: 100%; height: 100%; justify-content: center; align-items: center; flex-direction: column; background-color: rgba(0, 0, 0, .5); }
 <div id="gameover"> <h2>The Game Is Over</h2> <button onclick="restart()">Try again!</button> </div> <canvas id="canvas"></canvas>

暫無
暫無

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

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