PDA

View Full Version : Problem with collision detection



IroncrossBG
15-06-2019, 12:26 PM
Hello everyone, im new to the forum https://forum.lazarus.freepascal.org/Smileys/ExcellentSmileys1/smile.gif

So, im trying to recreate the original Asteroids game and im having a bit of a problem with my collision detection. I have an asteroid polygon made from lines which are made from float TPoint. The way my collision works is every tick, i make a line between the current bullet position and the future bullet position (x + xSpeed, y + ySpeed) and then check if an asteroid line intersects it and then destroy the bullet. But for unknown reasons to me, some of the bullets jump over the asteroid line and no collision occurs. Any ideas? i have attached my project as a zip, it's written in Delphi 10.3.

Project file: https://gofile.io/?c=HJIyHW

klausvdl
16-06-2019, 07:17 AM
// 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
begin
EM.Entities[I].Target := Inter;
EM.Entities[I].Pos := Inter;
end;


If the bullet is fast and the polygon small then the bullet could perhaps pass 2 lines of the same polygon within 1 tick: the bullet enters and leaves the polygon. In this case you get 2 results from LinesIntersect within that loop. But the first result alters EM.Entities[].Pos and replaces it with Inter. So the following result works with the wrong position. This could be the problem.

IroncrossBG
16-06-2019, 09:45 AM
Decided to ditch this part of the code and just use Point in Polygon(PNPoly) function.



// 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
begin
EM.Entities[I].Target := Inter;
EM.Entities[I].Pos := Inter;
end;

The collision detection above works nicely with non-moving objects, but once they start moving or rotating, it's done. When the asteroid moves, it's lines jump over the last or future position of the bullet, the bullet just passes and the check fails. The PNPoly function also works nicely with really fast moving objects, unless the speed is higher than the asteroid diameter itself.
Here is the PNPoly function i have if anyone finds it useful:


function PNPoly(X, Y: Double; Polygon: array of TPointF): Boolean;
var
I, J, pLength: Integer;
C: Boolean;
begin
pLength := Length(Polygon) - 1;
J := pLength;
C := False;
for I := 0 to pLength do
begin
if ((((Polygon[I].Y <= Y) and (Y < Polygon[J].Y)) or
((Polygon[J].Y <= Y) and (Y < Polygon[I].Y))) and
(X > (Polygon[J].X - Polygon[I].X) * (Y - Polygon[I].Y) /
(Polygon[J].Y - Polygon[I].Y) + Polygon[I].X)) then
C := not C;
J := I;
end;
Result := C;
end;

Does anybody how i can find the collision point between the bullet and the polygon with the function above? I still have the LastX and LastY of the bullet, and i tried to check for Line Intersect between the current Bullet pos and last Pos, but it fails if last Pos is inside the asteroid...

davido
19-07-2019, 02:05 PM
I think you had to start the configuration again from the beginning.

_______________________________________
SHAREit (https://shareit.onl/) MX Player (https://mxplayer.pro/)

Jonax
04-08-2019, 07:53 PM
Perhaps you could view your bullets at quantum bullets. Sometimes they're there, sometimes not. Make a feature out of the 'bug'.

Just kidding of course. Don't know if this is helpful but when I make simple games involving collision detection I make my moving objects round and use the Pythagoras to calculate distance between objects' centers and then compare to sum of radius. Works must of the time unless when I mess up code.

Good luck.

pitfiend
21-08-2019, 07:49 PM
in which order do you check the collision? does the asteroid check first or the bullet? I suggest you put your collision detection on the fastest object. also, if the bullet is inside the polygon take it as a collision, even if it didn't hit any lines in between movement positions. that should resolve your troubles.

EDIT: another thing to have in mind. bullets and asteroids don't dodge each other, they follow straight paths. so, if from one frame to the next, the bullet position cross the path of an asteroid, it's a hit too even if they didn't hit due to small sized asteroid.

Ñuño Martínez
29-08-2019, 11:38 AM
EDIT: another thing to have in mind. bullets and asteroids don't dodge each other, they follow straight paths. so, if from one frame to the next, the bullet position cross the path of an asteroid, it's a hit too even if they didn't hit due to small sized asteroid.
If so, then linear algebra can be used to detect if two trajectories crosses (line v line), or if the bullet trajectory collides with the asteroid (line v circle, line v ellipse or line v rectangle).