- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我遵循了有关如何使用 JS/HTML 构建基本游戏的教程,现在我正在扩展它:Game 。 (点击空格即可开火,右箭头在右侧移动,左箭头在左侧移动)
我有:
#hero
#enemies
数组,用于存储 .enemies
对象#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();
}
关于javascript - JS浏览器游戏-避免初始化所有对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59236870/
我们已经有一个使用 AnyEvent 的库。它在内部使用 AnyEvent,并最终返回一个值(同步 - 不使用回调)。有什么方法可以将这个库与 Mojolicious 一起使用吗? 它的作用如下: #
我想从 XSD 文件生成带有 JAXB 的 Java 类。 问题是,我总是得到一些像这样的类(删除了命名空间): public static class Action { @X
我有一个关于 html 输入标签或 primefaces p:input 的问题。为什么光标总是自动跳转到输入字段。我的页面高度很高,因此您需要向下滚动。输入字段位于页面末尾,光标自动跳转(加载)到页
我今天在考虑面向对象设计,我想知道是否应该避免 if 语句。我的想法是,在任何需要 if 语句的情况下,您都可以简单地创建两个实现相同方法的对象。这两个方法实现只是原始 if 语句的两个可能的分支。
String graphNameUsed = graphName.getName(); if (graphType.equals("All") || graphType.equals(
我有一张友谊 table CREATE TABLE IF NOT EXISTS `friendList` ( `id` int(10) NOT NULL, `id_friend` int(10
上下文 Debian 64。Core 2 二人组。 摆弄循环。我使用了同一循环的不同变体,但我希望尽可能避免条件分支。 但是,即使我认为它也很难被击败。 我考虑过 SSE 或位移位,但它仍然需要跳转(
我最近在 Java 中创建了一个方法来获取字符串的排列,但是当字符串太长时它会抛出这个错误:java.lang.OutOfMemoryError: Java heap space我确信该方法是有效的,
我正在使用 (C++) 库,其中需要使用流初始化对象。库提供的示例代码使用此代码: // Declare the input stream HfstInputStream *in = NULL; tr
我有一个 SQL 查询,我在 WHERE 子句中使用子查询。然后我需要再次使用相同的子查询将其与不同的列进行比较。 我假设没有办法在子查询之外访问“emp_education_list li”? 我猜
我了解到在 GUI 线程上不允许进行网络操作。对我来说还可以。但是为什么在 Dialog 按钮点击回调上使用这段代码仍然会产生 NetworkOnMainThreadException ? new T
有没有办法避免在函数重定向中使用 if 和硬编码字符串,想法是接收一个字符串并调用适当的函数,可能使用模板/元编程.. #include #include void account() {
我正在尝试避免客户端出现 TIME_WAIT。我连接然后设置 O_NONBLOCK 和 SO_REUSEADDR。我调用 read 直到它返回 0。当 read 返回 0 时,errno 也为 0。我
我正在开发 C++ Qt 应用程序。为了在应用程序或其连接的设备出现故障时帮助用户,程序导出所有内部设置并将它们存储在一个普通文件(目前为 csv)中。然后将此文件发送到公司(例如通过邮件)。 为避免
我有一组具有公共(public)父类(super class)的 POJO。这些存储在 superclass 类型的二维数组中。现在,我想从数组中获取一个对象并使用子类 的方法。这意味着我必须将它们转
在我的代码中,当 List 为 null 时,我通常使用这种方法来避免 for 语句中的 NullPointerException: if (myList != null && myList.size
我正在尝试避免客户端出现 TIME_WAIT。我连接然后设置 O_NONBLOCK 和 SO_REUSEADDR。我调用 read 直到它返回 0。当 read 返回 0 时,errno 也为 0。我
在不支持异常的语言和/或库中,许多/几乎所有函数都会返回一个值,指示其操作成功或失败 - 最著名的例子可能是 UN*X 系统调用,例如 open( ) 或 chdir(),或一些 libc 函数。 无
我尝试按值提取行。 col1 df$col1[col1 == "A"] [1] "A" NA 当然我只想要“A”。如何避免 R 选择 NA 值?顺便说一句,我认为这种行为非常危险,因为很多人都会陷入
我想将两个向量合并到一个数据集中,并将其与函数 mutate 集成为 5 个新列到现有数据集中。这是我的示例代码: vector1% rowwise()%>% mutate(vector2|>
我是一名优秀的程序员,十分优秀!