Основная проблема заключается в том, что вы итерируете массивы, в то время как вы удаляете элементы из массивов. Вы пропустите элемент для каждого удаляемого элемента (кроме последнего удаляемого элемента).
См. Также (Looping through array and removing items, without breaking for loop
)
Более того, вы 2 вложенных массива и удаляемые элементы образуют внешний список во внутренней l oop. Это приводит к ошибке, если последний элемент внешнего списка удален, а внутренний массив все еще итерирован:
for (let s = 0; s < shadows.length; s++) {
// [...]
for (let e = 0; e < bullets.length; e++) {
if (abs(bullets[e].x - shadows[s].x) < 25 && abs(bullets[e].y - shadows[s].y) < 25) {
bullets.splice(e, 1);
shadows.splice(s, 1); // <--- causes error if last element is removed
// but inner loop still runs
}
}
}
Другая проблема заключается в том, что проверка на столкновение работает неправильно, поскольку (shadows[s].x
, shadows[s].y
) - это верхний левый угол прямоугольника, а не центра.
Выполните итерацию массивов в обратном порядке и используйте (shadows[s].x+25
, shadows[s].y+25
) для проверки столкновения, чтобы решить проблему:
//Updating and moving bullets
for (let i = bullets.length-1; i >=0 ; i--) {
bullets[i].update();
bullets[i].display();
if (bullets[i].x < -50 || bullets[i].x > 650 || bullets[i].y < -50 || bullets[i].y > 650) {
bullets.splice(i, 1);
}
}
//Updating and moving shadows
for (let s = shadows.length-1; s >= 0; s--) {
shadows[s].update();
shadows[s].display();
let remove_enemy = false;
for (let e = bullets.length-1; e >=0 ; e--) {
if (abs(bullets[e].x - (shadows[s].x+25)) < 25 && abs(bullets[e].y - (shadows[s].y+25)) < 25) {
bullets.splice(e, 1);
remove_enemy = true;
}
}
if (remove_enemy) {
shadows.splice(s, 1);
}
}
Полный пример:
//Character Position
let playX = 300;
let playY = 300;
let up = false;
let down = false;
let left = false;
let right = false;
let working = false;
let bulletSpeed = 3;
var bullets = [];
var shadows = [];
var angleEn;
var enemySpeed = 1;
var spawnRate = 300;
function setup() {
var canvas = createCanvas(600, 600);
generateEnemy();
}
function generateEnemy() {
side = floor(random(0, 2));
side2 = floor(random(0, 2));
if (side % 2 === 0) { // top and bottom
shadows.push(new Enemy(random(0, width), height * (side2 % 2)));
} else { // sides
shadows.push(new Enemy(width * (side2 % 2), random(0, height)));
}
}
function timeEnter() {
if (frameCount % spawnRate === 0) {
generateEnemy();
if (enemySpeed < 3) {
enemySpeed += 0.1;
}
if (spawnRate > 50) {
spawnRate -= 10;
}
}
}
function character() {
fill(0);
rect(playerX, playerY, 50, 50);
}
function movement() {
if (up) {
playY -= 2;
}
if (down) {
playY += 2;
}
if (left) {
playX -= 2;
}
if (right) {
playX += 2;
}
}
function draw() {
//Setting up background
playerX = playX - 25;
playerY = playY - 25;
background(0);
fill(255);
rect(100, 100, 400, 400);
//Basic movement and display of character
movement();
character();
timeEnter();
//Updating and moving bullets
for (let i = bullets.length-1; i >=0 ; i--) {
bullets[i].update();
bullets[i].display();
if (bullets[i].x < -50 || bullets[i].x > 650 || bullets[i].y < -50 || bullets[i].y > 650) {
bullets.splice(i, 1);
}
}
//Updating and moving shadows
for (let s = shadows.length-1; s >= 0; s--) {
shadows[s].update();
shadows[s].display();
let remove_enemy = false;
for (let e = bullets.length-1; e >=0 ; e--) {
if (abs(bullets[e].x - (shadows[s].x+25)) < 25 && abs(bullets[e].y - (shadows[s].y+25)) < 25) {
bullets.splice(e, 1);
remove_enemy = true;
}
}
if (remove_enemy) {
shadows.splice(s, 1);
}
}
}
function keyTyped() {
if (key === 'w') {
up = true;
}
if (key === 's') {
down = true;
}
if (key === 'a') {
left = true;
}
if (key === 'd') {
right = true;
}
}
function keyReleased() {
if (key === 'w') {
up = false;
}
if (key === 's') {
down = false;
}
if (key === 'a') {
left = false;
}
if (key === 'd') {
right = false;
}
}
function mousePressed() {
dx = mouseX - 25 - playerX;
dy = mouseY - 25 - playerY;
angle = atan2(dy, dx);
vx = bulletSpeed * cos(angle);
vy = bulletSpeed * sin(angle);
bullets.push(new Bullet(playX, playY, vx, vy));
}
function Enemy(x, y) {
this.x = x;
this.y = y;
this.update = function() {
angleEn = atan2(playerY - this.y, playerX - this.x);
this.vx = cos(angleEn);
this.vy = sin(angleEn);
this.x += this.vx * enemySpeed;
this.y += this.vy * enemySpeed;
}
this.display = function() {
stroke(255);
strokeWeight(4);
fill(0);
rect(this.x, this.y, 50, 50);
}
}
function Bullet(x, y) {
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.update = function() {
this.x += this.vx;
this.y += this.vy;
}
this.display = function() {
ellipse(this.x, this.y, 25, 25);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js"></script>