quinta-feira, 2 de julho de 2015

Jogo Paper 2D: Os carros

Este artigo é a continuação do artigo "Jogo Paper 2D: Sprites e Câmera".

Neste artigo serão criados os Blueprints "PlayerCar" e "EnemyCar". 

Antes eu quero mostrar uma opção do editor que será bastante usado nesses Blueprints, que é a opção "Split Struct Pin". Várias Ações do Blueprint recebem uma estrutura como parâmetro. O "Location" é um exemplo de estrutura que agrega os valores X, Y e Z. Ao clicar com o botão direito no parâmetro de estrutura aparece a opção "Split Struct Pin" que separa a estrutura em parâmetros diferentes. A imagem abaixo mostra a Ação "Set Actor Location" usando o Location e com a estrutura separada:

Clique para aumentar

  • PlayerCar Blueprint:

Vamos começar com o Blueprint que representa o jogador. Crie um novo Blueprint do tipo "Actor" com o nome "PlayerCar".

Abra o Blueprint, na aba "Components" adicione um "Paper Sprite":


Na aba "Details" do "Paper Sprite", na propriedade "Source Sprite" escolha o "PlayerCar_Sprite":


Para testarmos colisão, adicione um componente do tipo "Capsule Collision":


Na aba "Details" da "Capsule", na propriedade "Shape" coloque os seguintes valores:


Na aba "MyBlueprint" crie as variáveis "CarSpeed" (tipo Float), "HorizontalDir" (tipo Integer) e "VerticalDir" (tipo Integer):


Na variável "CarSpeed", coloque "200" como "Default Value" (valor padrão). Neste jogo um pixel equivale a uma Unidade Unreal (uu), então o valor desta variável significa que a velocidade do carro do jogador é de 200 pixels/segundo.

Clique no botão "Class Defaults" da barra superior do editor de Blueprints e na aba "Details", categoria "Input", propriedade "Auto Receive", clique no combobox e escolha "Player 0". Isto serve para indicar que este Blueprint deve receber os comandos de Input do jogador.


O carro do jogador será controlado usando as setas do teclado. Os eventos de input modificam o valor das variáveis "HorizontalDir" e "VerticalDir". Estas variáveis podem receber os valores -1, 0 e 1. Elas serão usadas para calcular a direção que o carro deve se mover. A imagem abaixo mostra os eventos de input.


A movimentação do carro do jogador será feita no evento "Tick". Se você não conhece o evento "Tick" e o parâmetro "Delta Seconds", dê uma olhada no artigo "O Evento Tick e as Ações Latentes em Blueprints".

O evento Tick ficou desta forma:

Clique para aumentar 

A função "Clamp" é usada para limitar o carro do jogador dentro da pista. Para isso o valor de X tem de ser no mínimo 160 e no máximo 480. O valor de Z tem de ficar entre 40 e 440.

As variáveis "HorizontalDir" e "VerticalDir" são multiplicadas ao valor da velocidade. Por exemplo, se a variável "HorizontalDir" for 1, então o resultado será um valor positivo, que indica que o carro deve se mover no eixo de X para a direita. Se for -1, o resultado será negativo indicando que o movimento no eixo de X será para a esquerda. Se "HorizontalDir" for 0, o resultado será 0, por isso não se moverá no eixo de X.

  • EnemyCar Blueprint:

Crie um novo Blueprint do tipo "Actor" com o nome "EnemyCar". Na aba "Components" adicione um "Paper Sprite" e um "Capsule Collision" da mesma forma que foi feito para o "PlayerCar". Use o "EnemyCar_Sprite" na propriedade "Source Sprite". Crie uma variável do tipo Integer com o nome "Direction".

Um "EnemyCar" inicia o jogo no topo da tela. Ele se move para baixo e o seu movimento na horizontal é definido pelo valor da variável "Direction" (-1=esquerda; 0=centro; 1=direita). O valor da variável "Direction" muda aleatoriamente em um período de no mínimo 0,5 segundo e no máximo 1,5 segundos. Foi criado um evento customizado com o nome "ChangeDirection" responsável por essas mudanças de valores.

Clique para aumentar

As funções do tipo "Random" retornam um valor aleatório entre o valor mínimo e máximo especificado. Foi usada a função "SetTimer_Delegate" para agendar a próxima execução do evento "ChangeDirection". O parâmetro "Delegate" é uma referência para o evento, basta ligar o pequeno quadrado vermelho que tem no evento ao parâmetro da função "SetTimer_Delegate". Observe que o Timer não está com o Looping ativo e será executado apenas uma vez. A cada chamada do "ChangeDirection" o Timer será ativado com um valor de tempo diferente.

O evento Tick é semelhante ao do "PlayerCar". Uma das diferenças é que está sendo usada a função "AddActorWorldOffset" que adiciona os valores passados como parâmetros ao valor atual de posição: 

Clique para aumentar

A velocidade do "EnemyCar" está definido provisoriamente com o valor "100". No próximo artigo este valor será ajustado de acordo com o nível atual do jogo. Após modificar a posição do "EnemyCar" é chamada a Macro "TestLimit" que verifica se o "EnemyCar" encostou nas laterais da pista ou se já saiu da área de jogo:

Clique para aumentar

Se o "EnemyCar" já passou da base da tela, ele é destruído. Se o "EnemyCar" encostar nas laterais da pista, a direção de seu movimento é invertida.

Faltam alguns detalhes do "EnemyCar" que só poderão ser concluídos no próximo artigo, quando for criado o Blueprint "GameManager" que irá manter as informações do jogo.