Collisions and Frog Roadkill
We’re going to use AABB collision as discussed in lecture to detect whether the Frog
intersects with various objects. In your Lab03
folder, you will find CollisionComponent.h and CollisionComponent.cpp. This has a declaration of a new Component
subclass called CollisionComponent
, but you’ll need to implement the functions yourself.
First, implement GetMin()
and GetMax()
, which return Vector2
s for the min and max points of the box, respectively. You compute each of these points through a combination of the owner’s position, owner’s scale, and width/height of the box. For example, the min.x
position is:
min.x = ownerXPosition – (mWidth * ownerScale) / 2.0f
Remember that the min.y
is the smallest numerical y-value no matter which way the y-axis goes. With SDL coordinates, the minimum y-value is towards the top of the screen, but the calculation for min.y
is not affected by that.
Now implement the Intersect
function, which returns true
on an intersection. Use the basic AABB collision approach discussed in class where you test for the four cases the boxes cannot intersect. If none of these cases are true, then the boxes must intersect.
To validate that your CollisionComponent
functions are implemented correctly, any time you push a change to Lab03/CollisionComponent.cpp
, we run unit tests on GitHub Actions. After implementing correct GetMin
, GetMax
, and Intersect
functions, you should pass 5 of the test cases, but you will still fail 2 because they test the GetMinOverlap
function that you’ll implement in the next part. If you’re not passing all the GetMin
, GetMax
, and Intersect
test cases, that means there is something wrong which you need to fix. If you’re not sure what the failure message(s) mean, or want to manually run the unit tests, see the further information below.
Now add a CollisionComponent
to Frog
and Vehicle
. The Frog
collision should have a width and height of 25. For the Vehicle
, the dimensions of the collision component depend on if it’s a car or a truck. Use the SetSize
function to set the dimensions of the collision component. A car should be 32x32 while a truck should be 64x24.
Testing Frog vs. Vehicle Collision
Add an override of OnUpdate
to Frog
. You need to check whether the frog collides with any vehicles, and if so, kill the poor frog. This means you’re going to need to add a std::vector
of Vehicle*
to Game
so that you can access all of them. Then in the Vehicle
constructor and destructor, you will want to add and remove from this vector (sort of like how the Asteroids were in a vector in the last lab).
Once you have this vector, then in Frog::OnUpdate
you just need to check whether the frog’s collision component intersects with any of the vehicles’ collision components. If it does, you’ll kill the frog. For now, killing the frog should just move the frog back to the original start position at the bottom of the screen.
You should still be able to move the frog as before, but now if you intersect with a vehicle, the frog will move back to the start position.
Adding a DeadFrog
To make it a little easier to visualize where you died, make a new Actor
subclass called DeadFrog
. It’ll need a SpriteComponent
using "Assets/Dead.png"
. You also need to override OnUpdate
and make it so the DeadFrog
destroys itself after 0.5 seconds. You can implement this much like the timeout for lasers.
Now change it so when the frog dies, it creates a DeadFrog
at the spot it died.
Now when the Frog dies you should see a yellow skull and crossbones at the point of death (for 0.5 seconds), like so:
More Responsible Drivers
It turns out the vehicle drivers feel bad about running over countless frogs. Add an override of Vehicle::OnUpdate
. In here, figure out if the frog is within an angle in front of the vehicle. If it is, the vehicle should move at half of its original speed, otherwise the vehicle should move at normal speed.
We’re going to consider the frog to be “in front of” the vehicle if the frog is within Pi/6
radians of the forward vector of the vehicle. That means the vehicle driver can see the frog and so they’ll be responsible and slow down!
To implement this, we want you to use Vector2::Dot
as well as Math::Acos
. If you’re not sure how to use this to calculate whether the frog is “in front,” you should review the slides. Keep in mind that you can get the direction the vehicle is facing from its WrappingMove
component. Also, as with many problems, it might help to draw a diagram on paper if you get stuck.
You should verify that if the frog is “in front” of a vehicle that vehicle moves slower, and otherwise they move at normal speed.
Once you’e pushed this code, you’re ready to move on to part 3.
Further Info: CollisionComponent
Unit Tests
The tests for CollisionComponent
will automatically run on any push where you modify the Lab03/CollisionComponent.cpp
file.
Debugging the Tests Locally
If you are unexpectedly failing unit tests and would like to be able to debug locally, you can do the following:
- Clone the unit tests repo: https://github.com/itp380-20243/tests-Lab03
- Copy your
Lab03/CollisionComponent.cpp
file into the tests repo - Open the tests repo folder in Visual Studio (PC) or Visual Studio Code (Mac)
- There will be only one target to select in this case (
tests
), instead of the separateLabXX
targets like in your game - You can now run in the debugger like you normally do
Manually Running Unit Tests on GitHub Actions
If you want to manually run your CollisionComponent
unit tests on GitHub Actions, you can also do that. The TAs will be running the unit tests manually when grading, so we recommend you double-check them yourself. Keep in mind that it’s possible that your Frogger game works even if your CollisionComponent
is not quite correct. However, this will be a problem in future labs as you’ll reuse that code in most labs from here on out, which is why we require you to fix it.
-
First, on your GitHub page for your repo, go to the “Actions” tab:
-
Select “Unit Tests (Manual)” from the left column, then click on “Run workflow” dropdown and the green “Run workflow” button.
-
After a few seconds, it will start the unit tests. It will take about 45 seconds to run. If it succeeds, you will see a green check for that workflow run:
If it fails, you’ll get a red X. You can click on the run to see specifically which tests it failed.
If you aren’t sure what a particular failure means, ask someone in lab or office hours (or post on Piazza) and we can help.