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

📄 demo12_3.cpp

📁 《Windows游戏编程大师技巧(第二版)》源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:


void Init_Plasma(void)
{
// this function initializes and loads all the plasma 
// weapon pulses

// the plasma animations
static int plasma_anim_player[] = {0,1,2,3,4,5,6,7},
   		   plasma_anim_enemy[]  = {8,9,10,11,12,13,14,15};

// load the plasma imagery 
Load_Bitmap_File(&bitmap8bit, "OUTART/ENERGY8.BMP");

// create the first bob
Create_BOB(&plasma[0],0,0,8,8,16,
            BOB_ATTR_VISIBLE | BOB_ATTR_MULTI_ANIM,
            DDSCAPS_SYSTEMMEMORY);

// load animation frames
for (int frame=0; frame < 16; frame++)
     Load_Frame_BOB(&plasma[0],&bitmap8bit,frame,frame%8,frame/8,BITMAP_EXTRACT_MODE_CELL);  

// set animation rate
Set_Anim_Speed_BOB(&plasma[0],1);

// load animations
Load_Animation_BOB(&plasma[0], PLASMA_ANIM_PLAYER, 8, plasma_anim_player);
Load_Animation_BOB(&plasma[0], PLASMA_ANIM_ENEMY, 8, plasma_anim_enemy);

// set state to off
plasma[0].state = PLASMA_STATE_OFF;

for (int pulse=1; pulse < MAX_PLASMA; pulse++)
    {
    memcpy(&plasma[pulse], &plasma[0], sizeof(BOB));
    } // end for pulse

// unload data infile
Unload_Bitmap_File(&bitmap8bit);

} // end Init_Plasma

/////////////////////////////////////////////////////////

void Reset_Plasma(void)
{
// this function resets all the plasma pulses
for (int pulse = 0; pulse < MAX_PLASMA; pulse++)
    {
    plasma[pulse].state = PLASMA_STATE_OFF;
    } // end for pulse

} // end Reset_Plasma

///////////////////////////////////////////////////////////

void Delete_Plasma(void)
{
// this function simply deletes all memory and surfaces
// related to the plasma pulses

for (int index=0; index < MAX_PLASMA; index++)
    Destroy_BOB(&plasma[index]);

} // end Delete_Plasma

///////////////////////////////////////////////////////////

void Move_Plasma(void)
{
// this function moves all the plasma pulses and checks for
// collision with the rocks

for (int index=0; index < MAX_PLASMA; index++)
    {
    // test if plasma pulse is in flight
    if (plasma[index].state == PLASMA_STATE_ON)
        {
        // move the pulse 
        plasma[index].varsI[INDEX_WORLD_X]+=plasma[index].xv;
        plasma[index].varsI[INDEX_WORLD_Y]+=plasma[index].yv;
          
        // test for boundaries
        if ( (++plasma[index].counter_1 > PLASMA_RANGE_1)              || 
                (plasma[index].varsI[INDEX_WORLD_X] > UNIVERSE_MAX_X)  || 
                (plasma[index].varsI[INDEX_WORLD_X] < UNIVERSE_MIN_X ) ||
	            (plasma[index].varsI[INDEX_WORLD_Y] > UNIVERSE_MAX_Y)  || 
                (plasma[index].varsI[INDEX_WORLD_Y] < UNIVERSE_MIN_Y ) )
            {
            // kill the pulse
            plasma[index].state = PLASMA_STATE_OFF;
            plasma[index].counter_1 = 0;

            // move to next pulse
            continue;
            } // end if


// test for mines

 // test for mines
 for (int mine=0; mine < MAX_MINES; mine++)
     {
     if (mines[mine].state==MINE_STATE_ALIVE && 
         plasma[index].anim_state == PLASMA_ANIM_PLAYER  )
         {
         // test for collision 
         if (Collision_Test(plasma[index].varsI[INDEX_WORLD_X]-(plasma[index].width*.5), 
                            plasma[index].varsI[INDEX_WORLD_Y]-(plasma[index].height*.5), 
                            plasma[index].width, plasma[index].height,
                            mines[mine].varsI[INDEX_WORLD_X]-(mines[mine].width*.5), 
			     		    mines[mine].varsI[INDEX_WORLD_Y]-(mines[mine].height*.5),
                            mines[mine].width, mines[mine].height))
             {
             // kill pulse
             plasma[index].state     = PLASMA_STATE_OFF;
             plasma[index].counter_1 = 0;

             // do damage to mine
             mines[mine].varsI[INDEX_MINE_DAMAGE]+=(1+rand()%3);

             // increase the damage on the mine and test for death
             if (mines[mine].varsI[INDEX_MINE_DAMAGE] > MAX_MINE_DAMAGE)
                {
                // kill the ship    
                mines[mine].state=MINE_STATE_DEAD;

                // start a new mine
                Start_Mine();

                // add to players score
                player_score+=250;

                } // end if

             int width = 30+rand()%40;

             // start a burst
             Start_Burst(plasma[index].varsI[INDEX_WORLD_X], 
                         plasma[index].varsI[INDEX_WORLD_Y], 
                         width, (width*.5) + (width*.25),
                         int(mines[mine].xv)*.5, int(mines[mine].yv)*.5);   
             break; 
             } // end if
     
     } // end if alive

     } // end for mines


///////////////////////////////////////////////////////

// test for stations
 for (int station=0; station < MAX_STATIONS; station++)
     {
     if (stations[station].state == STATION_STATE_ALIVE && 
         plasma[index].anim_state == PLASMA_ANIM_PLAYER  )
         {
         // test for collision 
         if ( //stations[station].anim_state == STATION_SHIELDS_ANIM_OFF &&
             Collision_Test(plasma[index].varsI[INDEX_WORLD_X]-(plasma[index].width*.5), 
                            plasma[index].varsI[INDEX_WORLD_Y]-(plasma[index].height*.5), 
                            plasma[index].width, plasma[index].height,
                            stations[station].varsI[INDEX_WORLD_X]-(stations[station].width*.5), 
			     		    stations[station].varsI[INDEX_WORLD_Y]-(stations[station].height*.5),
                            stations[station].width, stations[station].height))
             {
             // kill pulse
             plasma[index].state = PLASMA_STATE_OFF;
             plasma[index].counter_1 = 0;

             // do damage to station
             stations[station].varsI[INDEX_STATION_DAMAGE]+=(1+rand()%3);

             // increase the damage on the station and test for death
             if (stations[station].varsI[INDEX_STATION_DAMAGE] > MAX_STATION_DAMAGE)
                {
                // kill the station
                stations[station].state=STATION_STATE_DEAD;

                // add to players score
                player_score+=10000;

                // has played won
                if (++num_stations_destroyed >= NUM_ACTIVE_STATIONS)
                   {
                   win_counter = 0;
                   player_won = 1;   
                   } // end if

                // make big sound
                DSound_Play(station_blow_id);

                } // end if

             // start a burst
             Start_Burst(plasma[index].varsI[INDEX_WORLD_X], 
                         plasma[index].varsI[INDEX_WORLD_Y], 
                         40+rand()%20,30+rand()%16,
                         int(stations[station].xv)*.5, int(stations[station].yv)*.5);   
             break; 
             } // end if
     
     } // end if alive

     } // end for stations


///////////////////////////////////////////////////////


    // test for collision with player
    if (plasma[index].anim_state == PLASMA_ANIM_ENEMY && player_state == PLAYER_STATE_ALIVE &&
        Collision_Test(plasma[index].varsI[INDEX_WORLD_X]-(plasma[index].width*.5), 
		               plasma[index].varsI[INDEX_WORLD_Y]-(plasma[index].height*.5), 
                       plasma[index].width, plasma[index].height,
                       player_x-(wraith.width*.5), 
                       player_y-(wraith.height*.5),
                       wraith.width, wraith.height))
        {

        Start_Burst(plasma[index].varsI[INDEX_WORLD_X], 
                    plasma[index].varsI[INDEX_WORLD_Y], 
                    40+rand()%20,30+rand()%16,
                    int(player_xv)*.5, int(player_yv)*.5);

        // update players damage
        player_damage+=2;

    
        // engage shields
        player_shield_count=3;

        // kill the pulse
        plasma[index].state = PLASMA_STATE_OFF;
        plasma[index].counter_1 = 0;

        // plasma is dead
        continue;
        } // end if

 ////////////////////////////////////////////////////////


        // test for collision with rocks
        for (int rock=0; rock < MAX_ROCKS; rock++)
            {
            if (rocks[rock].state==ROCK_STATE_ON)
                {
                // test for collision 
                if (Collision_Test(plasma[index].varsI[INDEX_WORLD_X]-(plasma[index].width*.5), 
					               plasma[index].varsI[INDEX_WORLD_Y]-(plasma[index].height*.5), 
                                   plasma[index].width, plasma[index].height,
                                   rocks[rock].varsI[INDEX_WORLD_X]-(rocks[rock].width*.5), 
								   rocks[rock].varsI[INDEX_WORLD_Y]-(rocks[rock].height*.5),
                                   rocks[rock].width, rocks[rock].height))
                    {
                    // kill pulse
                    plasma[index].state = PLASMA_STATE_OFF;
                    plasma[index].counter_1 = 0;
  
                    switch(rocks[rock].varsI[0])
                          {
                          case ROCK_LARGE:
                              {
                              // start explosion
                              Start_Burst(plasma[index].varsI[INDEX_WORLD_X], plasma[index].varsI[INDEX_WORLD_Y], 
                                          68+rand()%12,54+rand()%10,
                                          rocks[rock].xv*.5, rocks[rock].yv*.5);
                                        
                              } break;

                          case ROCK_MEDIUM:
                              {
                              // start explosion
                              Start_Burst(plasma[index].varsI[INDEX_WORLD_X], plasma[index].varsI[INDEX_WORLD_Y], 
                                          52+rand()%10,44+rand()%8,
                                          rocks[rock].xv*.5, rocks[rock].yv*.5);

                              } break;

                          case ROCK_SMALL:
                              {

                              // start explosion
                              Start_Burst(plasma[index].varsI[INDEX_WORLD_X], plasma[index].varsI[INDEX_WORLD_Y], 
                                          34-4+rand()%8,30-3+rand()%6,
                                          rocks[rock].xv*.5, rocks[rock].yv*.5);

                              } break;
                          
                          } // end switch

                    // update score
                    player_score+=rocks[rock].varsI[2];

                    // test strength of rock, cause damage
                    rocks[rock].varsI[2]-=50;

                    // split test
                    if (rocks[rock].varsI[2] > 0 && rocks[rock].varsI[2] < 50)
                        {
                        // test the size of rock
                        switch(rocks[rock].varsI[0])
                        {
                        case ROCK_LARGE:
                            {
                            // split into two medium
                            Start_Rock(rocks[rock].varsI[INDEX_WORLD_X]+rand()%16,rocks[rock].varsI[INDEX_WORLD_Y]+rand()%16,
                                       ROCK_MEDIUM,
                                       rocks[rock].xv-2+rand()%4,rocks[rock].yv-2+rand()%4);
                    
                            Start_Rock(rocks[rock].varsI[INDEX_WORLD_X]+rand()%16,rocks[rock].varsI[INDEX_WORLD_Y]+rand()%16,
                                       ROCK_MEDIUM,
                                       rocks[rock].xv-2+rand()%4,rocks[rock].yv-2+rand()%4);
                            
                           // throw in a small?
                           if ((rand()%3)==1)
                            Start_Rock(rocks[rock].varsI[INDEX_WORLD_X]+rand()%16,rocks[rock].varsI[INDEX_WORLD_Y]+rand()%16,
                                       ROCK_SMALL,
                                       rocks[rock].xv-2+rand()%4,rocks[rock].yv-2+rand()%4);

                            // kill the original
                            rocks[rock].state = ROCK_STATE_OFF;     
            
                            } break;

                        case ROCK_MEDIUM:
                            {
                            // split into 1 - 3 small
                            int num_rocks = 1+rand()%3;

                            for (; num_rocks >=1; num_rocks--)
                                {
                                Start_Rock(rocks[rock].varsI[INDEX_WORLD_X]+rand()%8,rocks[rock].varsI[INDEX_WORLD_Y]+rand()%8,
                                           ROCK_SMALL,
                                           rocks[rock].xv-2+rand()%4,rocks[rock].yv-2+rand()%4);

                                } // end for num_rocks
                 
                            // kill the original
                            rocks[rock].state = ROCK_STATE_OFF;

                            } break;

                        case ROCK_SMALL:
                            {
                            // just kill it
                            rocks[rock].state = ROCK_STATE_OFF;

                            } break;
 
                        default:break;

        
                        } // end switch

                        } // end if split
                    else
                    if (rocks[rock].varsI[2] <= 0)
                        {
                        // kill rock
                        rocks[rock].state = ROCK_STATE_OFF;
                        } // end else

                    // break out of loop
                    break;

                   } // end if collision

                } // end if rock alive

            } // end for rock

      } // end if

    } // end for index

} // end Move_Plasma

///////////////////////////////////////////////////////////

void Draw_Plasma(void)
{
// this function draws all the plasma pulses

for (int index=0; index<MAX_PLASMA; index++)
    {
    // test if plasma pulse is in flight
    if (plasma[index].state == PLASMA_STATE_ON)
        {
        // transform to screen coords
        plasma[index].x = plasma[index].varsI[INDEX_WORLD_X] - (plasma[index].width >> 1) - player_x + (SCREEN_WIDTH/2);
        plasma[index].y = plasma[index].varsI[INDEX_WORLD_Y] - (plasma[index].height >> 1) - player_y + (SCREEN_HEIGHT/2);

        // draw the pulse
        Draw_BOB(&plasma[index],lpddsback);
         
        // animate the pulse
        Animate_BOB(&plasma[index]);

        } // end if

    } // end for index

} // end Draw_Plasma

///////////////////////////////////////////////////////////

void Fire_Plasma(int x,int y, int xv, int yv, int source=PLASMA_ANIM_PLAYER)
{
// this function fires a plasma pulse at the given starting
// position and velocity, of course, one must be free for 
// this to work

// scan for a pulse that is available
for (int index=0; index < MAX_PLASMA; index++)
    {
    // is this one available
      // test if plasma pulse is in flight
    if (plasma[index].state == PLASMA_STATE_OFF)
       {
       // start this one up, note the use of world coords
       plasma[index].varsI[INDEX_WORLD_X] = x-(plasma[0].width*.5);
       plasma[index].varsI[INDEX_WORLD_Y] = y-(plasma[0].height*.5);
       
       plasma[index].xv = xv;
	   plasma[index].yv = yv;
       plasma[index].curr_frame = 0;
  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -