Qbasicnews.com

Full Version: Sprite classes in Allegro
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Sorry to have such a vague post, but could anyone possibly give me an example of a sprite class that could be used in Allegro? Basically, one that holds the position, and images of the sprite? I'm having unexpectedly high amounts of problems in this department.
I can make it in plain C with structures...

Code:
typedef struct {
   int x, y, vx, vy, ax, ay, rx, ry;     // Use ints and <<8 values. Read below
   BITMAP **cells;    // Dynamic array of cells
   int num_cells;
   int frame;
   int subframe;
   int status;
   int etc;
} SPRITETYPE;

SPRITETYPE sprites[100];

Ints <<8: to avoid floats, you can make every value integer and multiply by 256 (shift left 8 ). That way you get precission without having to use floating point numbers. To convert back to real coordinates/values, just divide by 256 (shift right 8: >>8 ) .
Alright, thanks.

I tried going by that, and here's what I have so far. Hopefully you can tell what I was trying to do through each section.

The code actually runs, however, upon excecuting the program, it closes right back out, so apparently, I'm doing something wrong in here.

Code:
#include <stdio.h>
#include <allegro.h>
#include <winalleg.h>

RGB* Pal;

struct SPRITE_STRUCT
{

    int x,y,currentimage;
    BITMAP** image[50];


};

void Load_Sprite(char *filename, BITMAP** bitmap)
{
    bitmap = (BITMAP**)load_bitmap(filename, Pal);
}

void Draw_Sprite(SPRITE_STRUCT sprite)
{
    draw_sprite(screen, (BITMAP*)sprite.image[sprite.currentimage],sprite.x,sprite.y);
}

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int nshowcmd)
{
    SPRITE_STRUCT character;

    allegro_init();
    set_color_depth(16);
    set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0);
    install_keyboard();
    
    character.currentimage = 0;


    while(!key[KEY_ESC])
    {
            


        Load_Sprite("character.bmp", character.image[0]);
        Draw_Sprite(character);

    }
    
    return(0);
}
At a glance, it could be because x and y have not been initialised and you then try to blit directly to the screen in Draw_Sprite using these 'wild' variables - which are probably way out of range.

[EDIT]
Ohh.. that 'bitmap' pointer in Load_Sprite also goes out of scope once the function ends, which is probably the main culprit.

If you're using C++ and happy with OOP, a better way would be like this:

Code:
#include <stdio.h>
#include <allegro.h>
#include <winalleg.h>

RGB* Pal;

class Sprite
{

public:

    // Loads a bitmap into specified slot
    void Load_Sprite (char *filename, int index);

    // Draws sprite to screen using existing coords
    void Draw_Sprite(int index);

    int x,y;

private:

    // Array of pointers to bitmaps
    BITMAP* image[50];
};

void Sprite::Load_Sprite(char *filename, int index)
{
   image[index] = load_bitmap(filename, Pal);
}

void Sprite::Draw_Sprite(int index)
{
   draw_sprite(screen, image[index], x, y);
}

int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int nshowcmd)
{

   allegro_init();
   set_color_depth(16);
   set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0);
   install_keyboard();
    
   Sprite character;
   character.x = 10;
   character.y = 10;

   while(!key[KEY_ESC])
   {    
  
      // Load bmp into index 0
      character.Load_Sprite("character.bmp", 0);

      // Draw sprite held at index 0
      character.Draw_Sprite(0);

   }
    
   return(0);
}
Quote:
Code:
void Load_Sprite(char *filename, BITMAP** bitmap)
{
    bitmap = (BITMAP**)load_bitmap(filename, Pal);
}

load_bitmap returns a BITMAP*... so either you need to amend your code to this:

Code:
void Load_Sprite(char *filename, BITMAP** bitmap)
{
    *bitmap = load_bitmap(filename, Pal);
}

Or you can change your function to just accept a pointer to a bitmap (this way is a lot better):

Code:
void Load_Sprite(char *filename, BITMAP* bitmap)
{
    bitmap = load_bitmap(filename, Pal);
}

Just to clarify, previously you could have done this with your original code:

Code:
BITMAP *someBitmap;
    Load_Sprite("arf.bmp", &someBitmap);

However, with the amended code (the second option), you call the function like this:

Code:
BITMAP *someBitmap;
    Load_Sprite("arf.bmp", someBitmap);


Another note, you'd probably want to check whether the function worked or not - obviously the load_bitmap function will fail if the file doesn't exist, or if the file is corrupt. So you can return a "status" value like so:


Code:
int Load_Sprite(char *filename, BITMAP* bitmap)
{
    return (bitmap = load_bitmap(filename, Pal));
}

Which will return 0 if it fails, or 1 if it succeeds.

Hope this helps.

-shiftLynx
P.S. Piptol's class is a lot nicer than using plain C for this purpose. Wink
Thank you very much. You are all my heroes. Smile I don't know why I was afraid to use classes in the beginning, but it sure as heck made it a lot easier.

But yeah, I got the class working, and a nice picture of....... a burger.... showed up on the screen. Thank you very much. Smile