GetMinOverlap, Riding Logs and Finishing Touches
While there are multiple ways to implement the frog being able to “ride” a log, we will use an approach that utilizes GetMinOverlap
, primarily because GetMinOverlap
will be critical for subsequent labs!
GetMinOverlap
You need to implement the CollisionComponent::GetMinOverlap
function. It returns CollSide::None
if “this” does not intersect with “other” (you can just use the Intersect
function to figure out if they don’t intersect). If they do intersect, the function returns the CollSide
that is the minimum overlap side. Furthermore, it sets the offset Vector2
passed in by reference to the offset to move “this” so it will be exactly touching “other”.
If the instructions below do not make sense to you, you should review the slides!
- You need to calculate the four
other
[Min
/Max
][X
/Y
]Diff
variables as discussed in lecture (and in this diagram): - In the context of
GetMinOverlap
, “this” corresponds to the player in the diagram, and “other” corresponds to the block - The
CollSide
s refer to the sides of “other”. Eg.CollSide::Top
means that the minimum overlap is the top side of “other” (so, the top side of the block in SDL) - Remember, these differences are always “other” side minus “this” side
- Whichever of the four
leftDist
/rightDist
/topDist
/bottomDist
has the lowest absolute value is the side of “other” that is minimally overlapped - For example, if
leftDist
has the lowest absolute value, then it’sCollSide::Left
- The offset reference variable represents the vector that you’d have to apply to “this” so that it exactly touches “other”. It will always have one component as
0
, and the other as the correct offset in that direction - If you collide with the left/right side of “other”, you should change
offset.x
- If you collide with the top/bottom side of “other”, you should change
offset.y
As with the other CollisionComponent
functions, we validate that your GetMinOverlap
is implemented correctly with the unit tests on GitHub Actions. Once you implement a correct GetMinOverlap
, you should pass all the unit tests. If you don’t pass the unit tests, that means there is an issue with your implementation that you need to fix to satisfy the GetMinOverlap
spec. Note that it is possible that your Frogger game will appear to work even with a wrong GetMinOverlap
function, which is why there are unit tests. If you want to manually run the tests, recall that the instructions are here.
Riding the Logs
Add a CollisionComponent
to Log
. They all have a height of 24.0f
, but the width depends on the type of log:
X
is96.0f
Y
is128.0f
Z
is192.0f
Next, you’ll need a vector of Log*
in Game
as well, so do the same thing you did with the vehicles.
Then in Frog::OnUpdate
, after the Vehicle
intersection checks, add another loop that loops over the Log
s. You’ll want to call GetMinOverlap
on the frog’s collision component, passing in each Log
’s collision component as a parameter, and saving the result in a local variable. If the result is CollSide::None
you can ignore that log. Otherwise, you want the frog to “ride” the log. To do this:
- Set the y-position of the frog to the y-position of the log
- Move the position of the frog based on the log’s
WrappingMove
direction, forward speed, and delta time. This is to get the frog to move in unison with the log - If the
CollSide
is eitherLeft
orRight
, you need to additionally addoffset.x +
either positive or negative16
(depending onLeft
orRight
) to the frog’s x-position, which will get it to line up nicely with the sides of the logs.
If everything’s working properly, you should be able to get the Frog to ride along with the log once you jump onto one:
Drowning
You may have noticed that right now the frog can just jump into the water and wait for a log to pick it up. We want to change it so that the frog dies if it misses a log. The bounds of the water area are between a y of 90 and 255. So, you just need to track whether your Log
s loop detected that the frog is riding on a log. If the frog isn’t actively riding a log and the y is within that established range, you should kill the frog. As with getting ran over by a vehicle, dying should create a DeadFrog
at the spot and reposition the Frog
back to the start.
You should verify that your frog can still jump onto and ride logs, but now if you jump into the water you’ll die.
The Goal
Rather than making a new subclass for the goal, you can treat it like the actor you made for the background image actor. Create a base Actor
and then create a collision component for it using the dimensions of 32x32. You want to create the goal at the the G
letter in the file and save a pointer to that actor in Game
.
Then in your Frog::OnUpdate
, you just need to check for intersection with the goal and if you intersect, you should set the frog’s position to the goal and then SetState
to ActorState::Paused
which will stop the frog from updating anymore.
Finally, you want to make it so that if the frog’s y position is less than 90 and you aren’t at the goal, the frog dies (since that means the frog jumped into the wall instead of the safe goal zone).
Your game should now be complete and work like the original video!
Once you’ve pushed your code, you should review the grading specifications to confirm you’ve satisfied them.