Game background is flashing, character leaving trails

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
Acegikmo
Posts: 15
Joined: Sat Jul 19, 2008 1:18 am

Game background is flashing, character leaving trails

Post by Acegikmo »

Hello :)
I'm really new to PSP programming, but I've done a little C++ before.
Anyway, I'm having trouble with my game.
I'm trying to display a background and be able to move a character on the screen.
So I made the background and the character in photoshop, saved as PNG.
The character is transparent at some pixels.
But the background is flashing and the character leaves a trail after itself.
It's not removing the previously drawn character.
Here's the code:

Code: Select all

// C-Application, png test

#include <pspdisplay.h>
#include <pspctrl.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspgu.h>
#include <png.h>
#include <stdio.h>
#include "graphics.h" 

#define printf pspDebugScreenPrintf
#define MAX&#40;X, Y&#41; &#40;&#40;X&#41; > &#40;Y&#41; ? &#40;X&#41; &#58; &#40;Y&#41;&#41;

PSP_MODULE_INFO&#40;"Png image display in C", 0, 1, 1&#41;; 
/* Exit callback */
int exit_callback&#40;int arg1, int arg2, void *common&#41; &#123;
          sceKernelExitGame&#40;&#41;;
          return 0;
&#125;

/* Callback thread */
int CallbackThread&#40;SceSize args, void *argp&#41; &#123;
          int cbid;

          cbid = sceKernelCreateCallback&#40;"Exit Callback", exit_callback, NULL&#41;;
          sceKernelRegisterExitCallback&#40;cbid&#41;;

          sceKernelSleepThreadCB&#40;&#41;;

          return 0;
&#125;

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks&#40;void&#41; &#123;
          int thid = 0;

          thid = sceKernelCreateThread&#40;"update_thread", CallbackThread, 0x11, 0xFA0, 0, 0&#41;;
          if&#40;thid >= 0&#41; &#123;
                    sceKernelStartThread&#40;thid, 0, 0&#41;;
          &#125;

          return thid;
&#125; 



int main&#40;&#41;
&#123;
    char buffer&#91;200&#93;;
    Image* ourImage;
    pspDebugScreenInit&#40;&#41;;
    SetupCallbacks&#40;&#41;;
    initGraphics&#40;&#41;; 
    SceCtrlData pad; 
    int x=480/2;
    int y=272/2;
    int y2=0;
    int x2=0;
    
    sprintf&#40;buffer, "Image.png"&#41;;
    ourImage = loadImage&#40;buffer&#41;; 
    if &#40;!ourImage&#41; 
    &#123;
       printf&#40;"Image load failed!\n"&#41;;
    &#125; 
    else 
    &#123; 
         sceDisplayWaitVblankStart&#40;&#41;; 
         blitAlphaImageToScreen&#40;0 ,0 ,480 , 272, ourImage, 0, 0&#41;;
         flipScreen&#40;&#41;;
    &#125; 
    while&#40;1&#41;
    &#123;
        sceCtrlReadBufferPositive&#40;&pad, 1&#41;;
            
        sprintf&#40;buffer, "Eye.png"&#41;;
        ourImage = loadImage&#40;buffer&#41;; 
        if &#40;!ourImage&#41; 
        &#123;
           printf&#40;"Image load failed!\n"&#41;;
        &#125; 
        else 
        &#123; 
             sceDisplayWaitVblankStart&#40;&#41;; 
             blitAlphaImageToScreen&#40;0 ,0 ,16 , 16, ourImage, x, y&#41;;
             flipScreen&#40;&#41;;
        &#125;
        
        if&#40;pad.Buttons & PSP_CTRL_DOWN&#41;
                       y++;
                
        if&#40;pad.Buttons & PSP_CTRL_UP&#41;
                       y--;
                       
        if&#40;pad.Buttons & PSP_CTRL_RIGHT&#41;
                       x++;
                
        if&#40;pad.Buttons & PSP_CTRL_LEFT&#41;
                       x--;
    &#125;
    sceKernelSleepThread&#40;&#41;;
    return 0;
&#125; 
Background:

Image PataPon style :)
Character:

Image


Do you know how to fix this?
hibbyware
Posts: 78
Joined: Wed Mar 28, 2007 10:29 am

Post by hibbyware »

Blit the background every loop not just once before the loop,

Also you should load the images once before your while loop not multiple times within the while loop,
Acegikmo
Posts: 15
Joined: Sat Jul 19, 2008 1:18 am

Post by Acegikmo »

How would I write the code then?
I'm not sure how the image loading works
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Code: Select all

    sprintf&#40;buffer, "Image.png"&#41;;
    backImage = loadImage&#40;buffer&#41;;
    if &#40;!backImage&#41;
    &#123;
       printf&#40;"Background Image load failed!\n"&#41;;
    &#125;
    sprintf&#40;buffer, "Eye.png"&#41;;
    eyeImage = loadImage&#40;buffer&#41;;
    if &#40;!eyeImage&#41;
    &#123;
       printf&#40;"Eye Image load failed!\n"&#41;;
    &#125;

    while&#40;backImage && eyeImage&#41;
    &#123;
        blitImageToScreen&#40;0 ,0 ,480 , 272, backImage, 0, 0&#41;;
        blitAlphaImageToScreen&#40;0 ,0 ,16 , 16, eyeImage, x, y&#41;;
        sceDisplayWaitVblankStart&#40;&#41;;
        flipScreen&#40;&#41;;
       
        sceCtrlReadBufferPositive&#40;&pad, 1&#41;;
        if&#40;pad.Buttons & PSP_CTRL_DOWN&#41;
                       y++;
               
        if&#40;pad.Buttons & PSP_CTRL_UP&#41;
                       y--;
                       
        if&#40;pad.Buttons & PSP_CTRL_RIGHT&#41;
                       x++;
               
        if&#40;pad.Buttons & PSP_CTRL_LEFT&#41;
                       x--;
    &#125;
Acegikmo
Posts: 15
Joined: Sat Jul 19, 2008 1:18 am

Post by Acegikmo »

Thanks, I'll try that :)
Acegikmo
Posts: 15
Joined: Sat Jul 19, 2008 1:18 am

Post by Acegikmo »

Works great!
What method is the best way to make a character fire bullets?
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Acegikmo wrote:Works great!
What method is the best way to make a character fire bullets?
Same as the eye - just start the coords at the player position + an offset for where his gun is, then move the bullet in a constant direction at a constant speed until it hits something or reaches its limit. If it's something more than just a dot, you'll need different versions of the image that show the bullet in the proper rotation for the direction it's headed. If it were something like a fireball, you might have different images that make it pulse or rotate. You'd just cycle through those images as the thing moved.
Acegikmo
Posts: 15
Joined: Sat Jul 19, 2008 1:18 am

Post by Acegikmo »

I just don't know how to do it.
One bullet is fine.
One piece of code to loop through all the time.
But multiple bullets is a problem; I don't know where to start.

Should I make a Structure like this?

Code: Select all

typedef struct
    &#123;
            int x=0;
            int y=0;
            bool on=0;
    &#125; Bullet;
Could you make a simple example where the character drops a bomb that falls and disappears when it reaches the bottom of the screen?

Here's the code so far:

Code: Select all

int main&#40;&#41;
&#123;
    char buffer&#91;200&#93;;
    Image* backImage;
    Image* eyeImage;
    pspDebugScreenInit&#40;&#41;;
    SetupCallbacks&#40;&#41;;
    initGraphics&#40;&#41;; 
    SceCtrlData pad; 
    int ex=480/2;
    int ey=272/2;
//    typedef struct
//    &#123;
//            int x=0;
//            int y=0;
//            bool on=0;
//    &#125; Bullet;
    
    sprintf&#40;buffer, "Image.png"&#41;;
    backImage = loadImage&#40;buffer&#41;;
    if &#40;!backImage&#41;
    &#123;
       printf&#40;"Background Image load failed!\n"&#41;;
    &#125;
    sprintf&#40;buffer, "Eye.png"&#41;;
    eyeImage = loadImage&#40;buffer&#41;;
    if &#40;!eyeImage&#41;
    &#123;
       printf&#40;"Eye Image load failed!\n"&#41;;
    &#125;
    double i=0;
    while&#40;backImage && eyeImage&#41;
    &#123;
        blitImageToScreen&#40;0 ,0 ,480 , 272, backImage, 0, 0&#41;;
        blitAlphaImageToScreen&#40;0 ,0 ,16 , 16, eyeImage, ex, ey&#41;;
        sceDisplayWaitVblankStart&#40;&#41;;
        flipScreen&#40;&#41;;
        sceCtrlReadBufferPositive&#40;&pad, 1&#41;;
        if&#40;pad.Buttons & PSP_CTRL_DOWN&#41;
                       ey+=1;
               
        if&#40;pad.Buttons & PSP_CTRL_UP&#41;
                       ey-=1;
                       
        if&#40;pad.Buttons & PSP_CTRL_RIGHT&#41;
                       ex+=1;
               
        if&#40;pad.Buttons & PSP_CTRL_LEFT&#41;
                       ex-=1;
    &#125; 
    sceKernelSleepThread&#40;&#41;;
    return 0;
&#125; 
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Code: Select all

#define NUM_BOMBS 4

struct bomb &#123;
    int x, y;
    /* extend as you add stuff */
&#125;;

/* global so that you can access from any function */
int ex=480/2;
int ey=272/2;
struct bomb bombs&#91;NUM_BOMBS&#93;;

int main&#40;&#41;
&#123;
    char buffer&#91;200&#93;;
    Image* backImage;
    Image* eyeImage;
    Image* bombImage;
    int all_images;
    SceCtrlData pad;
    unsigned int old_buttons = 0;
    int current_bomb = 0;

    pspDebugScreenInit&#40;&#41;;
    SetupCallbacks&#40;&#41;;
    initGraphics&#40;&#41;;

    /* init game objects */
    for &#40;i=0; i<NUM_BOMBS; i++&#41; &#123;
        bombs&#91;i&#93;.x = bombs&#91;i&#93;.y = -1;
    &#125;

    /* init images */
    sprintf&#40;buffer, "Image.png"&#41;;
    backImage = loadImage&#40;buffer&#41;;
    if &#40;!backImage&#41;
    &#123;
       printf&#40;"Background Image load failed!\n"&#41;;
    &#125;
    sprintf&#40;buffer, "Eye.png"&#41;;
    eyeImage = loadImage&#40;buffer&#41;;
    if &#40;!eyeImage&#41;
    &#123;
       printf&#40;"Eye Image load failed!\n"&#41;;
    &#125;
    sprintf&#40;buffer, "Bomb.png"&#41;;
    bombImage = loadImage&#40;buffer&#41;;
    if &#40;!bombImage&#41;
    &#123;
       printf&#40;"Bomb Image load failed!\n"&#41;;
    &#125;
    all_images = backImage && eyeImage && bombImage;

    while&#40;all_images&#41;
    &#123;
        int i;
        unsigned int new_buttons;

        /* get inputs */
        sceCtrlReadBufferPositive&#40;&pad, 1&#41;;
        new_buttons = pad.Buttons ^ old_buttons;
        old_buttons = pad.Buttons;

        /* process inputs */
        if&#40;pad.Buttons & PSP_CTRL_SELECT&#41;
            break; /* exit look when press select */
        if&#40;pad.Buttons & PSP_CTRL_DOWN&#41;
                       ey+=1;
        if&#40;pad.Buttons & PSP_CTRL_UP&#41;
                       ey-=1;
        if&#40;pad.Buttons & PSP_CTRL_RIGHT&#41;
                       ex+=1;
        if&#40;pad.Buttons & PSP_CTRL_LEFT&#41;
                       ex-=1;
        if&#40;new_buttons & PSP_CTRL_CROSS && pad.Buttons & PSP_CTRL_CROSS&#41;
        &#123;
            /* if you "fire" more than NUM_BOMBS, the first one&#40;s&#41; will just
              disappear from where they are and become the new bomb&#40;s&#41; */
            bombs&#91;current_bomb&#93;.x = ex;
            bombs&#91;current_bomb&#93;.y = ey+8;
            current_bomb = &#40;current_bomb+1&#41; % NUM_BOMBS;
        &#125;

        /* process game objects */
        for &#40;i=0; i<NUM_BOMBS; i++&#41; &#123;
            if &#40;bombs&#91;i&#93;.x >= 0&#41; &#123;
                bombs&#91;i&#93;.y++;
                if &#40;bombs&#91;i&#93;.y > &#40;272-16&#41;&#41;
                    bombs&#91;i&#93;.x = bombs&#91;i&#93;.y = -1;
                /* you would do some kind of collision detection in an else here */
            &#125;
        &#125;

        /* draw stuff */
        blitImageToScreen&#40;0 ,0 ,480 , 272, backImage, 0, 0&#41;;
        blitAlphaImageToScreen&#40;0 ,0 ,16 , 16, eyeImage, ex, ey&#41;;
        for &#40;i=0; i<NUM_BOMBS; i++&#41;
            if &#40;bombs&#91;i&#93;.x >= 0&#41;
                blitAlphaImageToScreen&#40;0 ,0 ,16 , 16, bombImage, bombs&#91;i&#93;.x, bombs&#91;i&#93;.y&#41;;

        sceDisplayWaitVblankStart&#40;&#41;;
        flipScreen&#40;&#41;;
    &#125;
    sceKernelSleepThread&#40;&#41;;
    return 0;
&#125; 
Acegikmo
Posts: 15
Joined: Sat Jul 19, 2008 1:18 am

Post by Acegikmo »

Great, thanks :)
Just a few questions.

What does this mean?

bombs.x = bombs.y = -1;

And what's this?

unsigned int old_buttons = 0;
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Acegikmo wrote:Great, thanks :)
Just a few questions.

What does this mean?

bombs.x = bombs.y = -1;

And what's this?

unsigned int old_buttons = 0;


The first is setting the bomb x/y coords to something that can never happen as a marker that the bomb is not in use. We can skip it if the coord is less than 0.

The second is part of a better way to check your buttons. Instead of just looking at pad.Buttons, you want to XOR the previous buttons with the current ones to make new_buttons - a variable that tells you which buttons just changed. That way you only have to look at a button when it changes. For example in the code

Code: Select all

if&#40;new_buttons & PSP_CTRL_CROSS && pad.Buttons & PSP_CTRL_CROSS&#41; 
That says look at CROSS only if it changed, and that the current value is pressed. That way we only fire once each time you press X. So we start the previous buttons (old_buttons) out at 0. Notice that each time through the loop, it is set to pad.Buttons for the next time through the loop.
Post Reply