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

Theme: auto

Loading Levels and Basic Movement

First, change your window to be 448x512 in size.

Next, create an actor in LoadData that’s centered in the window, has a SpriteComponent, and uses the "Assets/Background.png" texture.

You should see the window and a background: Frogger background

For this game, we’re using a text-based level file format. Here’s what the provided Assets/Level.txt file looks like:

......G......
...X.....Y...
.X...X....X..
......Z......
X...X...X....
....Y......Y.
.............
T....T....T..
..D.D...D.D..
.C..C..C..C..
B.....B.....B
...A.....A...
......F......

Each character represents a 32x32 square in a grid. The square in the top left corner is centered at (32, 80). A . means there’s nothing at that square. A, B, C, D, and T are vehicles, with A-D being four different types of cars and T being a truck. X, Y, and Z correspond to the logs floating in the river. F is the starting position of the frog and G is the goal.

You’ll need to make three Actor subclasses: Vehicle, Log, and Frog. Right now the only components they need are SpriteComponents.

Frog’s sprite component will always use “Assets/Frog.png”

For Vehicle, which texture you’ll use will depend on the letter:

  • A"Assets/CarA.png"
  • B"Assets/CarB.png"
  • C"Assets/CarC.png"
  • D"Assets/CarD.png"
  • T"Assets/Truck.png"

For Log, the texture also depends on the letter:

  • X"Assets/LogX.png"
  • Y"Assets/LogY.png"
  • Z"Assets/LogZ.png"

Write code in Game that loads in the text file and creates the correct actors with the correct textures. Ignore the G letter for now (treat it like a . or nothing at that square). You can use normal C++ file reading to read in the file (eg. std::ifstream to open the file and std::getline to read a line). For each square, if there’s an actor at that square, you’ll need to create it and set it to the correct position.

Once your actors are setup and you’re correctly creating them with the correct textures, your game should look like this: File loading

Frog Movement

Since the Frog hops are instant and not a continuous motion, Frog doesn’t need a MoveComponent. Instead, we can just detect the leading edge and calculate the new position in an override of OnProcessInput. You want to detect the leading edges of each of the four WASD keys: W for up, S for down, A for left, and D for right. On a leading edge, you want to move the Frog 32 units in the corresponding direction.

To save the “last frame” values, rather than using four separate bools, you should use a map where the key is an SDL_Scancode and the value is a bool.

You should also make it so the Frog can’t hop off-screen by restricting the min/max x and y values of its position. You can use the Math::Clamp to help do this.

Since Math::Clamp is a template function, all arguments need to be the same type and it will return a value of that type. In this case, you want the type to be float, because the x/y components of the Vector2 are floats. If you use int, you will truncate the position of the frog which will cause bugs later on, so don’t do this!

You should now hop in the four directions based on the WASD keys. Keep in mind that holding down a key should still only hop once, on the initial leading edge! Also verify that you can’t hop off-screen.

Vehicle and Log Movement

Since Vehicle and Log will move in the same way, it makes sense to make a component specifically for this. Make a new subclass of MoveComponent called WrappingMove. You need to add only a single member variable to the class, a Vector2 for the direction the owner should move in.

Instead of using the parent’s Update function, we want to have a separate override in WrappingMove. Inside here you want to move the owner in the direction specified by the direction member variable at the specified forward speed (don’t forget to multiply by delta time!). Remember that since WrappingMove is a subclass of MoveComponent, you already inherit the mForwardSpeed variable, so you shouldn’t declare another variable. Just use the one you inherited.

You also want to make it so WrappingMove will wrap the objects around the screen if their position moves off-screen. (You only need to worry about the x-component). For example, if x becomes less than 0 you will want to change the x to the screen width, which is 448).

Now add your WrappingMove component to both Vehicle and Log. Vehicles should have a forward speed of 50 and Logs a forward speed of 37.5. As for the direction, it should be based on the row in the file. Assume the first row of the file is row 0. Even rows should have a direction of <1, 0> (to the right) while odd rows should have a direction of <-1, 0> (to the left). This will give a desired alternating direction on each row.

Verify your logs and vehicles move to the left and right and wrap around screen, like in the original video. Note that the video shows the vehicles slow down and speed up in some cases, but your vehicles won’t behave that way just yet.

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