Ponto V!

Home C/C++ GS2 GS2D e C++: áudio, input e textos
André Santee
GS2D e C++: áudio, input e textosImprimir
Escrito por André Santee

No primeiro artigo da série sobre GS2D nós vimos como criar uma janela e desenhar sprites com a biblioteca. Nele conseguimos ter uma idéia de como é fácil utilizar a biblioteca. O artigo foi bem básico mas teve uma boa repercussão e eu fiquei respondendo e-mails com dúvidas sobre ele durante semanas após sua publicação (o que é ótimo!). Neste veremos como desenhar bitmap fonts e utilizar o componente de áudio e input da biblioteca.

O pré-requisito para acompanhar este artigo sem problemas é ter lido (e entendido todo) o primeiro artigo dessa série, então, a partir daqui, vamos assumir que o leitor tenha acompanhado toda a primeira parte.

Desenhando bitmap fonts

Bitmap font rendering é o nome dado à técnica que consiste em gerar textos a partir de caracteres (letras e símbolos) retirados de bitmaps, como a imagem a seguir:

Verdana20_shadow

A GS2D utiliza as fontes em bitmap do formato FNT (em texto), da Bitmap Font Generator da AngelCode. Neste formato, o arquivo FNT descreve as coordenadas e dimensões de cada caractere do bitmap e os nomes dos arquivos PNG que utiliza. No exemplo dado neste artigo utilizaremos a fonte Verdana20_shadow.fnt que, por sua vez, baseia-se na imagem Verdana20_shadow.png.

Desenhar textos é muito simples, basta utilizar o método:

Video::DrawBitmapText(const math::Vector2 &v2Pos, const std::wstring& text,
                      const std::wstring& font, const GS_COLOR color)

Exemplo:

video->DrawBitmapText(Vector2(30, 20), L"Texto que quero desenhar", L"Verdana20_shadow.fnt", GS_WHITE);

A biblioteca irá buscar o arquivo FNT assim como seus respectivos PNG's, no diretório passado no parâmetro bitmapFontDefaultPath da função CreateVideo (ver no primeiro artigo).

Não se esqueça de que o método DrawBitmapText deve ficar entre BeginSpriteScene e EndSpriteScene assim como o desenho de qualquer outro sprite. De fato, a biblioteca utilizará sprites convencionais para gerar os textos.

Utilizando o componente de áudio

Assim como para utilizar a parte de vídeo da GS2D precisamos instanciar o objeto Video (utilizado na forma de SpritePtr), o áudio da biblioteca fica por conta do objeto Audio (AudioPtr). Para instanciar este objeto utilizamos a função CreateAudio:

AudioPtr audio = CreateAudio(0);

O valor passado como parâmetro é reservado e não é utilizado nesta implementação, portanto podemos passar 0 sem preocupações. Com o objeto instanciado, podemos começar o carregamento dos efeitos sonoros. O objeto AudioSample (AudioSamplePtr) representa uma instancia de faixa de áudio (efeito sonoro ou música) de um arquivo MP3, OGG ou WAV:

AudioSamplePtr sample = audio->LoadSampleFromFile(L"win.ogg", GSST_SOUND_EFFECT);

GSST_SOUND_EFFECT indica que estamos carregando um efeito sonoro de curta duração, assim ele pode ser carregado na íntegra para a memória, o que torna sua execução muito mais rápida. Para arquivos mais longos, como de músicas, passamos GSST_MUSIC para executar a faixa em streaming.

Os métodos AudioSample::Play, ::Pause e ::Stop controlam a execução da faixa. Não se esqueça que ao executar o método ::Play, a faixa será reiniciada.

Entrada de dados

O objeto Input (InputPtr) é aquele que cuida da entrada de dados. Com ele é possível ler a entrada do teclado, mouse e joysticks:

InputPtr input = CreateInput(0, false);

A função CreateInput instancia o objeto. O argumento 0 é reservado e inutilizado. No segundo parâmetro passamos true se queremos receber alertas referentes a joysticks (úteis caso o jogo vá utiliza-los) ou false se não queremos.

Uma vez instanciado, para que funcione corretamente, o objeto Input requer que seu método ::Update seja chamado uma vez (apenas UMA vez) no início de cada repetição do laço principal:

Video::APP_STATUS status;
while ((status = video->HandleEvents()) != Video::APP_QUIT)
{
    if (status == Video::APP_SKIP)
        continue;

    input->Update();
    video->BeginSpriteScene();
    video->EndSpriteScene();
}

Neste artigo veremos apenas alguns dos métodos mais comuns. Com o método Input::GetKeyState(GS_KEY) informamos o código da tecla (teclado ou mouse) que queremos verificar e este retornará um dos quatro valores a seguir:

  • GSKS_HIT: a tecla acaba de ser pressionada
  • GSKS_DOWN: o usuário está segurando a tecla
  • GSKS_RELEASE: o usuário acabou de soltar a tecla
  • GSKS_UP: a tecla não está sendo pressionada.

Em GS_KEY podemos passar qualquer um dos valores enumerados abaixo:

GSK_UP,
GSK_DOWN,
GSK_LEFT,
GSK_RIGHT,
GSK_PAGEDOWN,
GSK_PAGEUP,
GSK_SPACE,
GSK_ENTER,
GSK_DELETE,
GSK_HOME,
GSK_END,
GSK_INSERT,
GSK_PAUSE,
GSK_ESC,
GSK_BACK,
GSK_TAB,
GSK_PRINTSCREEN,
GSK_SUBTRACT,
GSK_ADD,
GSK_F1 - GSK_F24,
GSK_A - GSK_Z,
GSK_0 - GSK_9,
GSK_MINUS,
GSK_PLUS,
GSK_COMMA,
GSK_DOT,
GSK_CTRL,
GSK_ALT,
GSK_SHIFT,
GSK_RMOUSE,
GSK_LMOUSE,
GSK_MMOUSE e
GSK_NUMPAD0 - GSK_NUMPAD9.

Verificar o estado de uma tecla é muito simples:

if (input->GetKeyState(GSK_P) == GSKS_HIT)
    sample->Play(); // se o usuário pressionar P, reproduza a faixa

Temos também outros métodos muito úteis, como Input::GetCursorPositionF que retorna um Vector2 contendo a posição atual do cursor do mouse.

Exemplo geral

O exemplo a seguir utiliza todas as novidades apresentadas neste artigo:

#include "../gs2d.h"
#include "../gs2dinput.h"
#include "../gs2daudio.h"

using namespace gs2d;
using gs2d::math::Vector2;

int main()
{
    VideoPtr video;

    if ((video = CreateVideo(800, 600, L"Fontes, som e input", true, true, L"fonts/")))
    {
        InputPtr input = CreateInput(0, false);
        AudioPtr audio = CreateAudio(0);

        AudioSamplePtr sample = audio->LoadSampleFromFile(L"win.ogg", GSST_SOUND_EFFECT);

        video->SetBGColor(math::ARGB(255, 30, 127, 200));

        Video::APP_STATUS status;
        while ((status = video->HandleEvents()) != Video::APP_QUIT)
        {
            if (status == Video::APP_SKIP)
                continue;

            input->Update();

            video->BeginSpriteScene();

            video->DrawBitmapText(Vector2(10, 10),
                L"P: play\nS: stop\nR: pause",
                L"Verdana20_shadow.fnt", GS_WHITE);

            if (input->GetKeyState(GSK_P) == GSKS_HIT)
                sample->Play();

            if (input->GetKeyState(GSK_S) == GSKS_HIT)
                sample->Stop();

            if (input->GetKeyState(GSK_R) == GSKS_HIT)
                sample->Pause();

            video->DrawBitmapText(input->GetCursorPositionF(video)+Vector2(20, 0),
                L"Segue o cursor do mouse", L"Verdana20_shadow.fnt", GS_BLACK);

            video->EndSpriteScene();
        }
    }
    return 0;
}

Baixe também os recursos utilizados no exemplo.

Feedback e próximos passos

Neste artigo procurei sanar as dúvidas e dificuldades levantadas por muitos dos que leram o último artigo e trazer com mais clareza as instruções sobre essas funcionalidades mais básicas da biblioteca. Faço também um agradecimento especial ao leitor Tácio Dias Palhão Mendes (@FoxTacy), que enumerou esses principais tópicos de dúvida e escreveu a estrutura básica desse artigo.

Um feedback por parte dos leitores será muito útil para que eu possa preencher possíveis lacunas neste artigo.

Nos vemos na próxima!


Comentários (2)
  • pavanetti  - 
    avatar

    Essa biblioteca é baseada em opengl ou directx? Pelo que vi todas as outras dependencias dela são multiplaforma, como a boost e a libpng. Tava querendo usar ela no linux. Sabe se alguém já compilou ela no linux?
    Se der, pode me dizer o que tenho que compilar linkando com o que?

  • André
    avatar

    Atualmente a única implementação desktop da biblioteca utiliza Direct3D, então ela compila somente no Windows.
    Eu estou procurando alguém com boa experiência em OpenGL e de preferência que já tenha tido algum contato com a linguagem Cg da NVIDIA para fazer a implementação SDL/OpenGL das classes gs2d::Video, gs2d::Shader, gs2d::ShaderContext, gs2d::Texture e gs2d::Sprite. Com isso, vai ser possível cross-compilar ela também em Linux e Mac!
    Eu havia prometido esse porte para o primeiro semestre desse ano, mas aqui no trabalho acabamos decidindo entrar no desenvolvimento mobile então tive que trabalhar num porte OpenGL ES 2.0. A boa notícia é que a biblioteca já roda também no Android e provavelmente no iPhone (que ainda não testei, mas deve funcionar sem maiores alterações na parte gráfica).
    A implementação OpenGL ES 2.0 encontra-se aqui: http://ethanon.svn.sourceforge.net/viewvc/ethanon/trunk/toolkit/Source /src/gs2d/src/Video/GLES2/
    A versão ES da API é parecida com a do desktop, mas como não existe fixed pipeline na ES 2.0, a forma de renderização é um pouco diferente.
    Alguém se cadidata?

Escrever um comentário
Your Contact Details:
Gravatar enabled
Comentário:
[b] [i] [u] [url] [quote] [code] [img]   
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch::(:shock:
:X:side::):P:unsure::woohoo::huh::whistle:;):S:!::?::idea::arrow:
Security
Por favor coloque o código anti-spam que você lê na imagem.
LAST_UPDATED2  

Busca

Linguagens

Twitter