Pathfinding a bullet with bounce mechanism

Working on a top down tank shooter game where bullets can be bounced off of walls once. Im having trouble with the enemy pathfinding ai for when they dont have a direct line of sight to the player, but can hit the player after bouncing off an object (for example to get around a wall).

Im really not sure how to go about doing this, other than with raycasting somehow. I guess i would need to raycast to an obstacle that can be bounced off of, then perform another raycast from there, but how do i find a spot where it will work without bogging down the system checking all possible spots every frame?

That sounds difficult but also fun to try and solve. Are you using the bounce behavior for the bullets? It’s a bit like planning a shot in billiards.

I agree that it could require a lot of resources. It’s all angles though. The first ray cast “ping” would get the wall angle. You could also get the angle between the player and wall or the tank. I just don’t know how that all fits together. It sounds like you have 2 points of a triangle (player and enemy) and need to calculate the 3rd point. I just don’t the formula. It depends on the type of walls.

Are the walls all straight up-down and left-right or are they angled? Can you post a pic of the scene so we can understand the needed math? Maybe also the events used to target/shoot and bounce.

The walls would all be straight up/down and left/right and I’m using the built in bounce behavior. I dont have it in front of me right now, but the firing mechanism is pretty straightforward. Im using a separate object for the turret pinned to the tank object with top down movement in order to rotate the turret independant of the tank body. I am using an extension for the firing behavior.

I was thinking something similar to your triangle idea. If I take the distance between the player and the enemy, cut it in half, then make a triangle with a point along an obstacle, perhaps the angle could be calculated like that and raycasting would only need to be checked once.

Might need to brush up on my trigonometry for this. There is definitely a way to do it mathematically speaking. It should be interesting to solve.

What if instead of raycasting from the enemy tank, do it from certain points (likely bounce targets) and check for line of sight to both the player and the enemy, then find the angle like that… That would be a lot of redundant code though… i know theres an efficient, elegant solution, im just not sure if im smart enough to find it.

Still trying to figure this out.

Have tried:

  • A radar-like scanning system where an invisible object is fired from the enemy at a very high speed and bounced off walls 1x. If the scanning object collides with the player, angle acquired/scan is complete; otherwise, scan object is deleted and another one is fired at angle +1° until player is found or angle variable>360. – this one didn’t work after a little tweaking and i didn’t bother debugging it… it just seems like there would be far too much going on, especially with multiple enemies on screen.

  • Placing invisible target objects at likely bounce points that check for line of sight to player & enemy simultaneously with raycasting, and if true the enemy fires a shot at the target object. Problems: a lot of redundant objects constantly raycasting and low accuracy.

If youre reading this and have any ideas at all please let me know. My game concept pretty much hinges on this mechanism working [well].

I’m probably going to do some googling. I created a quick project to draw the angles but it didn’t help.

Everything is draggable. Fire with space. The slider rotates the tank. I should’ve used different colors for the lines. The trajectory isn’t perfect bc the line isn’t the same as the bullet.
https://games.gdevelop-app.com/game-cf1141c5-f909-4bdd-a8bf-1217d8415e18/index.html

It’s rough and not optomized

Edit: I thought I fixed this bug but the line drawn 90° using the center point between the objects is off, I put in centerY twice. The dangers of copy/paste. It doesn’t matter. That line didn’t seem to help me unless the line was level.

Wow, thank you for going so far to help! Im about to try it out now.

It’s not really helping me figure this out. I tried using the player location to sort of ping the walls and then draw a bounce from there but that doesn’t really help me either. It’s sort of like shooting in reverse. My thought was to somehow drive the tank to a point on the path. IDK. There’s probably some easy formula but I’m not seeing it. The more complicated it gets the more resources it will use.

I wonder if it would be possible to draw the lines like in the app you uploaded, then at certain intervals do a full rotation to sort of “scan” the environment and stop if the lines intersect with the player?

I also feel like there’s some simple solution but I’m new to gdevelop and haven’t coded anything in a few years.

I added your code to my project, and I cant quite figure it out. When the line from the tank hits a horizontal wall it is reflected correctly, but when it hits a vertical wall the angle is wrong and it also goes through to the other side instead of reflecting off of it.

I’m not sure what the line drawn perpendicular from the center of the direct line from the player to the tank is for.

If I could just get it to draw the line from the enemy towards the angle its facing (according to its angle, which would be modified by other events) and then draw another line from the collision point to the proper angle, then check for a collision with that line and the player (while ending the line if it hits another obstacle). I think that’s what would make it work.

I definitely don’t have the understanding of trigonometry for this, but I’m going to catch up on that and study this code you’ve given me further.

I drew the extra lines looking for a pattern or a formula. It didn’t help. I’m not at my PC. I will be later and I can check the bounce math. I just wanted to try to get one surface to work as a test of the concept. I’ll see if it works on any wall. You could cast a ray instead of drawing a line as q way to check for rhe player. The line is just a visual aid.

I’m not good with trig either but I can make formulas work even when I don’t understand why they work. I just can’t find the right principle or formula. It probably involves solving for more than just one triangle.

This version needs work but the math is there. I tried to use a test bullet to adjust for the size of the bullet with the bounce. Separate objects isn’t the same as a bounce. It probably should just use math but that would require XFromAngleAndDistance(),YFromAngleAndDistance() instead of just angles.

Anyways, here’s my current project. I added a turret, it has a point on the tip. I added a group with the wall and player. I also added the sticker behavior to the turret.

try it:
https://games.gdevelop-app.com/game-9ef9252d-b155-4164-bb6a-c4cfbc7e9f5b/index.html

Edit: there has to be an easy way to calculate a bounce point. I tried using ChatGPT but it was wrong every time. It wasn’t even close.

Wow, you got it! Ill be very interested to get a closer look at how you did it later. I really appreciate your help!

1 Like

I modified the code to skip using a test bullet. The test bullet was a quick fix that didn’t really work. Instead, it calculates the distance (dist) to the wall and then subtracts 8 (half the size of the bullet)

This defiantly follows the path better. It would be better if I used a round bullet and collision mask.
https://games.gdevelop-app.com/game-22229c1e-86a7-4fc6-ab82-e9f7a01bc77d/index.html

1 Like

I finally got it to work just now. Even after i got the events right, it didn’t completely work until i went to the scene and changed the angle of the wall (in its properties) and the shape of the walls on the map. Rookie mistake on my part, probably.

1 Like

I knew to keep eye on this topic
And now i can make billiard game with guide lines
Bless you Keith

1 Like

Yes, that was part of the concept. An action similar to billiards. It should be expandable beyond 2 lines although I never tried to.

1 Like

I was able to create an expression that sort of refills itself once it has an initial value. The expression variables should probably be changed to make sure there’s no conflict but otherwise it seems to work pretty well. It doesn’t use the size of the object though, so it might clip something.

I added a 2nd slider to set the number of bounces.
https://games.gdevelop-app.com/game-3919f3f6-7c7a-402e-967f-e7ad63226a35/index.html

source:

Edit: quick change to the number of bounce count.

1 Like

You have no idea how this gonna help me in making billiard game
THX a lot

You’re welcome. It’s not super accurate with the current collision mask but the concept is good. It needs some tweaking.

Edit: I changed the concept. This is a separate repository. I noticed the ends weren’t being calculated. I changed the extension to check the position of the point and adjust the angle.

source: all wall objects need to be at zero degrees rotation for this version

edit: there’s still “dead spots” I don’t know why. It just stops drawing lines. I look at it later.

1 Like