You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Tutorial - Building 2D Games - Fix circle collision math and a few typos. (#138)
* Fix circle collision math and a few typos.
The circle collision explanation and code sample were incorrect.
The Circle class is implemented correctly later in this chapter (see ./snippets/cirlce.cs#methods_intersects).
* Add back "Since this forms a right triangle,"
* Use * instead of _
* Switch circle radii back to 5
* Corrections
---------
Co-authored-by: Simon (Darkside) Jackson <[email protected]>
Copy file name to clipboardExpand all lines: articles/tutorials/building_2d_games/12_collision_detection/index.md
+29-29Lines changed: 29 additions & 29 deletions
Original file line number
Diff line number
Diff line change
@@ -16,7 +16,7 @@ In this chapter you will:
16
16
We will first start by understanding the basics of collision detection and the different approaches that can be used.
17
17
18
18
> [!NOTE]
19
-
> There is a lot to understand when it comes to collision detection and the many complex ways that two objects can be considered IN collsion or NEAR collision. It is critical to get an understanding of the basics before jumping into code. So buckle up, we have a story to tell before you can get back to the keyboard.
19
+
> There is a lot to understand when it comes to collision detection and the many complex ways that two objects can be considered IN collision or NEAR collision. It is critical to get an understanding of the basics before jumping into code. So buckle up, we have a story to tell before you can get back to the keyboard.
20
20
>
21
21
> Feel free to keep coming back to this chapter and refer to the content when you need to, with a fresh cup of coffee.
22
22
@@ -34,36 +34,36 @@ Shaped based collision detection checks if two shapes overlap. The most common
34
34
35
35
#### Circle Collision Detection
36
36
37
-
Circle collision detection is computationally a simpler check than that rectangles. There are also no special considerations if the circles are rotated, which makes them easier to use. To determine if two circle shapes are overlapping, we only need to check if the square of the sum of the radii between the two circles is less than the squared distance between the two circles with the following formula:
37
+
Circle collision detection is computationally a simpler check than rectangles. There are also no special considerations if the circles are rotated, which makes them easier to use. To determine if two circle shapes are overlapping, we only need to check if the square of the sum of the radii between the two circles is less than the squared distance between the two circles with the following formula:
38
38
39
-
Two find the distance between two circles, imagine drawing a line from the center of one circle to the center of the other. This length of this line is the distance, but we could also calculate it by first walking up or down and then walking left or right from the center of one circle to another, forming a right triangle.
39
+
To find the distance between two circles, imagine drawing a line from the center of one circle to the center of the other. The length of this line is the distance, but we could also calculate it by first walking up or down and then walking left or right from the center of one circle to another, forming a right triangle.
40
40
41
41
||
If it is less, then the circles are overlapping; otherwise, they are not.
59
+
It is easy to confuse the direction of the inequality sign. As a quick mental test, think of how the math works when the origin of two circles are at the same position, i.e., when the *squared distance* is zero.
60
60
61
-
To calculate the squared distance between to points, MonoGame provides the [**Vector2.DistanceSquared**](xref:Microsoft.Xna.Framework.Vector2.DistanceSquared(Microsoft.Xna.Framework.Vector2,Microsoft.Xna.Framework.Vector2)) method:
61
+
To calculate the squared distance between two points, MonoGame provides the [**Vector2.DistanceSquared**](xref:Microsoft.Xna.Framework.Vector2.DistanceSquared(Microsoft.Xna.Framework.Vector2,Microsoft.Xna.Framework.Vector2)) method:
62
62
63
63
[!code-csharp[](./snippets/vector2_distance.cs)]
64
64
65
65
> [!TIP]
66
-
> MonoGame also provides a distance calculation method with [**Vector2.Distance**](xref:Microsoft.Xna.Framework.Vector2.Distance(Microsoft.Xna.Framework.Vector2,Microsoft.Xna.Framework.Vector2)) which returns the distance by providing the square root of the distance squared. So why do not we use this instead?
66
+
> MonoGame also provides a distance calculation method with [**Vector2.Distance**](xref:Microsoft.Xna.Framework.Vector2.Distance(Microsoft.Xna.Framework.Vector2,Microsoft.Xna.Framework.Vector2)) which returns the distance by providing the square root of the distance squared. So why not use this instead?
67
67
>
68
68
> Square root operations are more computationally complex for a CPU. So instead of getting the normal distance, which would require the square root operation, it is more efficient for the cpu to multiply the sum of the radii by itself to get the squared sum and use that for comparison instead.
69
69
@@ -113,14 +113,14 @@ Implementing SAT is out-of-scope for this tutorial. If you are interested in fur
113
113
114
114
#### Choosing a Collision Detection Method
115
115
116
-
When determining which collision detection method to use, you should start with the simplest one that meets the needs of your game. If distance checks work for your game mechanic, there's no need to implement more complex shape based detections. Similarly, if a circle can represent the bounding area of a game object, start with that before moving onto rectangles.
116
+
When determining which collision detection method to use, you should start with the simplest one that meets the needs of your game. If distance checks work for your game mechanic, there's no need to implement more complex shape based detections. Similarly, if a circle can represent the bounding area of a game object, start with that before moving on to rectangles.
117
117
118
118
Some other points to consider are
119
119
120
120
- Circles:
121
121
- Better for round objects like balls and coins.
122
122
- More accurate for rotating objects.
123
-
-Simpler check for overlap than rectangles.
123
+
-A simpler check for overlap than rectangles.
124
124
- Rectangles:
125
125
- Great for walls, platforms, and most game objects.
126
126
- Easy to visualize and debug.
@@ -137,7 +137,7 @@ A blocking collision response is the most basic response which just prevents the
137
137
1. Store the location of an object calculating the new location to move it to.
138
138
2. Check if it is overlapping an object at the new location:
139
139
140
-
- If it is overlapping, then set the position to the the position before it was moved.
140
+
- If it is overlapping, then set the position to the position before it was moved.
141
141
- If it is not overlapping, set the position to the new calculated position.
142
142
143
143
For example:
@@ -174,9 +174,9 @@ For example:
174
174
175
175
#### Bounce Collision Response
176
176
177
-
For games that need objects to bonce off each other (like a the ball in a Pong game), we need to calculate how their velocity should change after the collision. MonoGame provides the [**Vector2.Reflect**](xref:Microsoft.Xna.Framework.Vector2.Reflect(Microsoft.Xna.Framework.Vector2,Microsoft.Xna.Framework.Vector2)) method to handle this calculation for us. The method needs two pieces of information:
177
+
For games that need objects to bounce off each other (like the ball in a Pong game), we need to calculate how their velocity should change after the collision. MonoGame provides the [**Vector2.Reflect**](xref:Microsoft.Xna.Framework.Vector2.Reflect(Microsoft.Xna.Framework.Vector2,Microsoft.Xna.Framework.Vector2)) method to handle this calculation for us. The method needs two pieces of information:
178
178
179
-
1. The incoming vector (the direction something is moving).
179
+
1. The incoming vector (the direction that something is moving).
180
180
2. The normal vector (the direction perpendicular to the surface).
181
181
182
182
||
@@ -193,14 +193,14 @@ For example, if we had a ball moving around the screen and wanted it to bounce o
193
193
[!code-csharp[](./snippets/bounce_example.cs)]
194
194
195
195
> [!TIP]
196
-
> [**Vector2.UnitX**](xref:Microsoft.Xna.Framework.Vector2.UnitX) is $(1, 0)$ and [**Vector2.UnitY**](xref:Microsoft.Xna.Framework.Vector2.UnitY) is $(0, 1)$. We use these to get the screen edge normal since the edges of the screen are not at an angle. For more complex surfaces, you would need to calculate the appropriate normal vector based on the surface angle
196
+
> [**Vector2.UnitX**](xref:Microsoft.Xna.Framework.Vector2.UnitX) is $(1, 0)$ and [**Vector2.UnitY**](xref:Microsoft.Xna.Framework.Vector2.UnitY) is $(0, 1)$. We use these to get the screen edge normal since the edges of the screen are not at an angle. For more complex surfaces, you would need to calculate the appropriate normal vector based on the surface angle.
197
197
198
198
### Optimizing Collision Performance
199
199
200
200
When checking for collisions between multiple objects, testing every object against every other object (often called brute force checking) becomes inefficient as your game grows. Brute force checking can be calculated as $(n * (n - 1)) / 2$ where $n$ is the total number of objects. For example, if you have 100 objects in your game, that's $(100 * 99) / 2 = 4950$ collision checks every frame. To improve performance, we can use a two-phase approach:
201
201
202
202
1. Broad Phase: A quick, simple check to rule out objects that definitely are not colliding.
203
-
2. Narrow Phase: A more precise check only performed on objects that passed the broad phase.
203
+
2. Narrow Phase: A more precise check that is only performed on objects that have passed the broad phase.
204
204
205
205
For our simple game with just two objects, this optimization is not necessary. However, as you develop more complex games, implementing a broad-phase check can significantly improve performance.
206
206
@@ -352,11 +352,11 @@ In this chapter, you accomplished the following:
352
352
- Rectangles for walls and platforms.
353
353
- Explored different types of collision responses:
354
354
- Blocking to prevent objects from overlapping.
355
-
- Triggering to cause events when objects collide.
355
+
- Triggering events when objects collide.
356
356
- Bouncing to reflect objects off surfaces.
357
357
- Created reusable components:
358
358
- Implemented a Circle struct for circle-based collision.
359
-
- Added methods to detect circle intersection.
359
+
- Added methods to detect circle intersections.
360
360
- Applied collision concepts to our game:
361
361
- Added screen boundary collision for the slime.
362
362
- Implemented bouncing behavior for the bat.
@@ -377,10 +377,10 @@ In the next chapter, we will explore using tilesets and tilemaps to create tile
377
377
::: question-answer
378
378
For two rectangles A and B to collide:
379
379
380
-
1. A's left edge must be less than B's right edge
381
-
2. A's right edge must be greater than B's left edge
382
-
3. A's top edge must be less than B's bottom edge
383
-
4. A's bottom edge must be greater than B's top edge
380
+
1. A's left edge must be less than B's right edge.
381
+
2. A's right edge must be greater than B's left edge.
382
+
3. A's top edge must be less than B's bottom edge.
383
+
4. A's bottom edge must be greater than B's top edge.
384
384
385
385
:::
386
386
@@ -395,8 +395,8 @@ In the next chapter, we will explore using tilesets and tilemaps to create tile
0 commit comments