Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Discussion / Bullet collision help

Author
Message
Hangar18
17
Years of Service
User Offline
Joined: 13th Mar 2007
Location:
Posted: 18th Jun 2009 05:24 Edited at: 18th Jun 2009 05:27
I have found a long winded work around to this problem but was wondering if anyone else can offer a better solution. The problem is this

Some of my bullets travel so fast that they are going right through the intended target without registering a hit. And this is particularly so if youre right up close and personal to the target as the following code attempts to show.



Now I could increase the dist# condition from 100 to 1000 but the problem with that of course is it means you can be way off to the left or right and it still hits. The only other options I can think of are:

1. Setting up a condition that checks if the bullet position at the start of the next loop is further away that its last distance check. E.g.



2. Using DBs collision command might work but its so slow its not really an option

Any advice on this would be greatly appreciated.
TheComet
16
Years of Service
User Offline
Joined: 18th Oct 2007
Location: I`m under ur bridge eating ur goatz.
Posted: 18th Jun 2009 09:11 Edited at: 18th Jun 2009 09:11
What you can do is use a for to loop. So, lets say the bullet travels at the speed 40. Instead of saying
, you can use:



Make sure you do the collision check inside the loop.

Or you can use sparky's collision dll, and cast a ray from the old position of the bullet to the new position.

TheComet


Make the path of your enemies easier with Waypoint Pro!
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 18th Jun 2009 09:50 Edited at: 18th Jun 2009 09:54
If you aren't goint to use sparkys or DBC collision you can still use your distance check. I think you are on the right track. I think the only problem with your first version is that you aren't starting out at the gun barrel where bullet x,y =0. You are starting bullet+speed unit ahead of the bullet (also make sure you are using # after each variable as you decalred them above. I changed it for this



try:



Avoid putting the bullet in it's own loop (sorry TheComet) because if several entitys are firing at once, the whole program has to wait for each bullet to run through a separate loop instead of all bullets moving simulataneously based on the main loop's iterations. Assumingly, the bullet moves a certain speed each iteration of the main loop, so there are many options.

If you don't want to calculate an instantaneous hit, which some would argue a bullet travels so fast you can't see it so therefore why even move it each iteration; but maybe you want to see it or maybe have a character try to move out of the way, whatever the case here's another option:

Assumingly you already have a means of finding out if the bullet is pointed in the right direction towards the target. Find the distance to the target. Divide that distance by the speed of the bullet. If you don't want to use sqrt, then divide the squared distance by the squared speed of the bullet. This is how many iterations it'll take to get to the target.

Keep count of the iterations each main loop for the bullet. When it reaches the iteration count you calculated, check if the target is in the same position or within a certain amount of units of that position or the bullet's position, if so, you have a hit. This way you don't have to figure out where the bullet is each loop. You just figure out how long it would have taken to get to the target (iteration wise) and if the target isn't there, then no hit.

Enjoy your day.
Libervurto
17
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 18th Jun 2009 14:11
what if the bullet is going the opposite direction?

There is an eight letter word. You can insert a letter into it or remove a letter from it without changing its meaning. Answer
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 18th Jun 2009 15:18
Quote: "what if the bullet is going the opposite direction?"

Theory is still the same. You have to compensate from a central location.

Quote: "Assumingly you already have a means of finding out if the bullet is pointed in the right direction towards the target. Find the distance to the target. Divide that distance by the speed of the bullet. If you don't want to use sqrt, then divide the squared distance by the squared speed of the bullet. This is how many iterations it'll take to get to the target"


This also assumes you are moving the bullet toward the target. The distance and the hit is just a calculation independent of where the object bullet is. It's not the complete bullet code it's the calculation of the speed of the bullet to the target - hit or miss. For the complete bullet code you'd have to have place holders for bullet life, current position, last position, object (if its 3d) etc.

Enjoy your day.
Libervurto
17
Years of Service
User Offline
Joined: 30th Jun 2006
Location: On Toast
Posted: 18th Jun 2009 18:48
@Latch
Yeah I understand that, quite clever using squares like that so it is always a positive. Is that the only reason you used them, why not use ABS?
What I meant was what if the bullet isn't going to hit the target but it's close enough that it could in the next iteration if it WAS going towards it. Sorry for the long winded explanation.
I was trying to work it out on a piece of paper but I'm having a mental block. I could just be seeing a problem that doesn't exist lol

There is an eight letter word. You can insert a letter into it or remove a letter from it without changing its meaning. Answer
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 18th Jun 2009 22:39
Quote: "Yeah I understand that, quite clever using squares like that so it is always a positive. Is that the only reason you used them, why not use ABS"

It's the distance formula without the sqrt. That's even what Hangar18 was using in the first example, that's also why I assumed the direction had already been taken care of in code we weren't given. It's always positive because the distance is always positive.

Quote: "What I meant was what if the bullet isn't going to hit the target but it's close enough that it could in the next iteration if it WAS going towards it. Sorry for the long winded explanation"

If you divide the distance to the target by the speed of the bullet and it's less than 1 (i.e. less than 1 iteration) it's an immediate hit. It depends on what you want to do. If the distance / speed came out to say 1.5, that means the bullet would reach the target before a complete 2nd iteration. So the target has only 1 iteration to get out of the way. So on the second iteration it's a hit if the target didn't move on the first iteration. If the dist/speed was 2.1, the target has 2 whole iterations to get out of the way. If it's not out of the way by the end of the 2nd iteration, it's a hit on the 3rd iteration.

It all depends on how one wants to handle it. You could truncate the decimal and just use the whole iteration numbers. 1.5 means a hit on the next iteration. 2.1 means a hit on the 2nd iteration from now. 4.7 means a hit on the 4th iteration. Or you could round the value. However you want to handle it.

If we aren't using collision, when it was the iteration that was supposed to be the time of the hit, compare the bullet position with the target position +- the target's size on each axis. Abs() would come in handy there. It's not a perfect system, but it's pretty quick and probably accurate enough.

For arguments sake, the direction of the bullet would be in 2d; assigning only 1 speed to the bullet:


So after the iteration count, 'it', truncated, compare bendx and bendy with the target's new position.

Enjoy your day.
Zero G Scott
16
Years of Service
User Offline
Joined: 14th Dec 2007
Location: California, USA, Earth, Sol Sys
Posted: 18th Jun 2009 23:21
How convenient all this bullet talk is happening when I'm looking into getting some bullets code going. Nice stuff!
Hangar18
17
Years of Service
User Offline
Joined: 13th Mar 2007
Location:
Posted: 19th Jun 2009 03:19 Edited at: 19th Jun 2009 03:21
Thanks Latch!! I used a bit of a hybrid method in the end because when the target is a long way off and moves closer/further away the initial time calculation might not be valid by the time the bullet gets in the vicinity of the target. I dont have the code I used at my actual work computer (where I am now) but broadly what I did was...

- store the distance^2 (ie without using sqrt) from me to the target: this in fact already gets calculated as part of a radar check so no new calc needed here
- store the distance^2 from the bullet just fired, to me (nb. not the target)
- the point at which the 2nd stored distance^2 exceeds the 1st one, then I know the bullet has just passed the target (and hasnt hit or it would have already been taken care of via another subroutine)
- if at this point, the distance between bullet and target is substantially bigger than the 100 in my original code (e.g. >150), then there's basically no hope for the bullet to have hit the target so stop here and save on time.
- if not, then do as latch suggested and subtract the 1 full speed iteration from the bullet's current projection, and then
1) do a while / endwhile routine not a for i / next i (will explain why in a mo)
2) store a flag=1 so that next time the bullet routine gets here it wont go through the loop below again.



That way, if the bullet hits after the first or second turn, it doesnt have to run through the remaining 3 or 4 loops that it would in a for/next loop.

Also if I'm facing the opposite way to the target and fire, then the condition will get checked first iteration (and bypassed because the distance check will show the bullet is miles from where it needs to be).

And yes I didnt use actual distance (with sqrt) because of its speed issue. I had to redo alot of my game a while ago and found that not using sqrt really does make a difference.
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 19th Jun 2009 05:59
Quote: "Thanks Latch!! I used a bit of a hybrid method in the end because when the target is a long way off and moves closer/further away the initial time calculation might not be valid by the time the bullet gets in the vicinity of the target. I dont have the code I used at my actual work computer (where I am now) but broadly what I did was"


You're right about moving forward or backward. I was only thinking side to side dodging. But I still don't like the loop within loop stuff for bullets. So to try and save something of my suggestion, to adjust, don't calculate out the whole iteration time. Use one bullet speed (not x and y) and calulate the bullet x and y position with the code I posted earlier with the iteration automatically increasing until there's a hit or the bullet reaches a max distance where tx=targetx and ty=targety. The only reason to have tx and ty in this case is because I want to find an angle to the target. Otherwise, I would use an angle that the gun was pointing. And to be sure that the bullet didn't pass the target by because of the big leaps in position by bspd#, I would measure the distance from the previous bullet position to the target and from the current position to the target. If either of those positions are in range of the target, it's a hit:



And yes newzvalue is deliberate for the y calculation.

Enjoy your day.
Hangar18
17
Years of Service
User Offline
Joined: 13th Mar 2007
Location:
Posted: 19th Jun 2009 08:06
Thanks - the angle thing is a good idea! Just one question though, is DB slow when it comes to computing angles and inverse angles. My hunch is that if its slow with SQRTs and the like it might also be slow with anlges?
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 20th Jun 2009 01:07
I ran some benchmarks a few years ago and newxvalue, newyvalue,newzvalue were faster than their trig cousin functions. Test it out and see if it's within your desired specs. Test out atanfull() as well. You may be able to skip the atanfull() if you are just using the built in 3d rotation commands and you can just grab the angle with object angle y() etc.

Enjoy your day.

Login to post a reply

Server time is: 2024-05-20 12:02:59
Your offset time is: 2024-05-20 12:02:59