quinta-feira, 7 de abril de 2011

Usando e Brincando com a GS2D.



Resolvi estudar a GS2D feita por André Santee, e gostei bastante dos resultados. Aí resolvi escrever um pequeno tutorial e colocar aqui no Ponto V.

Os três únicos pré-requisitos são:

- Ter lido o primeiro post sobre a GS2D;
- Ter realizado todos os passos do post;
- Ser familiar com as sintaxes do C++.

Bom, vamos ao que interessa.

1- Criando efeitos sonoros:

As seguinte linha tem como finalidade criar um smartpointer para o sistema de audio e inicializá-lo.

AudioPtr audio = CreateAudio(0);

As seguintes linhas tem como finalidade criar um smartpointer para o seu efeito sonoro ou música, e carrega-lo no sistema da GS2D para ser usado.
A constante GSST_SOUND_EFFECT é uma constante que diz que o sample carregado é um efeito sonoro.
Você tem outras opções de constante, para música por exemplo você usaria: GSST_MUSIC
Para efeitos sonoros de ambiente você usaria GSST_AMBIENT_SFX e assim por diante.

AudioSamplePtr asp;
asp = audio->LoadSampleFromFile(L"pastaOndeEstaoOsRecursos/efeitoSonoro.formato", GSST_SOUND_EFFECT);

As seguintes linhas, você deve colocar dentro do seu loop de jogo.
while(true){
asp->Play();
}

Provavelmente você vai querer toca-lo quando objetos colidirem, ou quando você realizar alguma ação com seu ator de jogo, por exemplo. O que cria a necessidade de você saber ler inputs.

2- Lendo inputs:

Primeiro você precisa de um InputPtr

InputPtr input = CreateInput(0,true);

A cada iteração do loop de jogo você precisa chamar o Update para atualizar o estado de todas as teclas do teclado.

input->Update();

Para checar o estado de uma tecla:

if (input->GetKeyState(GSK_ESC == GSKS_DOWN)){
//fazer algo
}

Você pode perceber que são bem intuitivos os prefíxos da GS2D. GSK_ é um prefixo para constantes de teclas (GameSpaceKey) e GSKS_ para estado de teclas (GameSpaceKeyState).

Você pode checar outros valores possíveis pelo recurso auto completar na sua IDE, caso ela tenha esse recurso disponível.

3- Desenhando Texto

video = CreateVideo(larguraTela,alturaTela, L"Titulo",ehWindowed,permitirvsync,L"pastaOndeEstaoSeusArquivosFnt/",GSPF_UNKNOWN,ehMaximizavel);

Para poder desenhar texto com a GS2D tem um detalhe importante que você precisa prestar atenção ao inicializar a engine. Você precisa passar o nome da pasta onde estão seus arquivos .FNT. Você também precisará de um arquivo .bmp com a fonte "BitMapizada" (se me permite o neologismo). Você pode criar esses dois arquivos usando o programa: AngelCode Bitmap Font generator

Para desenhar texto, dentro do seu loop onde você desenha as coisas na tela:

video->DrawBitmapText(Vector2(cordenadax,cordenaday), L"textoQueDesejaEscrever", L"nomeDaFonte.fnt",gs2d::GS_WHITE);

4- Desenhando Sprites animadas:

Primeiro você precisa de um SpritePtr, que deve ser criado pelo seu sistema de video (VideoPtr)

SpritePtr suaSprite = video->CreateSprite(L"suaPastaDeRecursos/nomeDaSprite.png");

Para ela ser uma sprite animada, você precisa que a sua imagem com a spritesheet seja dividida em frames, e que cada frame tenha exatamente o mesmo tamanho.

A propósito, isso geralmente é padrão nas engines.

Entretanto, o seu arquivo onde está a spritesheet, difícilmente seguirá um padrão. Já vi spritesheets de vários tamanhos com mais ou menos frames.

Para usar sprites animadas, você deve configurar o número de retangulos de sprite pela linha:

suaSprite->SetupSpriteRects(colunas,linhas);

Segue a sprite sheet que usei como exemplo:


Em seguida dentro do seu loop onde está a lógica de desenho você precisa dizer qual é o retangulo atual pela linha:

suaSprite->SetRect(coluna,linha);

Você precisa montar a sua lógica de animação tendo em vista como cada engine de jogos acessa e trata as spritesheets.

Por exemplo, em uma spritesheet como essa que mostrei: a animação do personagem andando para baixo está na primeira linha, para esquerda na segunda, e assim por diante.

Você poderia criar um enumerador que diz qual é a animação, e um array que diz a ordem dos frames:

O enumerador seria por exemplo:

enum {ANIM_ANDABAIXO = 0, ANIM_ANDAESQUERDA, ANIM_ANDADIREITA,ANIM_ANDACIMA}

E o array da ordem dos frames poderia ficar assim:

short frames[4] = {0,1,2,1};
short frameAtual = 0;
short animAtual = 0;

Em seguida dentro do seu loop de desenho você precisaria usar isso tudo da seguinte forma:

if (frameAtual == 4) frameAtual = 0; //4 porque o vetor vai da posição 0 a 3 portanto 4 é uma posição inválida.
suaSprite->SetRect(animAtual,frames[frameAtual]);
frameAtual++;

Você precisa tratar esses valores na lógica de jogo, como no exemplo:

if (input->getKeyState(GSK_W) == GSKS_HIT) animAtual = ANIM_ANDACIMA;
if (input->getKeyState(GSK_A) == GSKS_HIT) animAtual = ANIM_ANDAESQUERDA;
if (input->getKeyState(GSK_S) == GSKS_HIT) animAtual = ANIM_ANDABAIXO;
if (input->getKeyState(GSK_D) == GSKS_HIT) animAtual = ANIM_ANDADIREITA;

Nesse exemplo usei ao invés das setas, as teclas w,a,s,d comumente usada nos jogos.

Bom, isso foi tudo que eu estudei, da GS2D.

Os meu próximo passo é tentar Integrar a Box2D ou alguma outra engine de física com a GS2D. Porém, destruir um planeta com uma pedrada é infinitamente mais fácil do que usar a Box2D com C++.

Espero que tenham gostado deste post!

Agradecimentos especiais a @tifaucz por ajudar a pesquisar algumas funcionalidades da GS2D :D

FoxT out.

PS: Não deixe de conferir o post do próprio autor no pontoV :)

Nenhum comentário:

Postar um comentário

Tem algo a dizer sobre isso? Diga!