一个阵列的重置影响另一个阵列
The reset of one array affecting a different array
我不完全确定这里发生了什么。当您发射所有三颗子弹并且最后一颗子弹离开屏幕时,"asteroids" 数组也会重置。
编辑:
是不是因为bullets数组在全部离开屏幕的时候最后拼接成了一个undefined?还是 return 基本空数组?即便如此,它也没有解释为什么小行星阵列也被取消了。我还发现,除非我至少射击一次,否则小行星甚至不会开始坠落。
造成这种情况的原因是什么?这是我第一次编写这么大的代码,代码量很大,但我确保在大多数情况下使用明显的变量名。
问题出在你的asteroids
class:
check(bullets) {
for (let i = 0; i < bullets.length; i++) {
if (dist(bullets[i].x, bullets[i].y, this.pos.x, this.pos.y) < this.r) {
return false;
} else {
return true;
}
}
}
如果没有要检查的子弹,这个函数 returns undefined
隐含地被调用代码认为是假的,它会立即摧毁小行星,就像它与子弹相撞一样.
此外,如果有子弹需要检查,而第一个恰好没有发生碰撞,则循环会过早中断 else { return true; }
,可能会丢失碰撞。
改为:
check(bullets) {
for (let i = 0; i < bullets.length; i++) {
if (dist(bullets[i].x, bullets[i].y, this.pos.x, this.pos.y) < this.r) {
return false;
}
}
return true; // no collisions (or bullets.length === 0)
}
话虽如此,函数名称 check
还是很不清楚。我将其重命名为 collidesWith(bullets)
并反转布尔值——"true, yes, we did collide with a bullet" 比 "false, yes, we did collide with a bullet" 更有意义。我们还可以使用 for ... of
循环结构。这给了我们:
collidesWith(bullets) {
for (const bullet of bullets) {
if (dist(bullet.x, bullet.y, this.pos.x, this.pos.y) < this.r) {
return true;
}
}
return false;
}
您可以进一步缩短为:
collidesWith(bullets) {
return bullets.some(e => dist(e.x, e.y, this.pos.x, this.pos.y) < this.r);
}
同样,我会将 bullet.check()
更改为 bullet.outOfBounds()
或类似的。
另一个提示:反向迭代您计划从以下位置切片当前元素的任何数组:
for (let j = asteroids.length - 1; j >= 0; j--) {
// code that could call `.splice(j, 1)`
}
否则,在拼接后,您的循环将跳过一个元素,您可能会错过碰撞。
一个小设计点,但 player.controls()
看起来很奇怪——为什么玩家要负责监听按键?我会在 keyPressed()
函数中收听并发送更改以从那里更新玩家位置。我还会将 draw
分解成更小的函数。但这些都是次要的设计决定,因此以上内容足以让您滚动。
这是 draw
函数的第一个修订版,经过调整以匹配修改后的布尔值:
function draw() {
background(0);
scene();
if (tick <= 0) {
if (asteroids.length < asteroidsLimit) {
asteroids.push(new Asteroid());
}
tick = 60;
}
for (let i = asteroids.length - 1; i >= 0; i--) {
if (asteroids[i].collidesWith(bullets)) {
asteroids.splice(i, 1);
}
else {
asteroids[i].update();
asteroids[i].display();
}
}
for (let i = bullets.length - 1; i >= 0; i--) {
if (bullets[i].outOfBounds()) {
bullets.splice(i, 1);
}
else {
bullets[i].update();
bullets[i].display();
}
}
image(ship, player.x, player.y);
player.controls();
tick--;
}
我不完全确定这里发生了什么。当您发射所有三颗子弹并且最后一颗子弹离开屏幕时,"asteroids" 数组也会重置。
编辑: 是不是因为bullets数组在全部离开屏幕的时候最后拼接成了一个undefined?还是 return 基本空数组?即便如此,它也没有解释为什么小行星阵列也被取消了。我还发现,除非我至少射击一次,否则小行星甚至不会开始坠落。
造成这种情况的原因是什么?这是我第一次编写这么大的代码,代码量很大,但我确保在大多数情况下使用明显的变量名。
问题出在你的asteroids
class:
check(bullets) {
for (let i = 0; i < bullets.length; i++) {
if (dist(bullets[i].x, bullets[i].y, this.pos.x, this.pos.y) < this.r) {
return false;
} else {
return true;
}
}
}
如果没有要检查的子弹,这个函数 returns undefined
隐含地被调用代码认为是假的,它会立即摧毁小行星,就像它与子弹相撞一样.
此外,如果有子弹需要检查,而第一个恰好没有发生碰撞,则循环会过早中断 else { return true; }
,可能会丢失碰撞。
改为:
check(bullets) {
for (let i = 0; i < bullets.length; i++) {
if (dist(bullets[i].x, bullets[i].y, this.pos.x, this.pos.y) < this.r) {
return false;
}
}
return true; // no collisions (or bullets.length === 0)
}
话虽如此,函数名称 check
还是很不清楚。我将其重命名为 collidesWith(bullets)
并反转布尔值——"true, yes, we did collide with a bullet" 比 "false, yes, we did collide with a bullet" 更有意义。我们还可以使用 for ... of
循环结构。这给了我们:
collidesWith(bullets) {
for (const bullet of bullets) {
if (dist(bullet.x, bullet.y, this.pos.x, this.pos.y) < this.r) {
return true;
}
}
return false;
}
您可以进一步缩短为:
collidesWith(bullets) {
return bullets.some(e => dist(e.x, e.y, this.pos.x, this.pos.y) < this.r);
}
同样,我会将 bullet.check()
更改为 bullet.outOfBounds()
或类似的。
另一个提示:反向迭代您计划从以下位置切片当前元素的任何数组:
for (let j = asteroids.length - 1; j >= 0; j--) {
// code that could call `.splice(j, 1)`
}
否则,在拼接后,您的循环将跳过一个元素,您可能会错过碰撞。
一个小设计点,但 player.controls()
看起来很奇怪——为什么玩家要负责监听按键?我会在 keyPressed()
函数中收听并发送更改以从那里更新玩家位置。我还会将 draw
分解成更小的函数。但这些都是次要的设计决定,因此以上内容足以让您滚动。
这是 draw
函数的第一个修订版,经过调整以匹配修改后的布尔值:
function draw() {
background(0);
scene();
if (tick <= 0) {
if (asteroids.length < asteroidsLimit) {
asteroids.push(new Asteroid());
}
tick = 60;
}
for (let i = asteroids.length - 1; i >= 0; i--) {
if (asteroids[i].collidesWith(bullets)) {
asteroids.splice(i, 1);
}
else {
asteroids[i].update();
asteroids[i].display();
}
}
for (let i = bullets.length - 1; i >= 0; i--) {
if (bullets[i].outOfBounds()) {
bullets.splice(i, 1);
}
else {
bullets[i].update();
bullets[i].display();
}
}
image(ship, player.x, player.y);
player.controls();
tick--;
}