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

Theme: auto

Movement

First, remove all the test actors from the previous part, but keep the actor that uses the Stars.png background texture as that’ll be the background for the game.

The MoveComponent class will implement actor movement. We’ve given you a declaration of the class, but you’ll have to implement the Update function.

Remember that in Actor::Update, you call Update on each component associated with that actor. So by giving an actor a MoveComponent, the movement code contained in it will run every frame.

Before you can implement Update, create a function in Actor called GetForward that returns the forward direction vector of the actor. Since the game is 2D, you can compute this using the unit circle equation covered in class. Remember that since +y is down in SDL, negate the y component of the equation.

MoveComponent has the following member variables:

  • An angular speed (in radians/second)
  • A forward speed (in pixels/second)

Inside MoveComponent::Update, first add code to update the owning actor’s rotation over time. This is very similar to the position update equation covered in lecture, except instead of position and velocity vectors, you have scalars for the current angle and angular velocity/speed.

Next, add code to updates the owning actor’s position based on the owning actor’s forward vector, the forward speed, and delta time (this is exactly like the slides at the end of the lecture).

To make sure that MoveComponent updates before other components update, we’ve set it’s “update order” variable to a lower number than the default of 100.

Ship

Now it’s time to create new files. We’re first going to create a subclass of Actor called Ship in two new files (Ship.h/cpp). The best way to create the files depends on whether you’re in Visual Studio or Visual Studio Code.

In Visual Studio:

  1. Right click on the folder for the Lab in the solution explorer (so in this case, Lab02)
  2. Select Add>New File
  3. Rename “New File” to whatever you want, so in this case Ship.cpp. Then repeat steps 2/3 for Ship.h, as well.

In Visual Studio Code:

  1. Right click on the folder for the Lab in the file list (in this case, Lab02
  2. Select Add>New File
  3. Rename the file to whatever you want, so in this case Ship.cpp. Then repeat steps 2/3 for Ship.h, as well.

Now in your Ship.h file, declare a subclass of Actor called Ship. Since you’re subclassing Actor, you can’t just use a forward declaration and you DO have to #include "Actor.h". The constructor of Ship takes in a class Game* parameter (as all Actor subclasses must).

Then, add two member variables (for these, you can use forward declarations):

  • A MoveComponent*
  • A SpriteComponent*

Since the Actor constructor takes in a game pointer, the implementation of the Ship constructor (in Ship.cpp) needs to pass the game pointer along in its initializer list, like this:

Ship::Ship(Game* game)
:Actor(game)
{
	// TODO: Add code here
}

Inside the Ship constructor, dynamically allocate a SpriteComponent and a MoveComponent, and assign them to the member variables for these components. Use "Assets/Ship.png" for the texture.

Create an instance of the Ship in Game and set its initial position to the center of the screen. Try various hardcoded angular/forward speeds just to make sure your movement works.

Hooking Up Input

Now, in the declaration for Ship, add an override of OnProcessInput. In this function, use the key state array to query the different keys (like SDL_SCANCODE_A). Based on the keys, you want to change the forward and angular speed of the MoveComponent the ship is using. Make it so the controls work as follows:

  • Pressing W moves forward while pressing S moves backwards. If both W and S are pressed, the ship shouldn’t move forward or backwards.
  • Pressing A rotates the ship counter-clockwise while pressing D rotates the ship clockwise. If both A and D are pressed, the ship shouldn’t rotate.
  • It is possible for the ship to move and rotate at the same time.

You should now be able to move and rotate the ship.

As an alternative to creating member variables to store the different components, you could instead use the templated GetComponent function that’s provided in Actor. For example, the following would get the pointer to the actor’s MoveComponent

MoveComponent* mc = GetComponent<MoveComponent>();

However, calling GetComponent every frame is not efficient when you know the component pointer isn’t going to change. That’s why we tell you to make a pointer to the components as member variables.

That being said, in cases where you don’t actually know the type of Actor subclass you’ve got a pointer to, it’s very helpful to use GetComponent to get a component if a specific type (if there is one).

Changing the Ship Texture when Moving

For some polish, add code in Ship that changes the sprite component texture to "Assets/ShipThrust.png" when the ship moves forward or backwards. When the ship’s not moving, set the texture back to the default "Assets/Ship.png".

When the ship flies around it should now look like this:Ship moving

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