距离上次封装有一个月了,PHYSX知道怎么弄朝向和位置了,我决定业余时间可以弄弄小游戏,
这个例子是通过改变调色板ID来达到颜色的亮灭,这个肯定过时了,不过思路还是不错的。
各个常量和结构体类型
#define BLINKER_ADD 0 // add a light to database
#define BLINKER_DELETE 1 // delete a light from database
#define BLINKER_UPDATE 2 // update a light
#define BLINKER_RUN 3 // run normal// blinking light structure
typedef struct BLINKER_TYP
{
// user sets these
int color_index; // index of color to blink
PALETTEENTRY on_color; // RGB value of "on" color
PALETTEENTRY off_color; // RGB value of "off" color
int on_time; // number of frames to keep "on"
int off_time; // number of frames to keep "off"
// internal member
int counter; // counter for state transitions
int state; // state of light, -1 off, 1 on, 0 dead
} BLINKER, *BLINKER_PTR;
主要函数是
int Blink_Colors(int command, BLINKER_PTR new_light, int id)
{
// this function blinks a set of lights
static BLINKER lights[256]; // supports up to 256 blinking lights
static int initialized = 0; // tracks if function has initialized
// test if this is the first time function has ran
if (!initialized)
{
// set initialized
initialized = 1;
// clear out all structures
memset((void *)lights,0, sizeof(lights));
} // end if
// now test what command user is sending
switch (command)
{
case BLINKER_ADD: // add a light to the database
{
// run thru database and find an open light
for (int index=0; index < 256; index++)
{
// is this light available?
if (lights[index].state == 0)
{
// set light up
lights[index] = *new_light;
// set internal fields up
lights[index].counter = 0;
lights[index].state = -1; // off
// update palette entry
lpddpal->SetEntries(0,lights[index].color_index,1,&lights[index].off_color);
// return id to caller
return(index);
} // end if
} // end for index
} break;
case BLINKER_DELETE: // delete the light indicated by id
{
// delete the light sent in id
if (lights[id].state != 0)
{
// kill the light
memset((void *)&lights[id],0,sizeof(BLINKER));
// return id
return(id);
} // end if
else
return(-1); // problem
} break;
case BLINKER_UPDATE: // update the light indicated by id
{
// make sure light is active
if (lights[id].state != 0)
{
// update on/off parms only
lights[id].on_color = new_light->on_color;
lights[id].off_color = new_light->off_color;
lights[id].on_time = new_light->on_time;
lights[id].off_time = new_light->off_time;
// update palette entry
if (lights[id].state == -1)
lpddpal->SetEntries(0,lights[id].color_index,1,&lights[id].off_color);
else
lpddpal->SetEntries(0,lights[id].color_index,1,&lights[id].on_color);
// return id
return(id);
} // end if
else
return(-1); // problem
} break;
case BLINKER_RUN: // run the algorithm
{
// run thru database and process each light
for (int index=0; index < 256; index++)
{
// is this active?
if (lights[index].state == -1)
{
// update counter
if (++lights[index].counter >= lights[index].off_time)
{
// reset counter
lights[index].counter = 0;
// change states
lights[index].state = -lights[index].state;
// update color
lpddpal->SetEntries(0,lights[index].color_index,1,&lights[index].on_color);
} // end if
} // end if
else
if (lights[index].state == 1)
{
// update counter
if (++lights[index].counter >= lights[index].on_time)
{
// reset counter
lights[index].counter = 0;
// change states
lights[index].state = -lights[index].state;
// update color
lpddpal->SetEntries(0,lights[index].color_index,1,&lights[index].off_color);
} // end if
} // end else if
} // end for index
} break;
default: break;
} // end switch
// return success
return(1);
} // end Blink_Colors
在game_init()处,添加了3个id,添加了东东,一为红亮黑灭,二为绿亮黑灭。亮灭都有相应的时间。
// load the 8-bit image
if (!Load_Bitmap_File(&bitmap,"starshipanim8.bmp"))
return(0);
// load it's palette into directdraw
if (FAILED(lpddpal->SetEntries(0,0,MAX_COLORS_PALETTE,bitmap.palette)))
return(0);
// clean the surface
DDraw_Fill_Surface(lpddsprimary,0);
// create the blinking lights
BLINKER temp; // used to build up lights
PALETTEENTRY red = {255,0,0,PC_NOCOLLAPSE};
PALETTEENTRY green = {0,255,0,PC_NOCOLLAPSE};
PALETTEENTRY black = {0,0,0,PC_NOCOLLAPSE};
// add red light
temp.color_index = 253;
temp.on_color = red;
temp.off_color = black;
temp.on_time = 30; // 30 cycles at 30fps = 1 sec
temp.off_time = 30;
// make call, note use of C++ call by reference for 2nd parm
int red_id = Blink_Colors(BLINKER_ADD, &temp, 0);
// now create green light
temp.color_index = 254;
temp.on_color = green;
temp.off_color = black;
temp.on_time = 90; // 30 cycles at 30fps = 3 secs
temp.off_time = 90;
// make call, note use of C++ call by reference for 2nd parm
int green_id = Blink_Colors(BLINKER_ADD, &temp, 0);
下面可以看看GAME_MAIN()中怎么操作的。
直接一个
// animate the lights
Blink_Colors(BLINKER_RUN, NULL, 0);
看下截图
下面进行封装,在ddraw_interfacez.h中加上一个结构体,
typedef struct BLINKER_TYP
{
// user sets these
int color_index; // index of color to blink
PALETTEENTRY on_color; // RGB value of "on" color
PALETTEENTRY off_color; // RGB value of "off" color
int on_time; // number of frames to keep "on"
int off_time; // number of frames to keep "off"
// internal member
int counter; // counter for state transitions
int state; // state of light, -1 off, 1 on, 0 dead
} BLINKER, *BLINKER_PTR;
加上个成员函数。
int DDRAW_Interface::Blink_Colors(int command, BLINKER_PTR new_light, int id)
只是将lpddpal改为成员变量m_lpddpal。
在main函数中的
int Game_Init(void *parms = NULL, int num_parms = 0)
{
// this is called once after the initial window is created and
// before the main event loop is entered, do all your initialization
// here
// load the 8-bit image
if (!ddraw->Load_Bitmap_File(&bitmap,"starshipanim8.bmp"))
return(0);
// load it's palette into directdraw
if (FAILED(ddraw->getlpddpal()->SetEntries(0,0,MAX_COLORS_PALETTE,bitmap.palette)))
return(0);
// create the blinking lights
BLINKER temp; // used to build up lights
PALETTEENTRY red = {255,0,0,PC_NOCOLLAPSE};
PALETTEENTRY green = {0,255,0,PC_NOCOLLAPSE};
PALETTEENTRY black = {0,0,0,PC_NOCOLLAPSE};
// add red light
temp.color_index = 253;
temp.on_color = red;
temp.off_color = black;
temp.on_time = 30; // 30 cycles at 30fps = 1 sec
temp.off_time = 30;
// make call, note use of C++ call by reference for 2nd parm
int red_id = ddraw->Blink_Colors(BLINKER_ADD, &temp, 0);
// now create green light
temp.color_index = 254;
temp.on_color = green;
temp.off_color = black;
temp.on_time = 90; // 30 cycles at 30fps = 3 secs
temp.off_time = 90;
// make call, note use of C++ call by reference for 2nd parm
int green_id = ddraw->Blink_Colors(BLINKER_ADD, &temp, 0);
// return success or failure or your own return code here
return(1);
}
循环函数也是逐行扫描。
int Game_Main(void *parms = NULL, int num_parms = 0)
{
// this is the main loop of the game, do all your processing
// here
// make sure this isn't executed again
if (window_closed)
return(0);
// for now test if user is hitting ESC and send WM_CLOSE
if (KEYDOWN(VK_ESCAPE))
{
PostMessage(main_window_handle,WM_CLOSE,0,0);
window_closed = 1;
} // end if
ddraw->DDraw_Lock_Primary_Surface();
// get video pointer to primary surfce
UCHAR *primary_buffer = (UCHAR *)ddraw->getPrimarybuffer();
// test if memory is linear
if (ddraw->getPrimarylpitch() == SCREEN_WIDTH)
{
// copy memory from double buffer to primary buffer
memcpy((void *)primary_buffer, (void *)bitmap.buffer, SCREEN_WIDTH*SCREEN_HEIGHT);
} // end if
else
{ // non-linear
// make copy of source and destination addresses
UCHAR *dest_ptr = primary_buffer;
UCHAR *src_ptr = bitmap.buffer;
// memory is non-linear, copy line by line
for (int y=0; y < SCREEN_HEIGHT; y++)
{
// copy line
memcpy((void *)dest_ptr, (void *)src_ptr, SCREEN_WIDTH);
// advance pointers to next line
dest_ptr+=ddraw->getPrimarylpitch();
src_ptr +=SCREEN_WIDTH;
} // end for
} // end else
ddraw->DDraw_Unlock_Primary_Surface();
// animate the lights
ddraw->Blink_Colors(BLINKER_RUN, NULL, 0);
// wait a sec
Sleep(33);
// do nothing -- look at pretty picture
// return success or failure or your own return code here
return(1);
}
OK,结果一样