quinta-feira, 2 de julho de 2015

Paper 2D Game: The cars

This article is the continuation of the article "Paper 2D Game: Sprites and Camera".

In this article we will create the Blueprints "PlayerCar" and "EnemyCar".

Before that I want to show an editor option that is often used in these Blueprints, which is the "Split Struct Pin" option. Many Blueprint Actions receive a structure as a parameter. The "Location" is an example of structure that aggregates the values X, Y and Z. When click with the right button on the structure parameter appears the "Split Pin Struct" option that separates the structure in different parameters. The image below shows the Action "Set Actor Location" using the Location and with the separate structure:

Click to enlarge

  • PlayerCar Blueprint:

Let's start with the Blueprint that represents the player. Create a new Blueprint of the "Actor" type named "PlayerCar".

Open the Blueprint, on the "Components" tab add a "Paper Sprite":

On the "Details" tab of the "Paper Sprite", in the property "Source Sprite" choose "PlayerCar_Sprite":

To test collision, add a component of the type "Capsule Collision":

On the "Details" tab of "Capsule", in the "Shape" property put the following values:

In "MyBlueprint" tab create the variables "CarSpeed" (Float type), "HorizontalDir" (Integer type) and "VerticalDir" (Integer type):

In the variable "CarSpeed" put "200" as "Default Value". In this game one pixel equals one Unreal Unit (uu), then the value of this variable means that the car speed of the player is 200 pixels/second.

Click the "Class Defaults" button from the top bar of the Blueprints editor and on the "Details" tab, "Input" category, "Auto Receive" property, click the combo box and choose "Player 0". This serves to indicate that this blueprint will receive the input commands of the player.

The car of the player is controlled using the arrow keys. Input events modify the value of the variables "HorizontalDir" and "VerticalDir". These variables can receive the values -1, 0 and 1. They are used to calculate the direction the car is moving. The image below shows the input events.

The movement of the player's car will be done at the "Tick" event. If you do not know the "Tick" event and the "Delta Seconds" parameter, take a look at the article "Tick Event and Latent Actions in Blueprints".

The content of the Tick event is this:

Click to enlarge 

The "Clamp" function is used to limit the "PlayerCar" on the street. For this, the value of X must be at least 160 and at most 480. The Z value must be between 40 and 440.

The variables "HorizontalDir" and "VerticalDir" are multiplied by the speed value. For example, if the "HorizontalDir" variable is 1, then the result will be a positive value, that indicates that the car should move on the X axis to the right. If it is -1, the result is negative indicating that the movement on the X axis is to the left. If "HorizontalDir" is 0, the result is 0, so it will not move on the X axis.

  • EnemyCar Blueprint:

Create a new blueprint of the "Actor" type named "EnemyCar". In the "Components" tab add a "Paper Sprite" and "Capsule Collision" the same way that was done for the "PlayerCar". Use the "EnemyCar_Sprite" in the "Source Sprite" property. Create a variable of Integer type named "Direction".

A "EnemyCar" starts the game on the top screen. It moves down and its horizontal movement is defined by the value of the variable "Direction" (-1=left, 0=center, 1=right). The value of the variable "Direction" randomly changes over a period of at least 0.5 seconds and a maximum of 1.5 seconds. A custom event was created with the name "ChangeDirection". It is responsible for these changes of values.

Click to enlarge

The functions of the "Random" type return a random value between the minimum and maximum values specified. It is used the "SetTimer_Delegate" function to schedule the next call of the event "ChangeDirection". The parameter "Delegate" is a reference to the event, simply connect the small red square that exists in the event to the parameter of the function "SetTimer_Delegate". Note that the Timer is not with the Looping active and will run only once. Every call of the "ChangeDirection" will activate the Timer with a different time value.

The Tick event is similar to the "PlayerCar". One difference is that we used the function "AddActorWorldOffset" that adds the values passed as parameters to the current location value: 

Click to enlarge

The speed of the "EnemyCar" is temporarily set to the value "100". In the next article this value will be adjusted according to the current level of the game. After modifying the position of "EnemyCar", the Macro "TestLimit" is called which checks if the "EnemyCar" touched the sides of the street or has left the playing area:

Click to enlarge

If the "EnemyCar" has passed the bottom of the screen, it is destroyed. If the "EnemyCar" touch the street sides, the direction of motion is reversed.

It is missing some details of the "EnemyCar" that can only be completed in the next article, when we created the Blueprint "GameManager" that will keep the information of the game.