Skip to main content Link Search Menu Expand Document (external link)

Theme: auto

Scrolling and Enemies

Now that the basic platforming works, you’re going to add a camera and enemies.

Scrolling Camera

You’re going to implement a 2D camera as described in lecture.

  • Add a private Vector2 for the camera position to game and a public Vector2& GetCameraPos() function that returns the camera position (the reference for the return type of the function is important)
  • In SpriteComponent::Draw, before the SDL_RenderCopyEx call, we want to adjust r.x and r.y by the camera position x/y, respectively. Remember that ScreenPos = WorldPos – CameraPos and you still want to keep the half width/height subtractions.
  • At the end of PlayerMove::Update, set the camera.x equal to the player’s position.x (leave the camera.y as 0)

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.

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!”

Next, we want to horizontally center the player on screen. To do this, should subtract 300 (half the screen 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).

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 let the player.x ever be less than the camera.x
  • Don’t change camera.x if you would decrease camera.x
  • Don’t let the camera.x go below 0 (to fix the problem at the start)

Your scrolling camera should now work as described. If you’re not sure if your camera’s working to specification, watch the final video. (Unlike the video, you will be able to run past the end of the level, because we haven’t added the win condition yet.)

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, we’re going to 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 get destroyed.

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 of 150
  • A CollisionComponent with size 32x32
  • A new MoveComponent subclass called GoombaMove (we’ll implement the movement a bit later)

Just like with the blocks, you’ll want to keep track of all the enemies in the Game class with a separate vector. This means also, just like with Block, your Goomba constructor should add to your enemy vector, and the destructor should remove from the enemy vector

Spawner

Now make another Actor subclass called Spawner. It doesn’t need any components, but it does need an OnUpdate override function.

In OnUpdate, 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
  • Set the Spawner’s state to ActorState::Destroy (so it’ll be destroyed and can’t spawn anything anymore)

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): Goombas floating

Making the Goombas Move

Now it’s time to implement GoombaMove::Update. 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 begin 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 CollSides 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).

If your goombas seem to turn at incorrect times, it’s because the goomba falling slightly into the platform is sometimes a MinOverlap of left or right. 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. As before, watch the video if you’re not sure if it’s working properly.

Stomping

Now you’ll add the ability for Mario to jump on and “stomp” the goombas. You should add a bool to Goomba to track whether it’s been stomped.

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 mInAir is true

If a goomba gets stomped, it should:

  • Change its texture to "Assets/Goomba/Dead.png"
  • No longer move in GoombaMove
  • 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 mYSpeed in PlayerMove to -350.0f (half of the normal jump velocity)
  • Set mInAir to true, since you’re in the air now

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 him to ActorState::Paused (so you can see him dead for all of eternity, or at least until you close the game window)

Keep in mind that if the goomba in question has already been stomped, then a collision against 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.