Bài giảng 9: Thời gian, cơ chế ngắt, đa tiến trình:
Tiết thứ: 26-29 Tuần thứ: 9+10
- Mục đích, yêu cầu:
• Nắm được cách tổ chức sự kiện theo thời gian..
• Nắm được cách ngắt 1 game đang chạy.
• Làm việc được với nhiều tiến trình.
- Hình thức tổ chức dạy học: Lý thuyết, thực hành, tự học, tự nghiên cứu
- Thời gian: Lý thuyết, thảo luận: 4t; Thực hành: 3t Tự học, tự nghiên cứu: 8t
- Địa điểm: Giảng đường do P2 phân công.
- Nội dung chính:
Lý thuyết:
Here is a breakdown of the major topics:
9.1 Timers
Timing is critical in a game. Without an accurate means to slow down a game to a
fixed rate, the game will be influenced by the speed of the computer running it,
adversely affecting gameplay.
9.1.1. Installing and Removing the Timer
You must be sure to call install timer before you create any timer routines
and also before you display a mouse pointer or play
int install timer()
You can call the remove timer function if you want to remove the timer before the program ends.
void remove timer()
9.1.2 Slowing Down the Program
You have seen the rest function used frequently in the sample programs in prior chapters, so it should be familiar to you. For reference, here is the declaration:
void rest(long time)
One feature that I haven’t gone over yet is the rest callback function. Have you noticed that Allegro provides a callback for almost everything it does? This is a fine degree of control seldom found in game development libraries; obviously, Allegro was developed by individuals with a great deal of experience, who had the foresight to include some very useful callback functions. Here is the declaration:
void rest callback(long time, void (*callback)())
This function works like rest, but instead of doing nothing, a callback function is
called during the delay period so your program can continue working even while
timing is in effect to slow the game down.
Here’s an example of how you would call the function:
//slow the game down
rest callback(8, rest1);
The rest1 callback function is very simple; it contains no parameters.
void rest1(void)
{
//time to rest, or do some work?
}
9.1.3 The TimerTest Program
The first section of code includes the defines, structs, and variables.
#include
#include
#include
#include "allegro.h"
#define MODE GFX AUTODETECT FULLSCREEN
#define WIDTH 640
#define HEIGHT 480
#define NUMSPRITES 6
#define BLACK makecol(0,0,0)
#define WHITE makecol(255,255,255)
//define the sprite structure
typedef struct SPRITE
{
int dir, alive;
int x,y;
int width,height;
int xspeed,yspeed;
int xdelay,ydelay;
int xcount,ycount;
int curframe,maxframe,animdir;
int framecount,framedelay;
}SPRITE;
//variables
BITMAP *back;
BITMAP *temp;
BITMAP *sprite images[10][10];
SPRITE *sprites[10];
BITMAP *buffer;
int n, f;
//timer variables
int start;
int counter;
int ticks;
int framerate;
Figure 9.1
The TimerTest program animates many sprites over a background scene.
The next section of code for the TimerTest program includes the sprite-handling
functions updatesprite, warpsprite, grabframe, and loadsprites.
void updatesprite(SPRITE *spr)
{
//update x position
if (++spr->xcount > spr->xdelay)
{
spr->xcount = 0;
spr->x += spr->xspeed;
}
//update y position
if (++spr->ycount > spr->ydelay)
{
spr->ycount = 0;
spr->y += spr->yspeed;
}
//update frame based on animdir
if (++spr->framecount > spr->framedelay)
{
spr->framecount = 0;
if (spr->animdir == -1)
{
if (--spr->curframe < 0)
spr->curframe = spr->maxframe;
}
Timers 415
416 Chapter 11 n Programming the Perfect Game Loop
else if (spr->animdir == 1)
{
if (++spr->curframe > spr->maxframe)
spr->curframe = 0;
}
}
}
void warpsprite(SPRITE *spr)
{
//simple screen warping behavior
//Allegro takes care of clipping
if (spr->x < 0 - spr->width)
{
spr->x = SCREEN W;
}
else if (spr->x > SCREEN W)
{
spr->x = 0 - spr->width;
}
if (spr->y < 0)
{
spr->y = SCREEN H - spr->height-1;
}
else if (spr->y > SCREEN H - spr->height)
{
spr->y = 0;
}
}
//reuse our friendly tile grabber
BITMAP *grabframe(BITMAP *source,
int width, int height,
int startx, int starty,
int columns, int frame)
{
BITMAP *temp = create bitmap(width,height);
int x = startx + (frame % columns) * width;
int y = starty + (frame / columns) * height;
blit(source,temp,x,y,0,0,width,height);
return temp;
}
void loadsprites(void)
{
//load dragon sprite
temp = load bitmap("dragon.bmp", NULL);
for (n=0; n<6; n++)
sprite images[0][n] = grabframe(temp,128,64,0,0,3,n);
destroy bitmap(temp);
//initialize the dragon (sprite 0)
sprites[0] = malloc(sizeof(SPRITE));
sprites[0]->x = 500;
sprites[0]->y = 0;
sprites[0]->width = sprite images[0][0]->w;
sprites[0]->height = sprite images[0][0]->h;
sprites[0]->xdelay = 1;
sprites[0]->ydelay = 0;
sprites[0]->xcount = 0;
sprites[0]->ycount = 0;
sprites[0]->xspeed = -5;
sprites[0]->yspeed = 0;
sprites[0]->curframe = 0;
sprites[0]->maxframe = 5;
sprites[0]->framecount = 0;
sprites[0]->framedelay = 5;
sprites[0]->animdir = 1;
//load fish sprite
temp = load bitmap("fish.bmp", NULL);
for (n=0; n<3; n++)
sprite images[1][n] = grabframe(temp,64,32,0,0,3,n);
destroy bitmap(temp);
//initialize the fish (sprite 1)
sprites[1] = malloc(sizeof(SPRITE));
sprites[1]->x = 300;
sprites[1]->y = 400;
sprites[1]->width = sprite images[1][0]->w;
sprites[1]->height = sprite images[1][0]->h;
sprites[1]->xdelay = 1;
sprites[1]->ydelay = 0;
sprites[1]->xcount = 0;
sprites[1]->ycount = 0;
sprites[1]->xspeed = 3;
sprites[1]->yspeed = 0;
sprites[1]->curframe = 0;
sprites[1]->maxframe = 2;
sprites[1]->framecount = 0;
sprites[1]->framedelay = 8;
sprites[1]->animdir = 1;
//load crab sprite
temp = load bitmap("crab.bmp", NULL);
for (n=0; n<4; n++)
sprite images[2][n] = grabframe(temp,64,32,0,0,4,n);
destroy bitmap(temp);
//initialize the crab (sprite 2)
sprites[2] = malloc(sizeof(SPRITE));
sprites[2]->x = 300;
sprites[2]->y = 212;
sprites[2]->width = sprite images[2][0]->w;
sprites[2]->height = sprite images[2][0]->h;
sprites[2]->xdelay = 6;
sprites[2]->ydelay = 0;
sprites[2]->xcount = 0;
sprites[2]->ycount = 0;
sprites[2]->xspeed = 2;
sprites[2]->yspeed = 0;
sprites[2]->curframe = 0;
sprites[2]->maxframe = 3;
sprites[2]->framecount = 0;
sprites[2]->framedelay = 20;
sprites[2]->animdir = 1;
//load bee sprite
temp = load bitmap("bee.bmp", NULL);
for (n=0; n<6; n++)
sprite images[3][n] = grabframe(temp,50,40,0,0,6,n);
destroy bitmap(temp);
//initialize the crab (sprite 2)
sprites[3] = malloc(sizeof(SPRITE));
sprites[3]->x = 100;
sprites[3]->y = 120;
sprites[3]->width = sprite images[3][0]->w;
sprites[3]->height = sprite images[3][0]->h;
sprites[3]->xdelay = 1;
sprites[3]->ydelay = 0;
sprites[3]->xcount = 0;
sprites[3]->ycount = 0;
sprites[3]->xspeed = -3;
sprites[3]->yspeed = 0;
sprites[3]->curframe = 0;
sprites[3]->maxframe = 5;
sprites[3]->framecount = 0;
sprites[3]->framedelay = 8;
sprites[3]->animdir = 1;
//load skeeter sprite
temp = load bitmap("skeeter.bmp", NULL);
for (n=0; n<6; n++)
sprite images[4][n] = grabframe(temp,50,40,0,0,6,n);
destroy bitmap(temp);
//initialize the crab (sprite 2)
sprites[4] = malloc(sizeof(SPRITE));
sprites[4]->x = 500;
sprites[4]->y = 70;
sprites[4]->width = sprite images[4][0]->w;
sprites[4]->height = sprite images[4][0]->h;
sprites[4]->xdelay = 1;
sprites[4]->ydelay = 0;
sprites[4]->xcount = 0;
sprites[4]->ycount = 0;
sprites[4]->xspeed = 4;
sprites[4]->yspeed = 0;
sprites[4]->curframe = 0;
sprites[4]->maxframe = 4;
sprites[4]->framecount = 0;
sprites[4]->framedelay = 2;
sprites[4]->animdir = 1;
//load snake sprite
temp = load bitmap("snake.bmp", NULL);
for (n=0; n<8; n++)
sprite images[5][n] = grabframe(temp,100,50,0,0,4,n);
destroy bitmap(temp);
//initialize the crab (sprite 2)
sprites[5] = malloc(sizeof(SPRITE));
sprites[5]->x = 350;
sprites[5]->y = 200;
sprites[5]->width = sprite images[5][0]->w;
sprites[5]->height = sprite images[5][0]->h;
sprites[5]->xdelay = 1;
sprites[5]->ydelay = 0;
sprites[5]->xcount = 0;
sprites[5]->ycount = 0;
sprites[5]->xspeed = -2;
sprites[5]->yspeed = 0;
sprites[5]->curframe = 0;
sprites[5]->maxframe = 4;
sprites[5]->framecount = 0;
sprites[5]->framedelay = 6;
sprites[5]->animdir = 1;
}
The last section of code for the TimerTest program includes the main function
int main(void)
{
//initialize
allegro init();
set color depth(16);
set gfx mode(MODE, WIDTH, HEIGHT, 0, 0);
srand(time(NULL));
install keyboard();
install timer();
//create double buffer
buffer = create bitmap(SCREEN W,SCREEN H);
//load and draw the blocks
back = load bitmap("background.bmp", NULL);
blit(back,buffer,0,0,0,0,back->w,back->h);
//load and set up sprites
loadsprites();
//game loop
while (!keypressed())
{
//restore the background
for (n=0; n
blit(back, buffer, sprites[n]->x, sprites[n]->y,
sprites[n]->x, sprites[n]->y,
sprites[n]->width, sprites[n]->height);
//update the sprites
for (n=0; n
{
updatesprite(sprites[n]);
warpsprite(sprites[n]);
draw sprite(buffer, sprite images[n][sprites[n]->curframe],
sprites[n]->x, sprites[n]->y);
}
Chia sẻ với bạn bè của bạn: |