Tutorial PSPSDK – Movimentação de Sprites

Hoje iremos aprender como trabalhar com SpriteSheets (folha de sprites) no PSPSDK como esta abaixo:

SpriteSheet Ryu

O PSPSDK possui um biblioteca gráfica que trabalha com imagens png com canais alpha.
Baixe esta classe de graphics :

Graphics

O que vamos utilizar da Graphics?

– Image*
– blitAlphaImageToScreen(int sx, int sy, int width, int height, Image* source, int dx, int dy);

Apenas isto, sendo o Image* (ponteiro para o arquivo de imagem), e o blitAlphaImageToScreen (função que irá desenhar na tela a imagem)

Vamos ao que interessa:

Arquivo main.c (muito parecido com o hello World)

/*****************************************************\
Exemplo de movimentação PSPSDK
Autor : Nei Estrabelli
site  : http://www.neyestrabelli.com
V.0.1 - Versão Beta

\*****************************************************/
#include

#include

#include

#include

#include

#include

#include "graphics.h"
#include "game.h"

PSP_MODULE_INFO("Exemplo de Movimentação", 0, 1, 1);

/**********Thread PSP**********/
int exit_callback(int arg1, int arg2, void *common) {
//THE NEXT LINE IS NEEDED FOR A CLEAN EXIT
sceKernelExitGame();
return 0;
}

/* Callback thread */
int CallbackThread(SceSize args, void *argp) {
int cbid;

cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);

sceKernelSleepThreadCB();

return 0;
}

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void) {
int thid = 0;

thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
if(thid >= 0) {
sceKernelStartThread(thid, 0, 0);
}

return thid;
}
/*********FIM Thread PSP**********/

int main(void)
{
pspDebugScreenInit();  // iniciamos o debug
SetupCallbacks();      // executamos a thread
initGraphics();       //  inciiamos gráfico
Game();               //  executamos o jogo
return 0;
}

Arquivo game.c

/*****************************************************\
Exemplo de movimentação PSPSDK
Autor : Nei Estrabelli
site  : http://www.neyestrabelli.com
V.0.1 - Versão Beta

\*****************************************************/

#include

#include

#include

#include

#include

#include "graphics.h"

#define LIMESQ 0    //definimos o inicio do cenario
#define LIMDIR 416 //definimos o final do cenario, sendo 480(fim da tela) - 64(largura do personagem)

void Game()
{
SceCtrlData pad;     // varival necessária para os controles
int mUpdateCnt = 0;  // variavel para controlar os frames
int PosX = 170;      // posicao inicial do personagem
int frameX = 64;     // tamanho em pixel da primeira imagem da spriteSheet
int frameY = 73;     // inicio da segunda linha da spriteSheet

//carregamos a spriteSheet do Ryu
Image* ryu;
ryu = loadImage("./imagens/ryu.png");

//carregamos a imagem de Fundo (cenario do Akuma)
Image* Fundo;
Fundo = loadImage("./imagens/fundo.png");

//aqui é onde o jogo irá ficar rodando
while(1){
mUpdateCnt++; //incrementamos a variável de controle de frames
sceCtrlReadBufferPositive(&pad, 1); // acionamos o buffer de leitura dos controles

//caso seja pressionado Direcional Esquerda
if (pad.Buttons & PSP_CTRL_LEFT) {
//indicamos que as sprites andando começam do 0 (posição inical da spriteSheet)
frameY = 0;
//verificamos o limite esquerdo
//se a posição X for menor que LIMESQ então dizemos que PosX é igual a LIMESQ
if(PosX < LIMESQ) {
PosX = LIMESQ;
} else {
//caso contrario o personagem anda para a esquera
PosX -= 2;
}
//caso seja pressionado Direcional Esquerda
} else if (pad.Buttons & PSP_CTRL_RIGHT) {
//indicamos que as sprites andando começam do 0 (posição inical da spriteSheet)
frameY = 0;
//verificamos o limite direito
//se a posição X for maior que LIMESQ então dizemos que PosX é igual a LIMESQ
if(PosX > LIMDIR) {
PosX = LIMDIR;
} else {
//caso contrario o personagem anda para a direita
PosX += 2;
}
//caso nenhum direcional seja pressionado
} else {
//indicamos que as sprites de stand começam da altura 73
frameY = 73;
}
//se mUpdateCnt / 10 = 0
if (mUpdateCnt % 10 == 0) {
//somanos frameX ( 64+64) || 64 = 1ª imagem, 128 = 2ª imagem, etc
frameX += frameX;
}
//se frameX for maior que 512 (tamanho máximo de nossa spriteSheet)
if(frameX == 512) {
//reiniciamos o valor para 64
frameX = 64;
}

/*
blitAlphaImageToScreen(int sx, int sy, int width, int height, Image* source, int dx, int dy);
sx     - limite do retangulo na posição horizontal
sy     - inicio do retangulo na posição vertical
width  - largura da imagem
height - altura da imagem
source - imagem alocada com a variavel "Image*"
dx      - posição de movimentação horizontal( 0 caso não tenha)
dy      -  posição de movimentação vertical ( 0 caso não tenha)
*/
blitAlphaImageToScreen(0, 0 , 480, 272, Fundo, 0, 0); //display da imagem de fundo

blitAlphaImageToScreen(frameX, frameY, 64, 73, ryu, PosX, 200); //display do personagem

//funções de refresh
sceDisplayWaitVblankStart();
flipScreen();
}
}

O codigo está bem comentado, sendo assim acho que não é necessário explicação.

Pack completo com o source + arquivo PBP você pode pegar aqui:

Movimentos + SRC
Para rodar o PBP é necessário Custom firmware (SE ou OE), crie uma pasta dentro da GAME150 e copie o EBOOT.PBP + a pasta de imagens, para rodar na versão 1.50 você pode utilizar o PSPBrew para que ele gere a pasta com % em seu devido lugar.

Este exemplo de movimentação ficará desta maneira:

Movimentação PSPSDK

Bom divertimento.

Qualquer dúvida sobre o exemplo comente abaixo.

0 pensou em “Tutorial PSPSDK – Movimentação de Sprites

  1. Caio Romão

    Po, muito legal a Graphics, é sua? As funções me lembraram muito SDL, o que é muito bom. Quem sabe eu não arrisco alguma coisa no PSP algum dia…

    Parabéns pela iniciativa de compartilhar o conhecimento =)

  2. neyestrabelli

    Sorry, eu nao dou curso de desenvolvimento….
    mas existe alguns locais que dão curso…
    por exemplo a faculdade Unicsul – Liberdade (onde faço faculdade de jogos)
    no forum da Unidev (www.unidev.com.br) deve ter mais alguns locais….porem la vc consegue aprender bastante coisa..
    caso vc queira aprender sozinho procure material sobre linguagem C/ C e depois se arrisque nas bibliotecas (SDL, ODE, etc)

  3. Daniel Santana Rodrigues

    neyestrabelli,

    tudo bem cara? tenho estudado o desenvolvimento de jogos e tirei como ponto inicial seu tutorial de movimentação de sprites.

    Sou desenvolvedor a 13 anos, tenho experiência mas no caso da linguagem C estou começando agora.

    Seguindo seu tutorial acima tudo funcionou, porém, consegui alguns Sprites de personagens do Street Fighter e pensei em desenvolver um MUGEN só para estudo. Porém já tem 3 dias que estou tentando carregar uma outra imagem que não a sua do Ryu e nao consigo de jeito nenhum cara. Estou usando o mesmo codigo que voce, so mudei o endereco da imagem, sei que o endereço esta correto e suspeito que o problema seja com a minha imagem, que é no formato PNG 32 (Macromedia Fireworks). Gostaria que se possível você me ajudasse com essa imagem cara, pois estou parado nesse ponto e não consigo andar.

    Se puder e tiver GTalk pode me adicionar se quiser responder por email pode usar o daniel.santana@gmail.com (somente em casa) ou daniel.rodrigues@braxis.com.br (servico)

    Desde já agradeço e parabenizo pelo trabalho.

    Obrigado.
    att,

    Daniel Santana Rodrigues

  4. neyestrabelli

    eae cara blza?
    te aconselho a dar uma olhada na documentação da biblioteca http://www.neyestrabelli.com/OSLib/pt-br/
    e também a pegar o source do mario coins

    http://www.neyestrabelli.com/blog/2007/01/24/mario-coins-to-psp-source/

    Para carregar mais uma imagem basta usar a função

    oslLoadImageFile como no exemplo e quando for desenhar chamar a oslDrawImage();

    seria mais ou menos assim:

    OSL_IMAGE *imagem;
    imagem = oslLoadImageFile(“imagem.png”, OSL_IN_RAM, OSL_PF_5551);
    while (!osl_quit)
    {

    oslStartDrawing();
    oslDrawImage(imagem);
    oslEndDrawing();
    oslSyncFrame();
    }

    Te aconselho a acompanhar a versão 2 da oslib ela esta com documentação mais completa, porém ainda não tem em portugues br, como estou com muito trampo da facu não tive tempo de mexer com ela….

    Boa sorte ae e no que precisar estou aqui para ajudar…
    abraço
    e obrigado por visitar o blog….

  5. Marcos

    blz sim ney =D
    entao… fiz do jeito que vc me disse e tentei compilar somente com somente pspsdk instalado aqui e deu o seguinte erro:
    “main.o: In function `main’:
    main.c:(.text+0x74): undefined reference to `initGraphics’
    main.c:(.text+0x7c): undefined reference to `Game’
    collect2: ld returned 1 exit status
    make: ** [test.elf] Erro 1”
    o que poderia ser? acha que é porque eu nao tenho a oslib instalado aqui?
    estou usando o linux para compilar os arquivos, conseguir compilar outros exemplos que eu encontrei por aí xD
    eu nao encontro como instalar o oslib no linux =/