sexta-feira, 25 de maio de 2012

Platformer Kit: SPG_HUD class (UnrealScript)

Já vimos diversos conceitos relacionados à programação com UnrealScript. Agora chegou a hora de ver todos esses conceitos juntos sendo aplicados em um jogo.

Na UDN (Unreal Developer Network) existe um excelente exemplo de jogo para estudo de UnrealScript que é o Platformer Starter Kit, disponível no link: 

Esta página da UDN possui todas as orientações necessárias para configurar e executar o Kit no UDK.

O código fonte em UnrealScript do Platformer Starter Kit está muito bem comentado. Mesmo assim, algumas partes do código são bem complexas para Iniciantes em UnrealScript. Vou iniciar uma série de artigos analisando as classes UnrealScript existentes no Platformer Starter Kit com o objetivo de gerar um material complementar para ajudar na compreensão do funcionamento deste exemplo de um jogo funcional.

Vamos começar analisando a classe mais simples: SPG_HUD. O único objetivo desta classe é desenhar na parte inferior esquerda da tela o texto "Health:" com o valor numérico que representa a energia atual do jogador, conforme imagem abaixo.


Se você ainda não conhece nada sobre a classe HUD, recomendo a leitura do meu artigo "Desenhando o HUD".

A classe SPG_HUD possui apenas a função PostRender() que contém o seguinte código.
event PostRender()
{
    local float XL, YL;
    local String Text;

    Super.PostRender();

    // Ensure that PlayerOwner and PlayerOwner.Pawn are valid
    if (PlayerOwner != None && PlayerOwner.Pawn != None)
    {
        // Set the text to say Health: and the numerical value of the player pawn's health
        Text = "Health: " $ PlayerOwner.Pawn.Health;
        // Set the font
        Canvas.Font = class'Engine'.static.GetMediumFont();
        // Set the current drawing color
        Canvas.SetDrawColor(255, 255, 255);
        // Get the dimensions of the text in the font assigned
        Canvas.StrLen(Text, XL, YL);
        // Set the current drawing position to the be at the bottom left position with a padding of 4 pixels
        Canvas.SetPos(4, Canvas.ClipY - YL - 4);
        // Draw the text onto the screen
        Canvas.DrawText(Text);
    }
}

Os comentários abaixo estão relacionados a conceitos existentes no código acima.

Existem duas funções principais na classe HUD usadas para desenhar na tela, que são as funções "DrawHud()" e a "PostRender()". A função "DrawHud()" só é chamada se a variável bShowHud for igual a true e se a tabela de pontos não estiver sendo exibida (bShowScores igual a false). Para entender a relação entre as funções "DrawHud()" e "PostRender()", analise a função "PostRender()" da classe HUD (pacote Engine).

A variável PlayerOwner é declarada na classe HUD e representa o PlayerController responsável pelo HUD. A sua inicialização é feita na função "PostBeginPlay()" da classe HUD.

A concatenação de strings pode ser feita com o uso de dois operadores: $ e @. A única diferença entre eles é que o operador @ coloca um espaço em branco entre as strings. Valores numéricos usados na concatenação são automaticamente convertidos para strings. Outra forma de concatenar strings é utilizando os operadores $= e @= que acrescenta uma string a uma variável string já existente. Por exemplo para complementar o texto do HUD com a informação HealthMax, podemos fazer assim:
Text = "Health: " $ PlayerOwner.Pawn.Health;
Text @= "- HealthMax:" @ PlayerOwner.Pawn.HealthMax;

A fonte usada para escrever o texto é obtida a partir de uma função estática da classe Engine. Existem quatro tamanhos pré-definidos de fontes que são obtidas através das funções:
native static final function Font GetTinyFont();
native static final function Font GetSmallFont();
native static final function Font GetMediumFont();
native static final function Font GetLargeFont();

A definição da cor da fonte é feita através da função SetDrawColor() da classe Canvas. A cor é representada no formato RGB, onde cada parâmetro é um byte (0 a 255). Pode ser definido também o elemento Alfa da cor que indica sua opacidade. Existe também a função SetDrawColorStruct() que recebe uma struct do tipo color que representa uma cor. Abaixo temos as duas funções:
native final function SetDrawColor(byte R, byte G, byte B, optional byte A = 255);

/** Set the draw color using a color struct */
final function SetDrawColorStruct(color C)
{
    SetDrawColor(C.R, C.G, C.B, C.A);
}