Just as a little learning project, I want to make an allegro program that just has a sprite on the display, and it walks left when press left, right when I press right etc. Basically all I have done so far is make a pong game which just used primitive bitmaps, rather than loading an image. So basically I just need to know how sprites work.
I need to know where does the sprite come from? Do I take a sprite sheet from google and load a section of that image file into the program?
When the sprite moves, how exactly do I put in the animation? Do I time it so that while a keyboard event is occurring, the program cycles through a few different images on a sprite sheet?
And if there is anything else I should know then I would appreciate any advice you all could give me
Here's a very broad description of how I do it :
For an animation, you need to know how long it displays for, how many frames there are, how much time has passed so far, and whether it loops or is static. Then you also need to know the current state of the animation, and how to set that state based on what your character is doing.
oh nice! Good thing my class just covered how to do OOP!
But on a simpler scale. I don't even know how to draw a sprite to the display. I've looked through the allegro manual and I can't find any functions that take in an image file or anything to draw to the display. All I can think of is creating a bitmap, and filling it with a colour
You can go and grab a sprite sheet off google, or make one yourself that looks like this:
This is the code I use to get a single tile off this sheet, and scroll through them over time.
To actually draw this I call the players' parent draw function.
void CVisibleTile::draw() { if(x+ TILE_SIZE >= 0 && x < SCREEN_W && y + TILE_SIZE >= 0 && y< SCREEN_H) { al_draw_bitmap(bmp, x, y, 0); } }
Hope that helps. There's a good tutorial on the wiki for the basics of displaying bitmaps as well. http://wiki.allegro.cc/index.php?title=Allegro_5_Tutorial/Input
But on a simpler scale. I don't even know how to draw a sprite to the display. I've looked through the allegro manual and I can't find any functions that take in an image file or anything to draw to the display.
Are you using Allegro 4 or Allegro 5?
Allegro 4 :
load_bitmap
draw_sprite
Allegro 5 :
al_load_bitmap
al_convert_mask_to_alpha
al_draw_bitmap
I'm using allegro 5.
what is the pallet object you have at line 15 jason? I hope you don't mind, but I'm just copying down that code so that I can mess around with it later to get a better understanding of what's going on.
Just to clarify, what does al_convert_mask_to_alpha do? I noticed that the rgb code in your function is magenta, so does that just make it so that magenta is transparent?
And I have read all the tutorials so far. And I've implemented them into a little pong game (except font, which I can't get to work so far). The bitmap tutorial unfortunately just explains how to make a solid colored square, not an image. Or in this case, and image out of a bigger image like a sprite sheet.
so does that just make it so that magenta is transparent?
Yes.
The bitmap tutorial unfortunately just explains how to make a solid colored square, not an image. Or in this case, and image out of a bigger image like a sprite sheet.
Use al_load_bitmap to load your spritesheet, then create an array of ALLEGRO_BITMAP* and fill it in with al_create_bitmap and al_draw_bitmap_region or use al_create_sub_bitmap on your spritesheet. Then use al_draw_bitmap to draw your images.
I think I need to add a second example to that bitmap tutorial that uses the image addon.
Can we copy bitmap to new bitmap without display ?
I find rotate_sprite(pframe->frame, vbitmap, pframe->iwidth / 2, pframe->iheight / 2, fangle).
How to use it? Which .h will be include ?
I guess you've figured out from the posts above that there really isn't any such thing as a sprite. In the olden days, the Commodore 64 had sprites. A sprite is just a bitmap that appears to animate simply because you are replacing it with another bitmap, i.e. a sprite is a class you create to manage, control and show the graphics in order
Forget about palettes. They are only used in 8 bit graphics and A5 doesn't support them.
Regarding al_convert_mask_to_alpha(): A5 uses the alpha channel to support transparency. A4 didn't and instead usually relied on 'magic pink', i.e. 255,0,255 magenta. So, al_convert_mask_to_alpha will look at your bitmap and any magenta pixel will be converted to transparency.
Ok so first step, I just want to cut a section (the top left most) of the sprite sheet and put it on the display, just for starters. Now I've got a program that compiles, but it has a segmentation fault in there. Also I'm wondering if I'm doing this right. I'm just making a class for the sprite, and using a drawing method with al_draw_bitmap_region.
(The rest of the code should be good, Its just copied from my pong game for the eventual keyboard input I will want to put in later)
I've never used al_draw_bitmap_region(), but that looks a little off. because your changing units from pixels to pictures with this line:
animationWidth = al_get_bitmap_width(bmp)/32; ...
To get just the top left image with al_create_sub_bitmap(). you'd do this:
bmp = al_load_bitmap("player.png") ALLEGRO_BITMAP* top_left_image = al_create_sub_bitmap(bmp, 0, 0, 32, 32);
and draw with al_draw_bitmap(top_left_image, x, y, 0)
It just makes more practical sense to create an entire array at once though. so if you have a 4x4 sheet and 32x32 tiles...
bmp = al_load_bitmap("player.png") ALLEGRO_BITMAP* bmp_array[4][4]; for (int x = 0; x < 4; x++) { for (int y = 0; y < 4; y++) { bmp_array[x][y] = al_create_sub_bitmap(bmp, 32*x, 32*y, 32, 32); } } sprite.bmp = bmp_array[0][0];
Also instead of creating the variables sprite_x, and sprite_y, you should just make them private members of your player class, and write public functions to modify the values. Same goes for the bitmap so you can switch which element in the bitmap array is getting drawn.
@Havacore
Your program is crashing because you are calling al_load_bitmap before you have initialized allegro and you forgot to initialize the image addon. You declare 'player sprite' (which calls player::player(), which calls al_load_bitmap) before you call al_init().
Ok I did it! I now have a program that draws a piece of the sprite sheet to the display! Now for animation, which is going to be quite the mountain for me to conquer
@Edgar
I've been looking at the code you posted in the first reply. It all looks good an makes sense to me now, I just don't quite know how to keep track of time in a program. (whether in an allegro program or in a regular C++ program). The only thing I can think of is using my FPS constant with the allegro timer, making the animation state change every 15 frames or so. Would that be how you would go about tackling that problem?
Also that map<string , Animation*> in the animationState class, what is that?
Thanks for all the help so far btw everyone, this is awesome!
Without giving you full code since you are doing it for a course of some sort. You can use al_create_timer( ALLEGRO_BPS_TO_SECS( 60 ) ); "60" being the FPS and use the Allegro Event system ALLEGRO_EVENT_TIMER.
Hope this helps you.
Edit:
Also that map<string , Animation*> in the animationState class, what is that?
It's an array. Similar to std::vector and array[10]
Without giving you full code since you are doing it for a course of some sort
Just to clarify, this isn't for a class, allegro programming is something I'm just learning on my own time. The course I mentioned earlier is just a regular computer science course.
On the other hand though, that is useful. I'll have to play around with events some more
I just don't quite know how to keep track of time in a program. (whether in an allegro program or in a regular C++ program). The only thing I can think of is using my FPS constant with the allegro timer, making the animation state change every 15 frames or so. Would that be how you would go about tackling that problem?
Use an ALLEGRO_TIMER, and set the the number of seconds between ticks using your FPS variable. You get the number of seconds per tick by taking the reciprocal of your FPS. Then for each timer event you receive, you call Animation::AdvanceFrameTime(seconds_per_tick).
Here is a working Allegro 4 based example of animation :
My post complete with animation example
If you download the zip file from that post you can view the source code I used for it and run the example I provided. The important functions from Animation.cpp are AnimationBase::AdvanceFrameTime, and AnimationBase::SetFrameTime, which I posted on the page I linked to. If you have any questions, feel free to ask. If I have time in the next few days, I may make a short version that works with A5.
Also that map<string , Animation*> in the animationState class, what is that?
It's an array. Similar to std::vector and array[10]
No, it's not an array. At best, it is like a sorted linked list. I gave William Labbett a short explanation of how to use the std::map class here :
std::map explanation, with link to SGI STL documentation
Ok I'm trying to use the code you put in the first response with the animation, stateAnimation and character classes. I'm still trying to wrap my head around the map thing, but I'm wondering if I can get away without using it. I worked on it a bit today but this is about as far as I got
sprite.h:
sprite.cc:
I changes some stuff from the original post, and I haven't filled in the player or the animation state class yet. I haven't figured out what exactly the setFrameTime and advanceFrameTime functions should do. One second I'm thinking that setFrameTime will set the duration, but then I think why wouldn't you just do that in the constructor... Maybe it's just because I need to step away from this for a second..
I haven't figured out what exactly the setFrameTime and advanceFrameTime functions should do.
SetFrameTime should take a time value and turn it into a frame number. AdvanceFrameTime should take the current value, add the delta time to it, and then use that value in a call to SetFrameTime.
I'll go over the basics of a forward playing looped animation :
And that's it. It gets slightly more complicated if you want more features, but it's a good place to start. Use it like this :