Reputation: 163
I am new to stack and not quite sure how to use it. But here I am. I am working on a ecosystem project, and I have an animal class with 2 different genders(0 for female, 1 for male). When 2 different genders intersect each other than I want to remove those 2 objects and add a couple(different object, static) object on that position. I kinda did it but it only works for a couple of seconds. Then the code just breaks. In the console it says, “Uncaught TypeError: Cannot read property ‘intersects’ of undefined”
Here's the question on the processing forum in case I get a solution which might help others: https://discourse.processing.org/t/multiple-object-intersection-and-removal/22900/2
Here's the sketch.js file:
var animats = [];
var couples = [];
function setup() {
frameRate(30);
createCanvas(displayWidth, 470);
for(var i = 0; i < 50; i++)
{
animats[i] = new Animat(random(0, width), random(0, height));
}
}
function draw() {
background(255,100,100);
for(var i = animats.length-1; i >= 0; i--) {
animats[i].birth();
animats[i].grow();
for(var j = i; j >= 0; j--) {
if(j != i && animats[i].intersects(animats[j])) {
animats.splice(i, 1);
animats.splice(j, 1);
}
}
}
}
Here's the animat class file:
function Animat(x, y) {
this.x = x;
this.y = y;
this.gender;
var g = random(0,1);
var c;
if(g > 0.5) {
c = 0;
this.gender = 0;
} else {
c = 255;
this.gender = 1;
}
this.speed = 1;
this.age = 0;
this.length = 0.5;
this.birth = function() {
//gender
//create
noStroke();
fill(c);
text("n", this.x, this.y, this.length, this.length);
ellipse(this.x, this.y, this.length * 2, this.length * 2);
//move
switch(floor(random(0,4))) {
case 0:
this.x += this.speed;
break;
case 1:
this.y += this.speed;
break;
case 2:
this.x -= this.speed;
break;
case 3:
this.y -= this.speed;
break;
default:
this.x++;
this.y--;
}
//bounce
if(this.x > width || this.x < 4){
this.speed *= -1;
}
if(this.y > height || this.y < 4){
this.speed *= -1;
}
}
this.grow = function() {
this.age += 0.01;
this.length += 0.05;
//age checks
if(this.age > 10) {
this.speed + 5;
} else if(this.age > 21) {
this.length = 25;
this.speed = this.speed
//console.log("max age:" + this.age)
} else if(this.age > 70) {
//die
} else {
}
//length checks
if(this.length > 25) {
this.length = 25;
//console.log("max length");
}
}
//relationship
this.intersects = function(other) {
var d = dist(this.x, this.y, other.x, other.y);
var r = this.length + other.length;
if(d < r) {
if(((this.gender == 0) && (other.gender == 1)) || ((this.gender == 1) && (other.gender == 0))) {
return true;
} else {
this.speed *= -1;
}
} else {
return false;
}
}
//mate
this.couple = function() {
if(((this.gender == 0) && (other.gender == 1)) || ((this.gender == 1) && (other.gender == 0))) {
return true;
} else {
this.speed *= -1;
}
}
//die
/*this.die = function() {
if(this.age > 50) {
return true;
} else {
return false;
}
}*/
}
Here's the codepen link for results I am getting: https://codepen.io/AbrarShahriar/pen/XWXwLPM
Upvotes: 1
Views: 255
Reputation: 1144
Try changing your nested for loop to:
for (var i = animats.length - 1; i >= 0; i--) {
animats[i].birth();
animats[i].grow();
for (var j = i; j >= 0; j--) {
if (j != i && animats[i].intersects(animats[j])) {
animats.splice(i, 1);
animats.splice(j, 1);
break; //exit the inner loop after a match
}
}
}
In other words, add a break;
after two animats
have coupled and have been removed from the array. The error was probably caused by you trying to call the intersects
method of an animat
that had already been removed.
Upvotes: 2
Reputation: 4847
you need to keep animats[i]
as long as the for-loop for j
has not finished.
Here the code you need to fix:
for(var i = animats.length-1; i >= 0; i--) {
animats[i].birth();
animats[i].grow();
let remove = false; // mark 'i' as NOT REMOVE by default
for(var j = i; j >= 0; j--) {
if(j != i && animats[i].intersects(animats[j])) {
remove = true; // mark 'i' as to remove when collision detected
animats.splice(j, 1);
}
}
if (remove) { // remove 'i' after compared to all 'j'
animats.splice(i, 1);
}
}
Upvotes: 1