我遵循了有关如何使用JS / HTML构建基本游戏的教程,现在我正在扩展它:Game。 (点击开火,向右箭头向右移动,向左箭头向左移动)

我有:


1 #hero
1个存储#enemies对象的.enemies数组
1个存储#lifes对象的.life数组


我在.enemies数组中添加了30个以上的#enemies对象,当游戏运行时,我会感觉到页面速度的影响。不逐步在.enemies数组中添加#enemies对象的最有效方法是什么?

var hero = {
    top : 700,
    left : 550
};


var missiles = [];

var enemies = [
{left: 700, top: -100},
{left: 500, top: -200},
{left: 200, top: -300},
{left: 700, top: -400},
{left: 400, top: -500},
{left: 800, top: -600},
{left: 200, top: -900},
{left: 250, top: -900},
{left: 120, top: -900},
{left: 160, top: -900},
{left: 280, top: -900},
{left: 330, top: -900},
{left: 330, top: -1100},
{left: 280, top: -1500},
{left: 800, top: -1500},
{left: 500, top: -1500},
{left: 700, top: -1550},
{left: 60, top: -1550},
{left: 560, top: -1600},
{left: 60, top: -1750},
{left: 900, top: -1700},
{left: 150, top: -1950},
{left: 200, top: -1960},
{left: 250, top: -1980},
{left: 50, top: -2500},
{left: 100, top: -2500},
{left: 150, top: -2500},
{left: 200, top: -2540},
{left: 250, top: -2580},
{left: 300, top: -2580},
{left: 350, top: -2580}
];

var lifes = [
    {left: 400, top: -600},
    {left: 50, top: -1300}

]


let health = document.getElementById("health");


const drawEnemies = () => {
    document.getElementById("enemies").innerHTML = "";
    for(var i = 0 ; i < enemies.length ; i++){
        document.getElementById('enemies').innerHTML +=
        `
        <div class="enemy" style='
        left:${enemies[i].left}px;
        top: ${enemies[i].top}px;
        '></div>
        `;
    }
}

const drawLifes = () => {
    document.getElementById("lifes").innerHTML = "";
    for(var i = 0 ; i < lifes.length ; i ++){
        document.getElementById('lifes').innerHTML +=
        `
        <div class='life' style='left:${lifes[i].left}px;
        top:${lifes[i].top}px;'>
        </div>
        `;
    }

}

const drawMissiles = () => {

    document.getElementById("missiles").innerHTML = "";
    for(var i = 0; i < missiles.length ; i++){
        document.getElementById('missiles').innerHTML +=
        `
        <div class='missile' style='left:${missiles[i].left}px;
        top:${missiles[i].top}px;'>
        </div>
        `;

        missiles[i].top
        missiles[i].left
    }
}

const drawHero = () => {
    document.onkeydown = function(e){
        if(e.keyCode == 65){
            health.value -=10;
        }
        if(e.keyCode == 37){
            hero.left = hero.left - 30;
            moveHero();

        }
        else if(e.keyCode ==39){
            hero.left = hero.left + 30;
            moveHero();

        }
        else if(e.keyCode == 32){
            missiles.push(
                {
                    left: hero.left + 25,
                    top: hero.top - 30
                }
            );
            drawMissiles();
        }
    }
}



const moveEnemies = () => {

    for(var i = 0 ; i < enemies.length ; i++){
        enemies[i].top += 2;
        if(enemies[i].top > 700){
            health.value -= 10;
            enemies.splice(i,1);
            if(health.value <= 0){
                alert("GAME OVER");
                document.location.reload();
            }

        }
    }

}

const moveHero = () => {
    document.getElementById("hero").style.left = hero.left + "px";
}

const moveMissiles = () =>{
    for(var i = 0 ; i < missiles.length ; i++){
        missiles[i].top -= 10;
    }
}

const moveLifes= () =>{
    for(var i = 0 ; i < lifes.length ; i++){
        lifes[i].top += 1;
    }
}

const explosion = (topEn, leftEn, delay = 300) => {
    const div = document.createElement('div');
    div.id = 'explosion';
    div.style.top = topEn + 'px';
    div.style.left = leftEn + 'px';

    document.getElementById('explosions').append(div);
    setTimeout(() => {
      div.remove()
    }, delay);
  }



const collisionDetector = () => {
    for(var i = 0 ; i < enemies.length ; i++){
        for(var j = 0 ; j < missiles.length ; j++){
            if(
                (missiles[j].top <= enemies[i].top + 50) &&
                (missiles[j].top >= enemies[i].top) &&
                (missiles[j].left >= enemies[i].left) &&
                (missiles[j].left <= enemies[i].left +50)
            ){
                explosion(enemies[i].top, enemies[i].left);
                enemies.splice(i, 1);
                missiles.splice(j,1);
            }
        }
    }
}

const lifeEating = () => {
    for(var i = 0 ; i < lifes.length ; i++){
        if(
            (lifes[i].top >= hero.top -60) &&
            (lifes[i].left >= hero.left) &&
            (lifes[i].left <= hero.left +50)
        ){
            health.value += 20;
            lifes.splice(i,1);
        }

    }
}



const gameLoop = () => {
    setTimeout(gameLoop,20);
    moveMissiles();
    drawMissiles();
    moveEnemies();
    drawEnemies();
    moveLifes();
    drawLifes();
    collisionDetector();
    lifeEating();
}

const app = () => {
    drawHero();
    drawEnemies();
    gameLoop();
}


app();

最佳答案

将对象添加到数组中并不会真正导致速度变慢,但是过度更新页面上的HTML会造成影响。尝试将其作为darwEnemies函数使用:

const drawEnemies = () => {
    var htmlToAdd = "";
    for(var i = 0 ; i < enemies.length ; i++){
        htmlToAdd +=
        `
        <div class="enemy" style='
        left:${enemies[i].left}px;
        top: ${enemies[i].top}px;
        '></div>
        `;
    }
    document.getElementById('enemies').innerHTML = htmlToAdd;
}


对于30个敌人,此函数现在一次更新HTML,而不是31次,因为我们现在正在for循环中更新变量,而不是页面HTML本身。您可以使用drawLifes()和drawMissles()做同样的事情。

const drawLifes = () => {
    var htmlToAdd = "";
    for(var i = 0 ; i < lifes.length ; i ++){
        htmlToAdd +=
        `
        <div class='life' style='left:${lifes[i].left}px;
        top:${lifes[i].top}px;'>
        </div>
        `;
    }
    document.getElementById("lifes").innerHTML = htmlToAdd;

}

const drawMissiles = () => {

    var htmlToAdd = "";
    for(var i = 0; i < missiles.length ; i++){
        htmlToAdd +=
        `
        <div class='missile' style='left:${missiles[i].left}px;
        top:${missiles[i].top}px;'>
        </div>
        `;

        missiles[i].top
        missiles[i].left
    }
    document.getElementById('missiles').innerHTML = htmlToAdd;
}


要添加更快的敌人,请向敌人中的每个对象添加“帧速率”属性。

var enemies = [
{framerate: 1, left: 700, top: -100},
{framerate: 1, left: 500, top: -200},
{framerate: 1, left: 200, top: -300},
{framerate: 1, left: 700, top: -400},
{framerate: 1, left: 400, top: -500},
{framerate: 2, left: 800, top: -600},
{framerate: 2, left: 200, top: -900},
{framerate: 2, left: 250, top: -900},
{framerate: 2, left: 120, top: -900},
{framerate: 2, left: 160, top: -900},
{framerate: 2, left: 280, top: -900},
{framerate: 2, left: 330, top: -900},
{framerate: 2, left: 330, top: -1100},
{framerate: 2, left: 280, top: -1500},
{framerate: 2, left: 800, top: -1500},
{framerate: 2, left: 500, top: -1500},
{framerate: 2, left: 700, top: -1550},
{framerate: 2, left: 60, top: -1550},
{framerate: 2, left: 560, top: -1600},
{framerate: 2, left: 60, top: -1750},
{framerate: 2, left: 900, top: -1700},
{framerate: 2, left: 150, top: -1950},
{framerate: 2, left: 200, top: -1960},
{framerate: 2, left: 250, top: -1980},
{framerate: 2, left: 50, top: -2500},
{framerate: 2, left: 100, top: -2500},
{framerate: 2, left: 150, top: -2500},
{framerate: 2, left: 200, top: -2540},
{framerate: 2, left: 250, top: -2580},
{framerate: 2, left: 300, top: -2580},
{framerate: 2, left: 350, top: -2580}
];


这将给我们在moveEnemies函数中提供一些参考,以告诉我们移动每个敌人的频率。

var frame = 0;
const moveEnemies = () => {
    frame++;
    for(var i = 0 ; i < enemies.length ; i++){
        if(frame % enemies[i].framerate == 0){
            enemies[i].top += 2;
            if(enemies[i].top > 700){
                health.value -= 10;
                enemies.splice(i,1);
                if(health.value <= 0){
                    alert("GAME OVER");
                    document.location.reload();
                }
            }
        }
    }
}


如果敌人的帧率为2,我们仅每隔一帧移动一次该敌人。因为您所有的敌人已经在每一帧中移动了,所以此代码并不会真正加快任何敌人的速度,而是使其中一些敌人减速。为了加快速度,请增加游戏的运行频率,如下所示:

const gameLoop = () => {
    setTimeout(gameLoop,10);//used to be 20
    moveMissiles();
    drawMissiles();
    moveEnemies();
    drawEnemies();
    moveLifes();
    drawLifes();
    collisionDetector();
    lifeEating();
}

10-06 00:18