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.

Compare Preços de: cybershot, games, psp, umd, livros no JáCotei.

8 Responses

  1. Caio Romão Says:

    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 Says:

    Essa graphics é propria do PSPSDK, nunca mexi com SDL, apenas fiz os tutoriais da Cuba Games mas ainda não apliquei nada…..

  3. Romulo De Lazzari Says:

    Curto e grosso!
    Nota 10!

    ps: Pena eu ter pegado num PSP uma vez só na minha vida ;|

    ps2: e realmente (concordando com o Caio) é muito parecido com SDL

  4. DEAD ANGEL Says:

    Cara curto muito jogos, e queria aprender a fazer, eu gostaria de saber se vc não da curso????

  5. neyestrabelli Says:

    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)

  6. Daniel Santana Rodrigues Says:

    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

  7. neyestrabelli Says:

    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….

  8. Felix Says:

    qual lib de png você usou?
    Grato

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.