CollideLine, how ignore certain entities?


(John Andersson) #1

Okay, so I am making a death star replica (go star wars) and I want it to fire its awesome laser. If other death stars cross the laser’s path, then they will get blown up. The problem is that collideLine only accounts for the first entity hit in the line, and because the death star has the same type as the other death stars (must be this way), it will register itself as the first entity hit with the collideLine function. The line starts from the death star’s center and goes in a random direction.

/*All of this code is in the laser.as*/

//The creator is set as the death star creating this laser
var creator:DeathStar = DeathStar;

//Find the first collided entity in a line
var ds:DeathStar = DeathStar(FP.world.collideLine("deathstar", creator.x, creator.y, targetX, targetY));
if (ds != null)
{
    //Blow up the collided death star with damage and acknowledge who the creator was
    ds.blowUp(damage, creator);
}

Now if I could just ignore the creator with something like

if (ds != null && ds != creator)
{
    //Blabla
}

then life would be great. But since collideLine still only registers the creator as the only entity hitting the line, even if it doesn’t damage the creator, it won’t check for collisions with other entities.

Now a possible solution would be to make an alternative to collideLine, something like collideLineInto (like there is for collideRect and collideRectInto), but after trying to make a function like that for around 1 hour now, I am still at step 1. The easiest solution would be to ignore the creator entirely with the collideLine function and then only check for one collision in the line, since I only want to blow up one death star at a time anyway.

Any ideas?


(John Andersson) #2

I found a pretty OK solution to this; simply displacing the laser from the death star’s center, depending on the angle of the death star.

var ds:DeathStar = DeathStar(FP.world.collideLine("deathstar", creator.x + displacement * Math.cos(angle * FP.RAD), creator.y + displacement * Math.sin(angle * FP.RAD), originTargetX, originTargetY));

But that doesn’ t really solve my problem in the way I want it, though


(Jean) #3

It’s a very stupid suggestion, but you could try instead of FP.world.collideLine("deathstar", creator.x, creator.y, targetX, targetY)

make

FP.world.collideLine("deathstar", targetX, targetY, creator.x, creator.y)

If it returns the creator then it hit nothing. Also, if you want to make detect ALL of the “death stars” that the laser got, you can do a

ds = DeathStar(FP.world.collideLine("deathstar", targetX, targetY, creator.x, creator.y));
while (ds !== creator){
  //handle hit on death star
  ds = DeathStar(FP.world.collideLine("deathstar", ds.x, ds.y, creator.x, creator.y));
}

(Jean) #4

OK now the explanation of what the code does:

The first step will start from the end of the laser going back to the creator, so you can get all the other entities before reaching the creator.

(assume red dots as enemy deah stars, green as the lazor and the black dot as the creator)

It found the first red dot, so now that I know that the farthest deah start is here, I will kill this entity and continue my collideLine from its origin(note that you remove the entity of the world, make sure to save it’s coordinates)

And then I repeat the process, since he death start I found isn’t the creator.

And done, you have detected all the colisions until you got the creator. (sorry for the paint bad-quality images)


(John Andersson) #5

Excellent! Never thought of going backwards. :slight_smile: