|
||||||
| C Tutorials All C Tutorials and Code |
![]() |
|
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
|
|||||
|
This is a guide to the Allegro Game library, an awesome C library which works on windows, unix, mac OS X, heck, it even works on BeOS and QNX.
Why use the Allegro library and C? Because: -It is very fast. -It is under a giftware license. -...I said so? no? whatever. So, download allegro here. There will be really helpful information on how to install it inside the package. If you use Dev-C++, there is a devpak. If you use MS Visual Studio.. I dunno. Maybe Xav can figure it out, he uses it. So once you've got allegro, let's make a simple program using it! #include the allegro library, allegro.h, and in your main() function, call allegro_init(). Next, if you want to use the mouse or keyboard, call install_keyboard() and/or install_mouse(). Next is graphics. Call set_color_depth(24) (or passing 32, or 16, or 15 or 8), and then call set_gfx_mode(GFX_AUTODETECT_WINDOWED, width, height, 0, 0) Finally, after the end of your main() function, call END_OF_MAIN(). So, now you should get a blank window which appears for an instant. To prevent it disappearing until you press the X button, make a global variable called X_button_state, and set it to zero. Make a function called X_button_handler(), inside of which you set X_button_state to one. In main(), call set_close_button_handler(X_button_handler()). Then, put a loop in the end of your main() function, which doesn't terminate until X_button_state = 1. Okay, so now I'll tell you about BITMAP structures, blit()ting, and drawing primitives. When you called set_gfx_mode(), you created a BITMAP structure called screen, which is literally the memory mapped pixels of the screen. Writing to the screen, however, is very slow, so it's best to create another BITMAP structure of the same size as your screen, and then, each turn of your main loop, draw to it and then copy the whole thing to the screen. To do this, outside your main loop, put: Code:
BITMAP * buffer = create_bitmap(width,height); Now, inside your loop, at the beginning, clear your buffer to black: Code:
clear_to_color(buffer, 0); And at the end, copy it to your screen, using the blit() function, which is for copying large areas of pixels: Code:
blit(buffer,screen,0,0,0,0,width,height); Code:
int red = makecol(255,0,0); int green = makecol(0,255,0); int blue = makecol(0,0,255); Now, let's use a few colors, to draw stuff! There are quite a few primitive drawing functions, so I'll just list them, and their arguments. Test them out, they look cool when moving! Code:
line(buffer,x1,y1,x2,y2,color); //line triangle(buffer,x1,y1,x2,y2,x3,y3,color); //filled triangle rect(buffer,x1,y1,x2,y2,color); //rectangle outline rectfill(buffer,x1,y1,x2,y2,color); // filled rectangle circle(buffer,x,y,r,color); // circle outline circlefill(buffer,x,y,r,color); // filled circle ellipse(buffer,x,y,rx,ry,color); // ellipse/oval outline ellipsefill(buffer,x,y,rx,ry,color); // filled ellipse/oval Last edited by Aereshaa; 07-03-2008 at 12:45 PM. |
| Sponsored Links |
|
|
|
|||||
|
Does Allegro support three dimensional graphics? Everything you mentioned seems to be two dimensional.
__________________
CodeCall Blog | CodeCall Wiki | Shareware | Linux Forum | My Blog Chat with other CodeCall members on IRC; connect to irc.codecall.net and join #codecall |
|
|||||
|
It does if you are willing to look up the formulae! For example, I made a 3d Pong game a few weeks ago. Basically, I used Allegro with math.h and checked the formulae on wikipedia. Also there are 3d math routines, although I haven't used them at all...
Okay, so next thing is input. Allegro uses two main sources of input: the keyboard array and the mouse variables. The keyboard array is key[] which is indexed by a kabillion macros: here's how it works: Code:
key[KEY_A] key[KEY_ESC] key[KEY_SHIFT] key[KEY_F1] key[KEY_CTRL] For mouse, use the variables mouse_x mouse_y, and use the bit-mapped variable mouse_b. mouse_b & 1 is left button, mouse_b & 2 is right, mouse_b & 4 is middle. any other buttons on your mouse can probably be found at later bits. Okay, next is text. To draw text on the screen, you need a font. Fonts can be loaded to allegro from GRX format .fnt files, 8x8 or 8x16 BIOS format fonts, or from specially prepared bitmaps. Allegro also contains a global font variable, containing a simple font. To load a font, use the load_font() function, like so. Code:
FONT * myfont = load_font("myfont.fnt",NULL,NULL);
So, to use a font, use the textprintf_ex() function. Code:
textprintf(buffer,font,x,y,color,bgcolor,"format string", ...) There are also textprintf_centre_ex(), and textprintf_right_ex(), variants which treat the coordinates given differently. Last edited by Aereshaa; 07-06-2008 at 12:27 AM. |
|
|||||
|
Okay, so, you've got a game, say a clone of space invaders, and you have the game logic all worked out, but wait! You can only draw triangles and squares and lines and circles!
What you need is sprites. Sprites are essentially bitmaps loaded out of a file. Allegro can load sprites from .bmp, .lbm, .tga, and .pcx image files, using the load_bitmap() function, whats syntax is: Code:
BITMAP * sprite = load_bitmap("whatever.bmp",NULL);
But remember that all bitmaps must be destroyed using destroy_bitmap() before the end of the program. To use a sprite, you will need the draw_sprite() function, similar to the blit() function, except that the color FF00FF (bright violet) is treated as transparent. It is used like this: Code:
draw_sprite(buffer,sprite,x,y); , which takes a width and height to stretch the sprite to, and rotate_sprite() which takes as an extra argument an angle in fixed point, which you can convert from radians using radtofix_r(): Code:
rotate_sprite(buffer,sprite,x,y,radtofix_r(PI / 3.0)); //rotates 60 degrees Last edited by Aereshaa; 07-07-2008 at 02:05 PM. |
| Sponsored Links |
|
|
|
|||||
|
Okay, that's pretty much the basic stuff, for extra features and lists of functions see here.
Now, I'll just share some examples: Aereshaa's Pong Reloaded. Undefine reloaded for classic pong. Code:
#include "stdio.h"
#include "unistd.h"
#include "time.h"
#include "allegro.h"
#include "stdlib.h"
#include "math.h"
#define scrH 128
#define scrW 256
#define color int
#define triple long double
#define reloaded
typedef struct MASS_ {
int xpos;
int ypos;
double xspd;
double yspd;
} MASS;
#define mass MASS *
int main(int argc, char** argv){
allegro_init();//setup of graphics & stuff.
install_keyboard();
install_mouse();
set_color_depth(24);
set_gfx_mode(GFX_AUTODETECT_WINDOWED, scrW * 2 , scrH * 2 ,0,0);
BITMAP *buffer = create_bitmap(scrW, scrH);//will speed things up.
MASS P1 = {64,64,0.0,0.0};
MASS P2 = {192,64,0.0,0.0};
MASS BL = {128,64,-2.0,0.0};
char P1_size = 8;
char P2_size = 8;
#ifdef reloaded
long P1_timeanom_pow = 0;
long P2_timeanom_pow = 0;
long P1_gravanom_pow = 0;
long P2_gravanom_pow = 0;
long P1_gravanom_dur = 0;
long P2_gravanom_dur = 0;
int gravdir = 0;
long P1_reflanom_pow = 0;
long P2_reflanom_pow = 0;
#endif
int P1_score = 0;
int P2_score = 0;
int winner = 0;
color white = makecol24(255,255,255);
color grey = makecol24(127,127,127);
color green = makecol24(0,255,0);
color red = makecol24(255,0,0);
color blue = makecol24(0,0,255);
color cyan = makecol24(0,255,255);
int show = 0;
while(!key[KEY_G] && !key[KEY_ESC]){
START:
clear(buffer);
textprintf_centre_ex(buffer,font,scrW / 2,24,blue,-1,"AERESHAA\'S");
textprintf_centre_ex(buffer,font,scrW / 2 + 1,24,cyan,-1,"AERESHAA\'S");
#ifdef reloaded
textprintf_centre_ex(buffer,font,scrW / 2,36,white,-1,"\"PONG RELOADED\"");
#else
textprintf_centre_ex(buffer,font,scrW / 2,36,white,-1,"\"PONG\"");
#endif
if(time(0) % 2)textprintf_centre_ex(buffer,font,scrW / 2 + 1,48,grey,-1,"press G to continue");
if(!(time(0) % 2) && show != 1)textprintf_centre_ex(buffer,font,scrW / 2 + 1,56,grey,-1,"press H to show controls");
if(key[KEY_H])show = 1;
if(show == 1){
textprintf_centre_ex(buffer,font,scrW / 2 + 1,68,grey,-1,"P1: W = up, S = down");
#ifdef reloaded
textprintf_centre_ex(buffer,font,scrW / 2 + 1,76,grey,-1,"anomalies: Z,X,C");
#endif
textprintf_centre_ex(buffer,font,scrW / 2 + 1,86,grey,-1,"P2: ^ = up, v = down");
#ifdef reloaded
textprintf_centre_ex(buffer,font,scrW / 2 + 1,94,grey,-1,"anomalies: I,O,P");
#endif
}
stretch_blit(buffer,screen,0,0,scrW,scrH,0,0,scrW*2,scrH*2);
}
while(!key[KEY_ESC]){
/* /TIMING PHASE/ * /
* Timing is very important, so it will be
* handled by using the nanosleep() function.
*/
usleep(25000);
#ifdef reloaded
P1_timeanom_pow++;
P2_timeanom_pow++;
P1_reflanom_pow++;
P2_reflanom_pow++;
P1_gravanom_pow++;
P2_gravanom_pow++;
if(P2_gravanom_dur){P2_gravanom_dur--;gravdir = 2;}
else if(P1_gravanom_dur){P1_gravanom_dur--;gravdir = 1;}
else if((P1_gravanom_dur) && (P2_gravanom_dur)){P2_gravanom_dur--;P1_gravanom_dur--;gravdir = 0;}
else{gravdir = 0;}
#endif
/* /CONTROL PHASE/ * /
* Control phase begins here. Both players will
* have access to easy controls for warps, time
* anomalies, gravity introduction, etc.
*/
if(key[KEY_S])P1.yspd += 0.5;
if(key[KEY_W])P1.yspd -= 0.5;
if(key[KEY_DOWN])P2.yspd += 0.5;
if(key[KEY_UP])P2.yspd -= 0.5;
if(key[KEY_Y]){ //reset
P1_score = 0;
P2_score = 0;
P1 = (MASS) {64,64,0.0,0.0};
P2 = (MASS) {192,64,0.0,0.0};
BL = (MASS) {128,64,-2.0,0.0};
winner = 0;
#ifdef reloaded
P1_timeanom_pow = 0;
P2_timeanom_pow = 0;
P1_gravanom_pow = 0;
P2_gravanom_pow = 0;
P1_gravanom_dur = 0;
P2_gravanom_dur = 0;
gravdir = 0;
P1_reflanom_pow = 0;
P2_reflanom_pow = 0;
#endif
goto START;
}
#ifdef reloaded
if(key[KEY_Z] && P1_timeanom_pow > 200){
P1.yspd = 0 - P1.yspd;
P2.yspd = 0 - P2.yspd;
BL.yspd = 0 - BL.yspd;
BL.xspd = 0 - BL.xspd;
P1_timeanom_pow = 0;
}
if(key[KEY_I] && P2_timeanom_pow > 200){
P1.yspd = 0 - P1.yspd;
P2.yspd = 0 - P2.yspd;
BL.yspd = 0 - BL.yspd;
BL.xspd = 0 - BL.xspd;
P2_timeanom_pow = 0;
}
if(key[KEY_X] && P1_gravanom_pow > 400){
P1_gravanom_dur = 50;
P1_gravanom_pow = 0;
}
if(key[KEY_O] && P2_gravanom_pow > 400){
P2_gravanom_dur = 50;
P2_gravanom_pow = 0;
}
if(key[KEY_P] && P2_reflanom_pow > 200){
BL.yspd = 0 - BL.yspd;
BL.xspd = 0 - BL.xspd;
BL.ypos = (128 - BL.ypos);
BL.xpos = (256 - BL.xpos);
P2_reflanom_pow = 0;
}
if(key[KEY_C] && P1_reflanom_pow > 200){
BL.yspd = 0 - BL.yspd;
BL.xspd = 0 - BL.xspd;
BL.ypos = (128 - BL.ypos);
BL.xpos = (256 - BL.xpos);
P1_reflanom_pow = 0;
}
#endif
/* /PHYSICS PHASE/ * /
* This game is very physics-intensive, so I will
* use the simplest algorithms I know. Time is the
* most complicated part.
*/
/*Player One*/
P1.ypos += (int) P1.yspd;
if(P1.ypos > scrH){//bounce off walls
P1.yspd = 0.0 - P1.yspd;
P1.ypos = scrH;}
if(P1.ypos < 0){//bounce off walls
P1.yspd = 0.0 + -P1.yspd;
P1.ypos = 0;}
P1.yspd += (P1.yspd > 0.0)?(-0.2):
(P1.yspd < 0.0)?(0.2):(0.0);
/*Player Two*/
P2.ypos += (int) P2.yspd; color grey = makecol24(127,127,127);
if(P2.ypos > scrH){//bounce off walls
P2.yspd = 0.0 - P2.yspd;
P2.ypos = scrH;}
if(P2.ypos < 0){//bounce off walls
P2.yspd = 0.0 + -P2.yspd;
P2.ypos = 0;}
P2.yspd += (P2.yspd > 0.0)?(-0.2):
(P2.yspd < 0.0)?(0.2):(0.0);
/*Ball*/
BL.ypos += (int) BL.yspd;
BL.xpos += (int) BL.xspd;
if(BL.ypos > scrH){ //bounce off walls
BL.yspd = 0.0 - BL.yspd;
BL.ypos = scrH;}
if(BL.ypos < 0){ //bounce off walls
BL.yspd = 0.0 + -BL.yspd;
BL.ypos = 0;}
if(BL.xpos < P1.xpos + 2 && BL.xpos > P1.xpos - 5
&& BL.ypos > P1.ypos - (P1_size + 2)
&& BL.ypos < P1.ypos + (P1_size + 2)){
BL.xspd = 0.0 + -BL.xspd; // bounce off paddle 1.
BL.xpos = P1.xpos + 2;
BL.yspd += P1.yspd;}
if(BL.xpos > P2.xpos - 2 && BL.xpos < P2.xpos + 5
&& BL.ypos > P2.ypos - (P2_size + 2)
&& BL.ypos < P2.ypos + (P2_size + 2)){
BL.xspd = 0.0 + -BL.xspd; // bounce off paddle 2.
BL.xpos = P2.xpos - 2;
BL.yspd += P2.yspd;}
if(BL.xpos > scrW){//score for P1
BL.xspd = -2.0;
BL.yspd = 0.0;
P1_score++;
BL.ypos = 64;
BL.xpos = scrW / 2;}
if(BL.xpos < 0){//score for P2
BL.xspd = 2.0;
BL.yspd = 0.0; if(winner)textprintf_centre_ex(buffer,font,scrW / 2,0,red,-1,"!P%d Wins!",winner);
P2_score++;
BL.xpos = scrW / 2;
BL.ypos = 64;}
#ifdef reloaded
BL.xspd += (gravdir == 1)?(0.1):(gravdir == 2)?(-0.1):(0.0);
#endif
/* /GAME PHASE/ */
if(P1_score == 15){
winner = 1;}
if(P2_score == 15){
winner = 2;}
/* /DRAWING PHASE/ * /
* Drawing phase begins here. All game objects
* must be drawn, unless mitigating circumstances
* arise. I will use primitives wherever possible.
*/
clear(buffer);
textprintf_ex(buffer,font,0,0,grey,-1,"%d",P1_score);
#ifdef reloaded
if(P1_timeanom_pow > 200)textprintf_ex(buffer,font,0,8,grey,-1,"time anomaly");
if(P1_reflanom_pow > 200)textprintf_ex(buffer,font,0,24,grey,-1,"reflect anomaly");
if(P1_gravanom_pow > 300)textprintf_ex(buffer,font,0,16,grey,-1,"gravity anomaly");
if(P1_gravanom_dur)textprintf_ex(buffer,font,0,16,green,-1,"gravity anomaly");
#endif
textprintf_right_ex(buffer,font,scrW,0,grey,-1,"%d",P2_score);
#ifdef reloaded
if(P2_timeanom_pow > 200)textprintf_right_ex(buffer,font,scrW,8,grey,-1,"time anomaly");
if(P2_reflanom_pow > 200)textprintf_right_ex(buffer,font,scrW,24,grey,-1,"reflect anomaly");
if(P2_gravanom_pow > 300)textprintf_right_ex(buffer,font,scrW,16,grey,-1,"gravity anomaly");
if(P2_gravanom_dur)textprintf_right_ex(buffer,font,scrW,16,green,-1,"gravity anomaly");
#endif
textprintf_centre_ex(buffer,font,scrW / 2, 64, grey, -1, "%.3f", BL.yspd / BL.xspd);
line(buffer,P1.xpos, P1.ypos + P1_size, P1.xpos, P1.ypos - P1_size, white);
line(buffer,P2.xpos, P2.ypos + P2_size, P2.xpos, P2.ypos - P2_size, white);
circle(buffer, BL.xpos, BL.ypos, 2, white);
if(winner)textprintf_centre_ex(buffer,font,scrW / 2,0,red,-1,"!P%d Wins!",winner);
stretch_blit(buffer,screen,0,0,scrW,scrH,0,0,scrW*2,scrH*2);
}
destroy_bitmap(buffer);
}END_OF_MAIN();
...Will add more. |
|
|||
|
I'm having a problem with set_close_button_handler(X_button_handler());. Code::Blocks gives me a compiler error stating "invalid use of void expression". Before that it gives me a warning - "warning: implicit declaration of function 'set close button handler'". I'm thinking the compiler isn't finding the function set_close_button_handler, but that doesn't make sense because I've imported allegro.h and all other functions work.
I'm using Allegro 4.2.1, Code::Blocks for my IDE, and the GNU GCC compiler (I installed MinGW for it). |
|
|||||
|
Oops, I gave the wrong name. It's set_close_button_callback(). Sorry about that.
Here is an example using fullscreen, and a loaded image, a matrix "digital rain" effect. (Attached.) Change the .txt extension to tga. Last edited by Aereshaa; 07-13-2008 at 09:25 PM. |
![]() |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | Search this Thread |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Creating a card game (multiplaye online with AI).. what do I program this in? | anothersoldier | General Programming | 1 | 07-19-2007 06:46 AM |
| Paying for Links | Chan | Marketing | 26 | 05-02-2007 08:37 PM |
| XBox 360 XNA Game Programming | Jordan | C# Programming | 14 | 09-29-2006 05:10 PM |
| Xav | ........ | 161.68 |
| neerlin | ........ | 100 |
| satrian | ........ | 100 |
| delia | ........ | 100 |
| chili5 | ........ | 70.08 |
| morefood2001 | ........ | 42.41 |
| MeTh0Dz|Reb0rn | ........ | 28.44 |
| RyanTuosto | ........ | 20 |
| gamiR | ........ | 19.64 |
| John | ........ | 14.46 |
Goal: 100,000 Posts
Complete: 68%