我遵循了有关如何使用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();
}