• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Mac OSX Collision Line facing a certain direction

U

Ufy

Guest
Okay, some context: I want to create a prototype of a Plants vs Zombies clone. And what I want is for the towers/plants to shoot, only if there is an enemy in front of it. I can't use the normal collision line code, since it looks like this:

My desired collision line:

Or perhaps there are other methods which I could use?
 
C

CedSharp

Guest
Okay, some context: I want to create a prototype of a Plants vs Zombies clone. And what I want is for the towers/plants to shoot, only if there is an enemy in front of it. I can't use the normal collision line code, since it looks like this:

My desired collision line:

Or perhaps there are other methods which I could use?
You can actually use the collision_line script, you're probably just using it wrong.
If you use it with something like instance_nearest, then that's why it's not working as you expect.
When defining the line position, try defining it from the 'tower' to the end of the room on the right.
Then, you'll realize that it'll shoot better, with one issue: it won't necessary shoot the closest enemy.

Another solution is to use raycasting. Big word for a simple thing: use collision_point in a for loop that goes from your tower to the right of the room.
The first enemy that matches will obviously be the closest!

I can write you an example code if you need, but I really thing this is a simple thing :)
 

TheouAegis

Member
Except for a few different types of plants, you don't even need a collision line. I mean, for a peashooter which can only shoot down its Lane and will only hit the nearest enemy in its Lane, all you need to do is Loop through every zombie, compare its y-coordinate to that of the plant and then compare the distance to the plant with the distance to the plant of the other zombies in the same y coordinate.
 
C

CedSharp

Guest
Except for a few different types of plants, you don't even need a collision line. I mean, for a peashooter which can only shoot down its Lane and will only hit the nearest enemy in its Lane, all you need to do is Loop through every zombie, compare its y-coordinate to that of the plant and then compare the distance to the plant with the distance to the plant of the other zombies in the same y coordinate.
Definitely a more optimized version of doing it. But then instead of having instances in the room you could have a simple controller object that holds the position of everyone in a grid and just draw stuff in the draw event...
I'm joking, but yeah, you can check if a zombie is in the same 'row' using it's y position, and then check if it is close enough using it's x position. That would be the dead-easy method of doing it.
 
U

Ufy

Guest
thanks guys, but I just did
if(collision_line(x,y,room_width,y, oEnemy, false, true))
which was more simple, and it works lolol
 
C

CedSharp

Guest
thanks guys, but I just did
if(collision_line(x,y,room_width,y, oEnemy, false, true))
which was more simple, and it works lolol
That's literally what I told you to do :)

CedSharp said:
When defining the line position, try defining it from the 'tower' to the end of the room on the right.
 

TheouAegis

Member
thanks guys, but I just did
if(collision_line(x,y,room_width,y, oEnemy, false, true))
which was more simple, and it works lolol
Okay, originally I was going to say something, but then I retracted my statement because in a PvZ type of game, the first zombie created in a certain row would be the closest to a plant in that row.

Except that's not always the case. For example, a zombie hit by a Frozen Peashooter will slow down (or halt) and meanwhile another zombie can come up from behind it and pass the frozen zombie by. Since the frozen zombie is the oldest one, it will continue to be attacked by all the plants in that row while the zombie closest to the plants remains untargeted.

And that's one reason collision_line is a bad option.
 
C

CedSharp

Guest
Okay, originally I was going to say something, but then I retracted my statement because in a PvZ type of game, the first zombie created in a certain row would be the closest to a plant in that row.

Except that's not always the case. For example, a zombie hit by a Frozen Peashooter will slow down (or halt) and meanwhile another zombie can come up from behind it and pass the frozen zombie by. Since the frozen zombie is the oldest one, it will continue to be attacked by all the plants in that row while the zombie closest to the plants remains untargeted.

And that's one reason collision_line is a bad option.
How is collision_line a bad option? It wouldn't get the closest enemy, the doc specifically mentions that it returns ONE of the collided instance IN NO SPECIFIC ORDER.
You have to handle it differently if you want to know which is the closest enemy.

But I think in his situation he just wants to shoot if a zombie is present at all, not targeting the closest one necessary.
So collision_line works fine in this scenarion.
 

TheouAegis

Member
Actually there is a specific order, and that order is what breaks it. You need it to be the enemy that is closest to the turret. The collision_line function in and of itself is not necessarily bad, but when used in a situation like this it is not adequate. 90% of time it would work because 90% of the time the zombie closest is also the oldest in that lane. But the point of the turret is to attack the nearest enemy in its row, not just any enemy that happens to be there.

Actually, it's going to fail on him more frequently than just 10% of the time, possibly. I just remembered that one of the enemy mechanics in PvZ is some enemies can switch lanes while they are walking. So now you could have a slow enemy walking down the middle lane and then it changes to the Top Lane. Meanwhile you have a fast enemy in the Top Lane that spawned later. None of the turrets in the Top Lane would be able to attack the faster, closer enemy because the slower enemy is older and would be targeted instead.

And even if the function goes after the newest instance rather than the oldest, the situation would still be the same. There would exist a scenario in which the enemy would become temporarily invincible simply by walking past another enemy or changing lanes. So early on in his game designing training, the function would suffice, but as soon as he starts implementing actual challenges to the game play, then it will no longer be adequate.
 
Top