⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 raiders3d.cpp

📁 游戏经典书 3D游戏编程大师技巧 源代码,本书是游戏编程畅销书作者Andre LaMothe的扛鼎之作
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    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 + -