📄 raiders3d.cpp
字号:
ties[index].yv = -4+rand()%8;
ties[index].zv = -4-rand()%64;
// turn the tie fighter on
ties[index].state = 1;
} // end Init_Tie
/////////////////////////////////////////////////////////
void Process_Ties(void)
{
// process the tie fighters and do AI (what there is of it!)
int index; // looping var
// move each tie fighter toward the viewpoint
for (index=0; index<NUM_TIES; index++)
{
// is this one dead?
if (ties[index].state==0)
continue;
// move the next star
ties[index].z+=ties[index].zv;
ties[index].x+=ties[index].xv;
ties[index].y+=ties[index].yv;
// test for past near clipping plane
if (ties[index].z <= NEAR_Z)
{
// reset this tie
Init_Tie(index);
// another got away
misses++;
} // reset tie
} // end for index
} // Process_Ties
//////////////////////////////////////////////////////////
void Draw_Ties(void)
{
// draw the tie fighters in 3D wireframe with perspective
int index; // looping var
// used to compute the bounding box of tie fighter
// for collision detection
int bmin_x, bmin_y, bmax_x, bmax_y;
// draw each tie fighter
for (index=0; index < NUM_TIES; index++)
{
// draw the next tie fighter
// is this one dead?
if (ties[index].state==0)
continue;
// reset the bounding box to impossible values
bmin_x = 100000;
bmax_x = -100000;
bmin_y = 100000;
bmax_y = -100000;
// based on z-distance shade tie fighter
// normalize the distance from 0 to max_z then
// scale it to 255, so the closer the brighter
USHORT rgb_tie_color = RGB16Bit(0,(255-255*(ties[index].z/(4*FAR_Z))),0);
// each tie fighter is made of a number of edges
for (int edge=0; edge < NUM_TIE_EDGES; edge++)
{
POINT3D p1_per, p2_per; // used to hold perspective endpoints
// step 1: perspective transform each end point
// note the translation of each point to the position of the tie fighter
// that is the model is relative to the position of each tie fighter -- IMPORTANT
p1_per.x =
VIEW_DISTANCE*(ties[index].x+tie_vlist[tie_shape[edge].v1].x)/
(tie_vlist[tie_shape[edge].v1].z+ties[index].z);
p1_per.y = VIEW_DISTANCE*(ties[index].y+tie_vlist[tie_shape[edge].v1].y)/
(tie_vlist[tie_shape[edge].v1].z+ties[index].z);
p2_per.x = VIEW_DISTANCE*(ties[index].x+tie_vlist[tie_shape[edge].v2].x)/
(tie_vlist[tie_shape[edge].v2].z+ties[index].z);
p2_per.y = VIEW_DISTANCE*(ties[index].y+tie_vlist[tie_shape[edge].v2].y)/
(tie_vlist[tie_shape[edge].v2].z+ties[index].z);
// step 2: compute screen coords
int p1_screen_x = WINDOW_WIDTH/2 + p1_per.x;
int p1_screen_y = WINDOW_HEIGHT/2 - p1_per.y;
int p2_screen_x = WINDOW_WIDTH/2 + p2_per.x;
int p2_screen_y = WINDOW_HEIGHT/2 - p2_per.y;
// step 3: draw the edge
Draw_Clip_Line16(p1_screen_x , p1_screen_y , p2_screen_x , p2_screen_y,
rgb_tie_color,back_buffer, back_lpitch);
// update bounding box with next edge
int min_x = min(p1_screen_x, p2_screen_x);
int max_x = max(p1_screen_x, p2_screen_x);
int min_y = min(p1_screen_y, p2_screen_y);
int max_y = max(p1_screen_y, p2_screen_y);
bmin_x = min(bmin_x, min_x);
bmin_y = min(bmin_y, min_y);
bmax_x = max(bmax_x, max_x);
bmax_y = max(bmax_y, max_y);
} // end for edge
// test if this guy has been hit by lasers???
if (cannon_state==1)
{
// simple test of screen coords of bounding box contain laser target
if (target_x_screen > bmin_x && target_x_screen < bmax_x &&
target_y_screen > bmin_y && target_y_screen < bmax_y)
{
// this tie is dead meat!
Start_Explosion(index);
// start sound
DSound_Play(explosion_id );
// increase score
score+=ties[index].z;
// add one more hit
hits++;
// finally reset this tie figher
Init_Tie(index);
} // end if
} // end if
} // end for index
} // end Draw_Ties
//////////////////////////////////////////////////////////
int Game_Main(void *parms)
{
// this is the workhorse of your game it will be called
// continuously in real-time this is like main() in C
// all the calls for your game go here!
int index; // looping var
// start the timing clock
Start_Clock();
// clear the drawing surface
DDraw_Fill_Surface(lpddsback, 0);
// read keyboard and other devices here
DInput_Read_Keyboard();
// game logic here...
if (game_state==GAME_RUNNING)
{
// move players crosshair
if (keyboard_state[DIK_RIGHT])
{
// move cross hair to right
cross_x+=CROSS_VEL;
// test for wraparound
if (cross_x > WINDOW_WIDTH/2)
cross_x = -WINDOW_WIDTH/2;
} // end if
if (keyboard_state[DIK_LEFT])
{
// move cross hair to left
cross_x-=CROSS_VEL;
// test for wraparound
if (cross_x < -WINDOW_WIDTH/2)
cross_x = WINDOW_WIDTH/2;
} // end if
if (keyboard_state[DIK_DOWN])
{
// move cross hair up
cross_y-=CROSS_VEL;
// test for wraparound
if (cross_y < -WINDOW_HEIGHT/2)
cross_y = WINDOW_HEIGHT/2;
} // end if
if (keyboard_state[DIK_UP])
{
// move cross hair up
cross_y+=CROSS_VEL;
// test for wraparound
if (cross_y > WINDOW_HEIGHT/2)
cross_y = -WINDOW_HEIGHT/2;
} // end if
// speed of ship controls
if (keyboard_state[DIK_A])
player_z_vel++;
else
if (keyboard_state[DIK_S])
player_z_vel--;
// test if player is firing laser cannon
if (keyboard_state[DIK_SPACE] && cannon_state==0)
{
// fire the cannon
cannon_state = 1;
cannon_count = 0;
// save last position of targeter
target_x_screen = cross_x_screen;
target_y_screen = cross_y_screen;
// make sound
DSound_Play(laser_id);
} // end if
} // end if game running
// process cannon, simple FSM ready->firing->cool
// firing phase
if (cannon_state == 1)
if (++cannon_count > 15)
cannon_state = 2;
// cool down phase
if (cannon_state == 2)
if (++cannon_count > 20)
cannon_state = 0;
// move the starfield
Move_Starfield();
// move and perform ai for ties
Process_Ties();
// Process the explosions
Process_Explosions();
// lock the back buffer and obtain pointer and width
DDraw_Lock_Back_Surface();
// draw the starfield
Draw_Starfield();
// draw the tie fighters
Draw_Ties();
// draw the explosions
Draw_Explosions();
// draw the crosshairs
// first compute screen coords of crosshair
// note inversion of y-axis
cross_x_screen = WINDOW_WIDTH/2 + cross_x;
cross_y_screen = WINDOW_HEIGHT/2 - cross_y;
// draw the crosshair in screen coords
Draw_Clip_Line16(cross_x_screen-16,cross_y_screen,
cross_x_screen+16,cross_y_screen,
rgb_red,back_buffer,back_lpitch);
Draw_Clip_Line16(cross_x_screen,cross_y_screen-16,
cross_x_screen,cross_y_screen+16,
rgb_red,back_buffer,back_lpitch);
Draw_Clip_Line16(cross_x_screen-16,cross_y_screen-4,
cross_x_screen-16,cross_y_screen+4,
rgb_red,back_buffer,back_lpitch);
Draw_Clip_Line16(cross_x_screen+16,cross_y_screen-4,
cross_x_screen+16,cross_y_screen+4,
rgb_red,back_buffer,back_lpitch);
// draw the laser beams
if (cannon_state == 1)
{
if ((rand()%2 == 1))
{
// right beam
Draw_Clip_Line16(WINDOW_WIDTH-1, WINDOW_HEIGHT-1,
-4+rand()%8+target_x_screen,-4+rand()%8+target_y_screen,
RGB16Bit(0,0,rand()),back_buffer,back_lpitch);
} // end if
else
{
// left beam
Draw_Clip_Line16(0, WINDOW_HEIGHT-1,
-4+rand()%8+target_x_screen,-4+rand()%8+target_y_screen,
RGB16Bit(0,0,rand()),back_buffer,back_lpitch);
} // end if
} // end if
// done rendering, unlock back buffer surface
DDraw_Unlock_Back_Surface();
// draw the informtion
sprintf(buffer, "Score %d Kills %d Escaped %d", score, hits, misses);
Draw_Text_GDI(buffer, 0,0,RGB(0,255,0), lpddsback);
if (game_state==GAME_OVER)
Draw_Text_GDI("G A M E O V E R", WINDOW_WIDTH/2-8*10,WINDOW_HEIGHT/2,RGB(255,255,255), lpddsback);
// check if the music has finished, if so restart
if (DMusic_Status_MIDI(main_track_id)==MIDI_STOPPED)
DMusic_Play(main_track_id);
// flip the surfaces
DDraw_Flip();
// sync to 30ish fps
Wait_Clock(30);
// check for game state switch
if (misses > 4*NUM_TIES)
game_state = GAME_OVER;
// check of user is trying to exit
if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE])
{
PostMessage(main_window_handle, WM_DESTROY,0,0);
} // end if
// return success
return(1);
} // end Game_Main
//////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -