Scrolling and Enemies
Now that the basic platforming works, you’re going to add a camera and enemies.
Scrolling Camera
Implement a 2D camera as described in lecture.
- Add a private
Vector2
for the camera position toGame
- In
SpriteComponent::Draw
, when you calculate the x/y position of the rectangle, you also need to account for the camera position. Remember thatScreenPos = WorldPos – CameraPos
. - At the end of
PlayerMove::HandleUpdate
, set thecamera.x
equal to the player’sposition.x
. You don’t need to change thecamera.y
because the original Super Mario Bros. does not scroll up and down
Now the player will start at the leftmost edge on the screen, and you should be able to move through the level. For now, the player will always remain on the leftmost edge on screen, like this:
You may notice that if you’re standing right next to a tall green pipe, start running into the pipe, and try to jump, you won’t be able to jump over the pipe. This is a bug because the pipe is made of multiple “blocks.” You do not need to fix this in the lab, but if you’re curious how to fix it, we discuss in “Taking it Further!”
Centering the Player
Next, we want to horizontally center the player on screen. To do this, should subtract half the window width when calculating the new camera.x
value in PlayerMove
Now the player is centered when you move through. Though now you’ll see the area to the left of the level when the game starts (which we’ll fix in a second):
No Backtracking
In the original Super Mario Bros., you can’t move the camera backwards, and you can’t move the player off the screen to the left. You can only scroll forward. We want this, so:
- Don’t change
camera.x
if you would decreasecamera.x
- Don’t let the
camera.x
go below 0 - Don’t let the
player.x
ever be less than thecamera.x
Your scrolling camera should now work like this:
Creating Enemies
The Y
letter in the level file corresponds to the location of an enemy. However, we do not want to simply create all the enemies as the game first loads, because then they will have moved out of position by the time the player gets close.
Instead, make a Spawner
actor that doesn’t do anything other than wait for the player to get close enough, at which point the spawner will create one enemy, and then destory itself.
Goomba
The “goomba” is one of Mario’s enemies. Make a new Actor
subclass called Goomba
with:
- A
SpriteComponent
using the"Assets/Goomba/Walk0.png"
texture, and a draw order of50
- A
CollisionComponent
with size{32, 32}
- An instance of a new
Component
subclass calledGoombaMove
Just like with the blocks, you’ll want to keep track of all the goombas in the Game
class with a separate vector.
Spawner
Now make another Actor
subclass called Spawner
. It doesn’t need any components, but it does need a HandleUpdate
.
In HandleUpdate
, you want to spawn a Goomba
if the x-distance between the spawner and the player is less than 600
. In this case:
- Create a Goomba, and set its position to the Spawner’s position
- The Spawner should
Destroy()
itself
Now in your level loading code, whenever you see a Y
, create a Spawner
object.
Now when you move through the level, you should see various Goombas positioned slightly above blocks (where their spawn spots are):
Making the Goombas Move
Now it’s time to implement GoombaMove::HandleUpdate
. Unlike the earlier parts of this lab, the instructions for this are less detailed. You should apply the techniques you’ve already learned to implement the behaviors as described.
- Goombas should start out moving to the left at a speed of 100 units/second
- If while moving left, they run into a block or another goomba, they should start moving to the right. Hint: Think about which
CollSide
s this means…
Hint 2: Don’t forget that a goomba should not be able to collide with itself! - Similarly, if they’re moving to the right and run into a block or another goomba, they should start moving left again.
- On any collisions, you should “fix” the position so the goomba is no longer overlapping
- If a goomba isn’t standing on any blocks, it should fall with the same gravity as the player does (but they would continue moving left/right as needed)
- If a goomba’s y-position places them below the bottom of the screen, destroy them (because this means they fell into a pit).
A Goomba falling slightly into the platform is sometimes an overlap of left or right, which may cause your Goomba to occasionally switch directions when it shouldn’t. To fix this, check block collision in two consecutive loops. In the first loop, only care about “top”. Then in the second loop, look for “left/right” overlaps, but don’t count it as a collision unless the block.y
is approximately the same as the goomba.y
.
As you move through the level, you should see goombas moving to the left initially. You should see that goombas that hit a wall or each other should switch their horizontal direction. Watch the two goombas in between the pipes near the beginning of the level, as they should change directions back and forth on account of each other and the walls. If you move a bit further, you should see two goombas fall from a high platform to a middle platform and then to the ground:
Stomping
Mario is able to jump on and “stomp” the goombas.
Mario successfully stomps a goomba if one these is true:
-
Mario hits the top of the goomba
OR
-
Mario hits the left/right of the goomba AND is in the air
If a goomba gets stomped, it should:
- Change its texture to
"Assets/Goomba/Dead.png"
- No longer move
- Not be able to collide with Mario anymore
- Get destroyed after 0.25 seconds
When Mario stomps a goomba, he should also do a “half jump”, which just means:
- Set player’s y-velocity half of the normal jump velocity
If Mario collides with a goomba but does NOT satisfy the “stomping” conditions, Mario should die. When Mario dies you should:
- Change his texture to
"Assets/Mario/Dead.png"
- Set “is active” to false so Mario no longer updates
Keep in mind that if the goomba in question has already been stomped, then a collision against it should do nothing.
You should be able to stomp goombas now by jumping on them. You should die if you just run into them when not in the air:
Once you’e pushed this code, you’re ready to move on to part 3.