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

Theme: auto

Level, Player, and Jumping

This lab uses a background texture just like the previous one did, but it’s much bigger, so you need to position the background actor to (3392, 224)

Next, make a Block actor subclass that has a SpriteComponent and a CollisionComponent:

  • Much like Log or Vehicle from Lab 3, the texture it uses will depend on a letter (A-I are the valid block letters). The textures are all with file names like "Assets/BlockX.png", where X is the letter of the block
  • The CollisionComponent for Block should be 32x32

In Game, you need a vector of Block* and AddBlock/RemoveBlock functions, as well as a public getter that returns a const reference to the vector. Use the pattern where the Block constructor calls AddBlock and destructor RemoveBlock

The level loading is like Lab 3, but there are some changes:

  • For now, load the Assets/Level0.txt file
  • The top left corner of the file is centered at (16, 16)
  • Each block is 32x32 in size
  • The letters A through I should spawn a Block with the corresponding texture
  • Don’t do anything for all other letters (and .) for now

You should see the new background texture and some platforms made of blocks: Initial Mario blocks loaded

The Player

Make a subclass of Actor called Player

  • Give the Player a SpriteComponent and use the "Assets/Mario/Idle.png" texture. When constructing the SpriteComponent, use a draw order of 200 (so the player is in front of the blocks)
  • Give your Player a CollisionComponent with dimensions 32x32.

Next, make a subclass of MoveComponent called PlayerMove.

  • Create a PlayerMove in the Player constructor
  • In the level file, the character P represents the player spawn position. Modify the level loader in Game::LoadData() to create a new Player at this location. When you create the player, save its pointer in a member variable in Game.

You should see the player on the bottom left part of the window, hovering above a block:Player spawning

Player Controls

Now let’s add player controls. We’ll implement this in the PlayerMove class. Begin by adding overrides for ProcessInput and Update. As we go along, you’ll need to add member variables to support these.

PlayerMove::ProcessInput

Use the A and D keys to modify the forward speed. For now, just set it to 300.0f for D and -300.0f for A, and 0 if either both or neither keys are pressed.

PlayerMove::Update

This won’t use the base MoveComponent::Update, so don’t call that. For now, move the x-position according to forward speed and delta time.

You should now be able to move left and right with A/D keys.

Add a float member variable mYSpeed to track the vertical velocity. In Update, move the Actor’s y-position according to mYSpeed and delta time

  • mYSpeed should default to 0.0f
  • mYSpeed is a velocity, so it is in units/second
  • To change the velocity you need an acceleration, which is in units/second2
  • We will use an acceleration of 2000.0f for gravity
  • You need to incrementally update mYSpeed every frame using the Euler integration formula. Make sure you do this at the end of Update.

Your character will now rapidly fall off the bottom of the screen.

Next, add a check that prevents the player y-value from increasing past 448.0f. Now your player will fall through the platform and stop halfway off the bottom of the screen.

Now it’s time to check if the player overlaps with blocks using the GetMinOverlap function implement in Lab 3. You should do this after you update the player’s position, but before you update mYSpeed. Loop over the blocks and check the CollSide:

  • If it’s CollSide::None, then Mario didn’t collide with the block, so move on
  • If it’s CollSide::Top and mYSpeed > 0.0f, Mario is landing on top of block, so set mYSpeed = 0, which stops Mario from moving down
  • For anything other than CollSide::None, you also must adjust the player’s position by the offset vector you get from GetMinOverlap
  • Because the collision components require the most up-to-date position information to work correctly, you should call SetPosition to update player’s position each time you detect a block collision
  • Mario can collide with more than one block on any given frame, so you should NOT quit the loop on the first collision

Rather than calling GetComponent<CollisionComponent>() on every block every frame, you could cache this in a member variable in Block.

You should now be able to slide back and forth along the starting platform smoothly without falling through it. If you walk off the edge, the player should fall to the bottom of the screen.

Making the Player Jump

Now let’s make the player jump!

PlayerMove variables

Create two new bools in PlayerMove, both initialized to false: mSpacePressed and mInAir

PlayerMove::ProcessInput

We need to detect the leading edge of the spacebar, like in Lab 3. If so, set mYSpeed to -700.0f (this means the player’s y-velocity has them moving upwards)

You should now be able to jump only on the leading edge of the space bar. However, you can jump again while in the air, which we don’t want to support. There are also some glitches to fix.

Preventing Multiple Jumps

  • In PlayerMove::ProcessInput code for jumping, only set mYSpeed if mInAir is false (meaning, don’t start a new jump if mInAir is true). Then, set mInAir to true when the player starts jumping
  • Back in Update, before you loop over all the blocks, first set mInAir to true – that is, we are assuming we are in the air. Then, when you detect that the player collided with the top of a block, set mInAir to false. This way, the player will properly “land” on the ground when colliding with the top of a block. If the player doesn’t collide with the top of any block, mInAir will be true since we set it to that before the loop.

With this change, you will no longer be able to jump out of the pits in the level. However, ultimately this will kill Mario anyway, so it’s fine.

Fixing Floating

Back in Update, change it so that if the player collides with the bottom of a block, and the mYSpeed is negative, set it to 0.0f. This allows gravity to immediately take over and the player will start falling correctly.

The basics of the platformer should now be setup. You should be able to make your way up to the top platform. Verify that the player behaves correctly when you bump into a platform from the side.

Now change your level file to "Assets/Level1.txt". There is an additional letter, Y that you should ignore for now.

You should now see the beginning of the level on screen (and verify that jumping and such still works).

Once you’e pushed this code, you’re ready to move on to part 2.