I have been updating my progress about the collisions and the most difficult part for me was to do the rectangle vs circle overlapping.
The things I have tried are to get the point on the line between two corners of the rectangle that is the closest to the circle using the dot product and a normalized vector and another method using different zones around the rectangle and check if the circle is inside of one of the zones to get the closest point.
The first method using the dot product was difficult at first because I had not practiced this kind of mathematics before, but it was explained to me like this: first I create a vector between the two points on the chosen line. in this case the right edge of the rectangle. Then I normalize the vector so that it points in the direction of this line from the top right corner point to the bottom right corner point.
The dot product is the multipication of two vectors. In this case it was the normalized unit vector and the centre point of the circle. the ‘x’ and the ‘y’ of the two vectors are multiplied together like this: X1 * X2 + Y1 * Y2. The result is a number, not a vector or a point. Then I use the dot product to create the closest point on this line realtive to the centre of the circle. Like this:
U is the unit vector.
P is the bottom right corner point.
Dot is the dot Product.
(U.x * Dot + P.x , U.y * Dot * P.y)
The above is a coordinate with the x coordinate and the y coordinate seperated by a comma ‘,’. This coordinate is the point on the line closest to the centre of the circle.
I don’t quite understand this yet, since I have not studied the mathematics of dot products before.
When I tried to implement the dot product method, the line seemed to be located a little to the right of the rectangle and a little bit below it(there are pictures of this including a picture of the closest point function in a previous post called “more collisions”). I was frustrated about this and after asking the programming teacher about this he said there was another way to find the closest point on the lines, less optimal but easier if you don’t have experience of the dot product.
This way is to divide the surroundings of the rectangle into different zones, differenciated by its corners. This makes 8 zones around the rectangle. If the circle is in the right-hand zone or the left-hand zone, you can use the circle’s y-coordinate to find the closest point on the line because that point has the same y-value as the circle. In the zone under or over, you can use the x-coordinate of the circle instead. In the case of the circle beeing in one of the corner zones, the closest point is the corner.
I thought this would be easy to do so I just deleted my previous attempt using the dot product and started to do this other method instead.
I started with the right-hand side of the rectangle again.
Realizing this is a lot of mathematical raw text I will illustrate the code for the right-hand side check and how that looks in my test window.
This makes a small area of collision, but it is not colliding when it is clearly overlapping. It is only colliding exactly there.
and here is when it is clearly overlapping but not registering any collisions:
I tried around with different values for the overlap check but it just didn’t work.
After a discussion about the origin point of various shapes, I realized I had made an error in setting the circles’ points of origin! SFML’s shape objects such as the circle or the rectangle have built in functions. among them there is a function to set the origin of their shapes. I used this function to set the origin at the centre of the circle. All shapes’ origins are in the top left corner by default. To set a rectangle’s point of origin you want to set it to half the width and half the length. I set the circles by half their radii instead of their whole radii making their centre points a little to the left and above the centre. After I had changed this I tried again, but with the results were not getting much better.
Then I realized that maybe the dot product method did in fact work, only the radii of the circles were not synchronized with the shape of the circle, which made it look like the line was off when it really was at the right place!
There was only one way to try this. I removed the above shown code I had worked with for a few hours and I started from the beginning with the dot product method again. This time the sides of the rectangles collided perfectly from the first try. Needless to say I was relieved.
There was one thing I overlooked at first. When a circle was inside of a rectangle, clearly overlapping it, it did not register an overlap. I had to add another condition to the overlap function which was: If the position of the circle is inside the boundaries of the rectangle, there is indeed an overlap as well.
This means not only is the final artefact I was responsible for this week finished before the pre-alpha, where we were supposed to show our Game Development teacher what we have done so far, but the foundation for the mechanics of the mayor game play is also finished.
The AI and the main player action, which is eating other fish, are dependent on the circle circle and the rectangle circle collisions, or rather their overlap registrations. The circles are meant to attract fish and the rectangle circle overlaps enables the player to eat at attack. Combined with what the others have done, we have almost everything we need to create a working Alpha version of the game, a sort of playable prototype with the main feature(s) of the game.
Here is the final rectangle circle collision code:
Now there is the matter of implementing this to work as it is supposed to.