Um dos valores exibidos na tela é o da variável Time que armazena o tempo que está faltando para encerrar o jogo. Em outro artigo veremos como desenhar os valores das variáveis na tela.
A variável Time inicia com o valor 30. Precisamos de uma forma de diminuir 1 do valor desta variável a cada segundo. Para fazer isto vamos criar um Timer. Um Timer permite que uma função seja executada depois de passar o tempo especificado. Esta função pode ser executada uma única vez ou periodicamente.
Antes de criarmos um Timer, vamos precisar de uma variável do tipo FTimerHandle que será usada para referenciar o Timer que foi criado. Será necessário também criarmos uma função que será executada pelo Timer. A função se chamará Clock().
Abra o arquivo TutoProjectGameMode.h, coloque a variável TimerHandleClock e a declaração da função Clock() no bloco protected abaixo da função BeginPlay() conforme código abaixo.
...
protected:
int32 PlayerLevel;
int32 Score;
int32 ItemCount;
int32 Time;
bool bGameOver;
virtual void BeginPlay() override;
FTimerHandle TimerHandleClock;
void Clock();
};
Um jogo em execução possui um Timer Manager que pode ser acessado usando a função GetWorldTimerManager() em qualquer subclasse de AActor. O Timer Manager possui uma função chamada SetTimer() usada para criar um Timer.
Vamos colocar a criação do Timer dentro da função StartGame() que está no arquivo TutoProjectGameMode.cpp. A função StartGame() vai ficar com este conteúdo:
void ATutoProjectGameMode::StartGame()
{
Score = 0;
PlayerLevel = 1;
ItemCount = 0;
Time = 30;
bGameOver = false;
GetWorldTimerManager().SetTimer(TimerHandleClock, this, &ATutoProjectGameMode::Clock,
1.0f, true);
}
A função SetTimer() está recebendo cinco parâmetros, vamos analisar a chamada da função e cada um dos parâmetros:
- GetWorldTimerManager().SetTimer() : A primeira coisa que acontece nesta linha é a execução da função GetWorldTimerManager() que retorna uma instância do tipo FTimeManager. Depois disso é executada a função SetTimer() da instância FTimeManager que foi retornada.
- TimerHandleClock : Este é o primeiro parâmetro da função SetTimer(). TimerHandleClock é a variável do tipo FTimerHandle que criamos. Ela será preenchida com as informações necessárias para posteriormente podermos referenciar o Timer que será criado.
- this : Esta é uma palavra chave do C++ que referencia a instância que está sendo executada neste momento. É semelhante a palavra Self usada em Blueprints.
- &ATutoProjectGameMode::Clock : Neste parâmetro informamos qual é a função que será executada pelo Timer. Observe que antes da identificação da função tem o operador &. Este operador é usado para retornar o endereço de memória da função. A identificação da função é composto pelo nome da classe, o operador de resolução de escopo :: e pelo nome da função sem parênteses.
- 1.0f : Este parâmetro indica o tempo em segundos que o Timer deve esperar antes de executar a função. Este é um valor do tipo float. Vamos analisar o tipo float em outro artigo.
- true : Este parâmetro booleano é o de Loop. Se for true então o Timer executará a função periodicamente. Se for false, a função será executada apenas uma vez.
A função SetTimer() é equivalente ao node Blueprint chamado Set Timer by Function Name que está na imagem abaixo.
Falta apenas a definição da função Clock() para concluirmos o nosso Timer. Adicione o código abaixo no final do arquivo TutoProjectGameMode.cpp.
void ATutoProjectGameMode::Clock()
{
if (Time > 0)
{
Time--;
}
else
{
bGameOver = true;
GetWorldTimerManager().ClearTimer(TimerHandleClock);
}
}
O Timer executa a função Clock() uma vez a cada segundo. Usamos o condicional if para testar se o valor da variável Time é maior que zero. Se for verdadeiro então a variável Time é decrementada, ou seja, o seu valor é diminuído de 1.
Se o resultado da expressão do if for falso, então o bloco else será executado. No bloco else, a variável booleana bGameOver recebe o valor true para indicar que o jogo acabou. Depois é chamada a função ClearTime() para parar a execução do Timer que criamos.