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

📄 outpost.cpp

📁 一个太空大战游戏的源程序及演示程序 VC++ 6.0
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  		   stations[index].varsI[INDEX_WORLD_X] = UNIVERSE_MIN_X;
           } // end if
		else
		if (stations[index].varsI[INDEX_WORLD_X] < UNIVERSE_MIN_X )
           {
  		   stations[index].varsI[INDEX_WORLD_X] = UNIVERSE_MAX_X;
           } // end if	    

		if (stations[index].varsI[INDEX_WORLD_Y] > UNIVERSE_MAX_Y)
           {
		   stations[index].varsI[INDEX_WORLD_Y] = UNIVERSE_MIN_Y;
           } // end if
		else
		if (stations[index].varsI[INDEX_WORLD_Y] < UNIVERSE_MIN_Y ) 
           {
		   stations[index].varsI[INDEX_WORLD_Y] = UNIVERSE_MAX_Y;
           } // end if

        // test for damage level
        if (stations[index].varsI[INDEX_STATION_DAMAGE] > (MAX_STATION_DAMAGE/4) &&
            (rand()%(20 - (stations[index].varsI[INDEX_STATION_DAMAGE] >> 3))) == 1)
            {
            int width = 20+rand()%60;

             // start a burst
             Start_Burst(stations[index].varsI[INDEX_WORLD_X] - (stations[index].width>>1)+RAND_RANGE(0,stations[index].width),
                         stations[index].varsI[INDEX_WORLD_Y] - (stations[index].height>>1)+RAND_RANGE(0,stations[index].height), 
                         width,(width >> 2) + (width >> 1),
                         int(stations[index].xv)>>1, int(stations[index].yv)>>1);   

            // add some particles

            } // end if

		} // end if alive

	} // end for index

} // end Move_Stations

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

void Draw_Stations(void)
{
// this function draws all the stations

for (int index=0; index < MAX_STATIONS; index++)
    {
    // test if station is alive
    if (stations[index].state == STATION_STATE_ALIVE)
        {
        // transform to screen coords
        stations[index].x = stations[index].varsI[INDEX_WORLD_X] - (stations[index].width >> 1) - player_x + (SCREEN_WIDTH/2);
        stations[index].y = stations[index].varsI[INDEX_WORLD_Y] - (stations[index].height >> 1) - player_y + (SCREEN_HEIGHT/2);

        // draw the station
        Draw_BOB(&stations[index],lpddsback);

		// animate the station
        Animate_BOB(&stations[index]);
         
        } // end if

    } // end for index

} // end Draw_Stations

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

void Delete_Stations(void)
{
// this function simply deletes all memory and surfaces
// related to the gunships

for (int index=0; index < MAX_STATIONS; index++)
    Destroy_BOB(&stations[index]);

} // end Delete_Stations

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

void Init_Mines(void)
{
// this function loads and initializes the mines to a known state
	
int frame;  // looping va

// create the first bob
Create_BOB(&mines[0],0,0,48,36,16,
            BOB_ATTR_VISIBLE | BOB_ATTR_MULTI_FRAME,
            DDSCAPS_SYSTEMMEMORY);

// load animation frames 
for (frame = 0; frame <= 15; frame++)
	{
	// load the mine
    Pad_Name("OUTART/PREDMINE", "BMP", buffer, frame);
	Load_Bitmap_File(&bitmap8bit, buffer);		

    // load the actual .BMP
    Load_Frame_BOB(&mines[0],&bitmap8bit,frame,0,0,BITMAP_EXTRACT_MODE_ABS);  

    // unload data infile
    Unload_Bitmap_File(&bitmap8bit);

	} // end if

// set state to off
mines[0].state  = MINE_STATE_DEAD;

// set ai state to sleep mode
mines[0].varsI[INDEX_MINE_AI_STATE] = MINE_STATE_AI_SLEEP;

// set damage to 0
mines[0].varsI[INDEX_MINE_DAMAGE] = 0;

// set contact count to 0
mines[0].varsI[INDEX_MINE_CONTACT_COUNT] = 0;

// set animation rate
Set_Anim_Speed_BOB(&mines[0],3);

// make copies
for (int mine=1; mine < MAX_MINES; mine++)
    {
    memcpy(&mines[mine], &mines[0], sizeof(BOB));
    } // end for mine

} // end Init_Mines

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

void Reset_Mines(void)
{
// this functions resets all the mines

// make copies
for (int mine = 0; mine < MAX_MINES; mine++)
    {
    // set state to off
    mines[mine].state = MINE_STATE_DEAD;

    // set ai state to sleep mode
    mines[mine].varsI[INDEX_MINE_AI_STATE] = MINE_STATE_AI_SLEEP;

    // set damage to 0
    mines[mine].varsI[INDEX_MINE_DAMAGE] = 0;

    // set contact count to 0
    mines[mine].varsI[INDEX_MINE_CONTACT_COUNT] = 0;

    } // end for mine

} // end Reset_Mines

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

void Start_Mine(int override=0, int x=0, int y=0, int ai_state=MINE_STATE_AI_ACTIVATED)
{
// this functions starts a mine, note that if override = 1
// then the function uses the sent data otherwise it's random

// first find an available stations
for (int index=0; index < MAX_MINES; index++)
	{
	// is this one dead
	if (mines[index].state  == MINE_STATE_DEAD)
		{

        if (!override)
            {
	    	// position the mine
    		int xpos = RAND_RANGE((UNIVERSE_MIN_X+256),(UNIVERSE_MAX_X-256));
		    int ypos = RAND_RANGE((UNIVERSE_MIN_Y+256),(UNIVERSE_MAX_Y-256));

            // set position
		    mines[index].varsI[INDEX_WORLD_X] = xpos;
		    mines[index].varsI[INDEX_WORLD_Y] = ypos;

  	        // set velocity
		    mines[index].xv = RAND_RANGE(-8,8);
		    mines[index].yv = RAND_RANGE(-8,8);

		    // set remaining state variables
		    mines[index].state  = MINE_STATE_ALIVE;

		    // set damage to 0
            mines[index].varsI[INDEX_MINE_DAMAGE] = 0;

            // set ai state
            mines[index].varsI[INDEX_MINE_AI_STATE] = ai_state;

            // set contact count
            mines[index].varsI[INDEX_MINE_CONTACT_COUNT] = 0;
            
		    // done so exit
		    return;

            }
        else
            {
            // set position
		    mines[index].varsI[INDEX_WORLD_X] = x;
		    mines[index].varsI[INDEX_WORLD_Y] = y;

      	    // set velocity
	    	mines[index].xv = 0;
		    mines[index].yv = 0;

		    // set remaining state variables
		    mines[index].state  = MINE_STATE_ALIVE;

		    // set damage to 0
            mines[index].varsI[INDEX_MINE_DAMAGE] = 0;

            // set ai state
            mines[index].varsI[INDEX_MINE_AI_STATE] = ai_state;

            // set contact count
            mines[index].varsI[INDEX_MINE_CONTACT_COUNT] = 0;

		    // done so exit
		    return;

            } // end else


		} // end if alive
	
	} // end for index

} // end Start_Mine

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

void Move_Mines(void)
{
// this function moves/animates all the mines

for (int index=0; index < MAX_MINES; index++)
    {
    // test if station is alive
    if (mines[index].state == MINE_STATE_ALIVE)
        {

// test for activation
if (mines[index].varsI[INDEX_MINE_AI_STATE] == MINE_STATE_AI_ACTIVATED)
    {

        // move the mines
        mines[index].varsI[INDEX_WORLD_X]+=mines[index].xv;
        mines[index].varsI[INDEX_WORLD_Y]+=mines[index].yv;


       // add damage trails
       if (mines[index].varsI[INDEX_MINE_DAMAGE] > (MAX_MINE_DAMAGE >> 1) && 
           (rand()%3)==1)
        {
        Start_Particle(PARTICLE_TYPE_FLICKER, PARTICLE_COLOR_WHITE, 30+rand()%25, 
                      mines[index].varsI[INDEX_WORLD_X]+RAND_RANGE(-4,4), 
                      mines[index].varsI[INDEX_WORLD_Y]+RAND_RANGE(-4,4), 
                      (mines[index].xv>>3), (mines[index].yv>>3));
    
        Start_Particle(PARTICLE_TYPE_FADE, PARTICLE_COLOR_RED, 5, 
                      mines[index].varsI[INDEX_WORLD_X]+RAND_RANGE(-4,4), 
                      mines[index].varsI[INDEX_WORLD_Y]+RAND_RANGE(-4,4), 
                      (mines[index].xv>>3), (mines[index].yv>>3));

        } // end if

        // tracking algorithm

        // compute vector toward player
        float vx = player_x - mines[index].varsI[INDEX_WORLD_X];
        float vy = player_y - mines[index].varsI[INDEX_WORLD_Y];

        // normalize vector (sorta :)
        float length = Fast_Distance_2D(vx,vy);


        // only track if reasonable close
        if (length < MIN_MINE_TRACKING_DIST)
            {
            vx=mine_tracking_rate*vx/length;
            vy=mine_tracking_rate*vy/length;

            // add velocity vector to current velocity
            mines[index].xv+=vx;
            mines[index].yv+=vy;

            // add a little noise
            if ((rand()%10)==1)
                {
                vx = RAND_RANGE(-1,1);
                vy = RAND_RANGE(-1,1);
                mines[index].xv+=vx;
                mines[index].yv+=vy;
                } // end if

            // test velocity vector of mines
            length = Fast_Distance_2D(mines[index].xv, mines[index].yv);

            // test for velocity overflow and slow
            if (length > MAX_MINE_VELOCITY)
                {
                // slow down
                mines[index].xv*=0.75;
                mines[index].yv*=0.75;

                } // end if

            } // end if
        else
            {
            // add a random velocity component
            if ((rand()%30)==1)
                {
                vx = RAND_RANGE(-2,2);
                vy = RAND_RANGE(-2,2);

                // add velocity vector to current velocity
                mines[index].xv+=vx;
                mines[index].yv+=vy;

                // test velocity vector of mines
                length = Fast_Distance_2D(mines[index].xv, mines[index].yv);

                // test for velocity overflow and slow
                if (length > MAX_MINE_VELOCITY)
                    {
                    // slow down
                    mines[index].xv*=0.75;
                    mines[index].yv*=0.75;

                    } // end if
        
                } // end if
           
            } // end else

        } // end if activated
    else
        {
        // compute dist from player
        float vx = player_x - mines[index].varsI[INDEX_WORLD_X];
        float vy = player_y - mines[index].varsI[INDEX_WORLD_Y];

        float length = Fast_Distance_2D(vx,vy);

        if (length < MIN_MINE_ACTIVATION_DIST)
            {
            mines[index].varsI[INDEX_MINE_AI_STATE] = MINE_STATE_AI_ACTIVATED;

            // sound off
            DSound_Play(mine_powerup_id);
            } // end if

        } // end else

        // test for boundaries
        if (mines[index].varsI[INDEX_WORLD_X] > UNIVERSE_MAX_X)
           {
  		   mines[index].varsI[INDEX_WORLD_X] = UNIVERSE_MIN_X;
           } // end if
		else
		if (mines[index].varsI[INDEX_WORLD_X] < UNIVERSE_MIN_X )
           {
  		   mines[index].varsI[INDEX_WORLD_X] = UNIVERSE_MAX_X;
           } // end if	    

		if (mines[index].varsI[INDEX_WORLD_Y] > UNIVERSE_MAX_Y)
           {
		   mines[index].varsI[INDEX_WORLD_Y] = UNIVERSE_MIN_Y;
           } // end if
		else
		if (mines[index].varsI[INDEX_WORLD_Y] < UNIVERSE_MIN_Y ) 
           {
		   mines[index].varsI[INDEX_WORLD_Y] = UNIVERSE_MAX_Y;
           } // end if

    // check for collision with player
         if (player_state == PLAYER_STATE_ALIVE && player_state == PLAYER_STATE_ALIVE &&
             Collision_Test(player_x-(wraith.width>>1), 
                            player_y-(wraith.height>>1), 
                            wraith.width, wraith.height,
                            mines[index].varsI[INDEX_WORLD_X]-(mines[index].width>>1), 
			     		    mines[index].varsI[INDEX_WORLD_Y]-(mines[index].height>>1),
                            mines[index].width, mines[index].height)) 
             {

             // test for contact count
             if (++mines[index].varsI[INDEX_MINE_CONTACT_COUNT] > MAX_MINE_CONTACT_COUNT)
                {
            
                 // add to players score
                 player_score+=250;

                 // damage player
                 player_damage+=30;

                 // engage shields
                 player_shield_count = 3;

                 int width = 30+rand()%40;

                 // start a burst
                 Start_Burst(mines[index].varsI[INDEX_WORLD_X], 
                             mines[index].varsI[INDEX_WORLD_Y], 
                             width, (width>>1) + (width>>2),
                             int(mines[index].xv)>>1, int(mines[index].yv)>>1);   


                 // kill the mine
                 mines[index].state=MINE_STATE_DEAD;

                 // start a new mine
                 Start_Mine();
             
                // process next mine
                continue;

                } // end if contact count

             } // end if
        else // no collision or other problem, so reset
            {
            mines[index].varsI[INDEX_MINE_CONTACT_COUNT] = 0;
            } // end else

		} // end if alive

	} // end for index

} // end Move_Mines

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

void Draw_Mines(void)
{
// this function draws all the mines

for (int index=0; index < MAX_MINES; index++)

⌨️ 快捷键说明

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