quinta-feira, 29 de março de 2007

Colocando a Mão nos Fundos


Vamos usar essas imagens que foram baixadas e convertidas. A intenção é fazer um programa onde os fundos corram da direita para a esquerda, o fundo mais da frente mais rápido e o mais de trás mais lento, para dar a sensação de profundidade. O sprite do avião deverá se mover conforme pressionamos o direcional.

Copie o conteúdo de PATemplate para uma nova pasta. Entre em source e crie uma pasta chamada "gfx". Copie os arquivos gerados pelo PAGfx (incluindo o PAGfx.ini) para a pasta "gfx" criada. Não é necessário copiar a pasta bin e seu conteúdo. Dois clicks em "Template.pnproj". Abra a pasta source e edite o arquivo main.c. Coloque o seguinte conteúdo nele:

// Includes
#include <pa9.h> // Include for PA_Lib

#include "gfx/all_gfx.c"
#include "gfx/all_gfx.h"

// Function: main()
int main(int argc, char ** argv)
{
  //variaveis
  s32 x=95;
  s32 y=79;
  s32 scrl=0;

  //programa
  PA_Init(); // Initializes PA_Lib
  PA_InitVBL(); // Initializes a standard VBL

  PA_EasyBgLoad(1, 0, fundo3);
  PA_EasyBgLoad(1, 1, fundo4);
  PA_EasyBgLoad(1, 2, fundo5);

  PA_InitParallaxX(1, 512, 256, 128, 0);

  PA_LoadSpritePal(1, 0, (void*)aviao_Pal);
  PA_CreateSprite(1, 0, (void*)aviao_Sprite, OBJ_SIZE_64X32, 1, 0, x, y);

  // Infinite loop to keep the program running
  while (1)
  {
    scrl ++;
    PA_ParallaxScrollX(1, scrl);

    x += (Pad.Held.Right - Pad.Held.Left) * 2;
    y += (Pad.Held.Down - Pad.Held.Up) * 2;
    if (y<0) y=0;
    if (y>159) y=159;
    if (x<0) x=0;
    if (x>191) x=191;

    PA_SetSpriteXY(1,0,x,y);

    PA_WaitForVBL();
  }

  return 0;
} // End of main()

Como o programa funciona:
  • Inicializa as variáveis x, y (que serão a posição do canto superior esquerdo do sprite) e a variável scrl (que será o valor auxiliar do scroll da tela).
  • Carrega, na tela 0, no background mais da frente (zero), o arquivo gerado a partir da imagem "fundo3".
  • Carrega, na tela 0, no background nivel 1, o arquivo gerado de "fundo4".
  • Carrega, na tela 0, no BG2, o "fundo5".
  • Define o Parallax dos fundos. Parallax é um recurso da PAlib para a movimentação de fundos. No caso, vamos setar apenas o ParallaxX (somente horizontal). Os parâmetros de PA_InitParallaxX são: tela, velocidade_BG0, velocidade_BG1, velocidade_BG2 e velocidade_BG3. As velocidades seguem a seguinte lógica: 256 é um pixel a cada frame de animação. Valores maiores aumentam a velocidades (mais pixels por frame), valores menores diminuem a velocidade (demora mais frames para mover um pixel). Por exemplo: velocidade=512 irá mover dois pixels por frame, 1024 irá mover 4 pixels; 128 irá mover um pixel a cada 2 frames, 64 moverá um pixel a cada 4 frames, 96 moverá um pixel a cada 3 frames. 0 (zero) significa que esse fundo não será afetado pelo parallax.
  • Carrega a paleta de cores do sprite na tela 1, na paleta 0 da memória de vídeo, usando a paleta gerada pela imagem do avião.
  • Cria o sprite na tela 1, identificado como 0, usando a imagem do avião, de tamanho 64x32 (OBJ_SIZE_64X32), em modo 256 cores (1), usando a paleta 0, posicionado em x,y.
  • Começa o loop infinito do jogo.
  • Aumenta scrl (soma 1 a scrl).
  • Move o parallax da tela 1 conforme o valor de scrl.
  • Se for pressionado para a direita, x é acrescido de 2. Se for pressionado para a esquerda, x é decrescido de 2. Se nenhum dos dois for pressionado, x se mantém igual (lembram o que eu escrevi no segundo artigo?)
  • Se for pressionado para baixo, y é acrescido de 2. Se for pressionado para cima, y é decrescido de 2. Se nenhum dos dois for pressionado, y permanece igual.
  • Verifica que o sprite não passe dos limites da tela (x não pode ser menor que 0 nem maior que 191, ou seja, 255-64; y não pode ser menor que 0 e nem maior que 159, ou seja, 191-32). Se o sprite passar do limite da tela, ele deve ser resetado para o limite da tela. Reparem também que nesta seqüência de IFs eu não usei as chaves; se o if executar um comando apenas, elas não são necessárias.
  • Posiciona, na tela 1, o sprite 0 na posição x,y
  • Aguarda o processamento do frame.
  • Encerra o loop, como ele é infinito, volta para o início do loop.

Um comentário:

Leonardo Zimbres disse...

Massa. Muito prático. Ao contrário do actionscript, to passando por cada uma com ele...