I down loaded your program, did a little conversion here and there because I am still using Lazarus
2.0.2 with 3.0.4 …
Looking at your methods of detection I would say that you have floating point rounding errors
and you're skipping over a number because you are looking for exact values.. This isn't going
to happen like the way you wish..
What you should be doing is using a 2x2 box test area..
if you use the PtinRect (Point_Int_Rect) you can determine if the current X,Y target is within
the rectangle block
Since you are using floats throughout maybe you could write a PtInRectF function..
I think I have solved the problem.
I modified the code to make it compilable on Linux. I also added an autofire checkbox and bullet speed trackbar. Also, TTimer.Interfal lower than 16 usually is useless, so I changed it to 16.
If you want to compare the source codes, I recommend Meld.
The solution for the issue is to use CompareValue and set a tolerance/delta for it:
https://www.freepascal.org/docs-html/rtl/math/comparevalue.html
I use 0.1 for the tolerance.
Ok, i give up.
Ok, i give up.
Don't give up easily friend.
I'm still inspecting your (previous) code. And I found some interesting things about the bug:
- The bullet jump over issue won't happen if the asteroid is not rotating
- Clockwise and anticlockwise rotation give different results
To better understand what I said, please download the modified code below and do:
Press 'F' to have clockwise rotation and you will see the bullets jump over issue. But if you release the 'F' key then you can see the collision detection works correctly.
Now try to press 'R' to have anticlockwise rotation. If you pay attention you will notice the condition to make the issue appears is different for clockwise and anticlockwise rotation.
Some code should be rewritten to take advantage of readable code and efficiency..
For example
for I := 0 to pLength do with Polygon[ I ] do
begin
// Then address the members directly...
End;
also, as soon as the Result is true a BREAK should be executed to get out of the remaining loop,
this will speed up things.
The reason behind the bug is when the asteroid rotates, sometimes the current and future bullet position end up inside the asteroid. I tried adding LastX and LastY instead of future pos, but the same thing happens.
The reason behind the bug is when the asteroid rotates, sometimes the current and future bullet position end up inside the asteroid. I tried adding LastX and LastY instead of future pos, but the same thing happens.
Then it won't be hard. I simply repeat the collision detection twice, the second one has speed x 2:
//COLLISION DETECTION for I := 0 to EM.Entities.Count - 1 do for J := Low(A.Polygon) to High(A.Polygon) do if LinesIntersect(A.Polygon[J].x1, A.Polygon[J].y1, A.Polygon[J].x2, A.Polygon[J].y2, EM.Entities[I].Pos.X, EM.Entities[I].Pos.Y, EM.Entities[I].Pos.X + EM.Entities[I].xSpeed, EM.Entities[I].Pos.Y + EM.Entities[I].ySpeed, Inter) then EM.Entities[I].Active := False; for I := 0 to EM.Entities.Count - 1 do if not(EM.Entities[I].Active) then Continue else for J := Low(A.Polygon) to High(A.Polygon) do if LinesIntersect(A.Polygon[J].x1, A.Polygon[J].y1, A.Polygon[J].x2, A.Polygon[J].y2, EM.Entities[I].Pos.X, EM.Entities[I].Pos.Y, EM.Entities[I].Pos.X + EM.Entities[I].xSpeed*2, EM.Entities[I].Pos.Y + EM.Entities[I].ySpeed*2, Inter) then EM.Entities[I].Active := False;
Almost perfect, still 1 hidden bug.
Download the code below, run it and hold 'F' key. Only 1 missed bullet in a 360 clockwise rotation.
I'm back and I am sure I have solved the problem. But my solution has a small flaw.
//COLLISION DETECTION for I := 0 to EM.Entities.Count - 1 do for J := Low(A.Polygon) to High(A.Polygon) do if LinesIntersect(A.Polygon[J].x1, A.Polygon[J].y1, A.Polygon[J].x2, A.Polygon[J].y2, EM.Entities[I].Org.X, EM.Entities[I].Org.Y, EM.Entities[I].Pos.X + EM.Entities[I].xSpeed, EM.Entities[I].Pos.Y + EM.Entities[I].ySpeed, Inter) then EM.Entities[I].Active := False;
I added TEntity.Org. Without my explanation, I believe you can guess how it works. But as I already said it has a small flaw.
I am curious to know if the solutions being used here are some of the known ones, as this problem seems to be an age old and must have a big number of solutions. I read the posts, but did not see a hint.There are multiple, but there are also multiple, different implementations of the drawing.
The reason for my question, beside my curiosity, is that I assume there must be a well tested efficient way to solve this problem.