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

📄 demo13_10.cpp

📁 windows游戏编程大师源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
              particles[pindex].start_color = COLOR_GREEN_START;
              particles[pindex].end_color   = COLOR_GREEN_END;
              } break;

         case PARTICLE_COLOR_BLUE:
              {
              particles[pindex].start_color = COLOR_BLUE_START;
              particles[pindex].end_color   = COLOR_BLUE_END;
              } break;

         case PARTICLE_COLOR_WHITE:
              {
              particles[pindex].start_color = COLOR_WHITE_START;
              particles[pindex].end_color   = COLOR_WHITE_END;
              } break;

         break;

         } // end switch

// what type of particle is being requested
if (type == PARTICLE_TYPE_FLICKER)
   {
    // set current color
    particles[index].curr_color  = RAND_RANGE(particles[index].start_color, particles[index].end_color);

   } // end if
else
   {
   // particle is fade type
   // set current color
   particles[index].curr_color  = particles[index].start_color;
   } // end if

} // end Start_Particle

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

void Start_Particle_Explosion(int type, int color, int count, 
                              int x, int y, int xv, int yv, int num_particles)
{
// this function starts a particle explosion at the given position and velocity

while(--num_particles >=0)
    {
    // compute random trajectory angle
    int ang = rand()%360;

    // compute random trajectory velocity
    float vel = 2+rand()%4;

    Start_Particle(type,color,count,
                   x+RAND_RANGE(-4,4),y+RAND_RANGE(-4,4), 
                   xv+cos_look[ang]*vel, yv+sin_look[ang]*vel);        

    } // end while

} // end Start_Particle_Explosion

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

void Start_Particle_Ring(int type, int color, int count, 
                              int x, int y, int xv, int yv, int num_particles)
{
// this function starts a particle explosion at the given position and velocity
// note the use of look up tables for sin,cos

// compute random velocity on outside of loop
float vel = 2+rand()%4;

while(--num_particles >=0)
    {
    // compute random trajectory angle
    int ang = rand()%360;

    // start the particle
    Start_Particle(type,color,count,
                   x,y, 
                   xv+cos_look[ang]*vel, 
                   yv+sin_look[ang]*vel);        

    } // end while

} // end Start_Particle_Ring

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

void Draw_Particles(void)
{
// this function draws all the particles

// lock back surface
DDraw_Lock_Back_Surface();

for (int index=0; index<MAX_PARTICLES; index++)
    {
    // test if particle is alive
    if (particles[index].state==PARTICLE_STATE_ALIVE)
       {
       // render the particle, perform world to screen transform
       int x = particles[index].x;
       int y = particles[index].y;

       // test for clip
       if (x >= SCREEN_WIDTH || x < 0 || y >= SCREEN_HEIGHT || y < 0)
          continue;

       // draw the pixel
       Draw_Pixel(x,y,particles[index].curr_color, back_buffer, back_lpitch);
    
      } // end if

    } // end for index

// unlock the secondary surface
DDraw_Unlock_Back_Surface(); 

} // end Draw_Particles

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

void Process_Particles(void)
{
// this function moves and animates all particles

for (int index=0; index<MAX_PARTICLES; index++)
    {
    // test if this particle is alive
    if (particles[index].state == PARTICLE_STATE_ALIVE)
       {
       // translate particle
       particles[index].x+=particles[index].xv;
       particles[index].y+=particles[index].yv;

       // update velocity based on gravity and wind
       particles[index].xv+=particle_wind;
       particles[index].yv+=particle_gravity;

       // now based on type of particle perform proper animation
       if (particles[index].type==PARTICLE_TYPE_FLICKER)
          {
          // simply choose a color in the color range and assign it to the current color
          particles[index].curr_color = RAND_RANGE(particles[index].start_color, particles[index].end_color);

          // now update counter
          if (++particles[index].counter >= particles[index].max_count)
             {
             // kill the particle
             particles[index].state = PARTICLE_STATE_DEAD;             

             } // end if

          } // end if
      else
          {
          // must be a fade, be careful!
          // test if it's time to update color
          if (++particles[index].counter >= particles[index].max_count)
             {
              // reset counter
              particles[index].counter = 0;

             // update color
             if (++particles[index].curr_color>particles[index].end_color)
                {
                // transition is complete, terminate particle
                particles[index].state = PARTICLE_STATE_DEAD;  
 
                } // end if

             } // end if

          } // end else
             
       } // end if 

    } // end for index

} // end Process_Particles

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

void Cannon_Sound(void)
{        
// this functions hunts for an open handle to play a cannon sound

// start a hit sound
for (int sound_index=0; sound_index < 8; sound_index++)
    {
    // test if this sound is playing
    if (DSound_Status_Sound(cannon_ids[sound_index])==0)
       {
       DSound_Play(cannon_ids[sound_index]);
       break;
       } // end if

     } // end for 

} // end Cannon_Sound

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

void Explosion_Sound(void)
{        
// this functions hunts for an open handle to play a explosion sound

// start a hit sound
for (int sound_index=0; sound_index < 8; sound_index++)
    {
    // test if this sound is playing
    if (DSound_Status_Sound(explosion_ids[sound_index])==0)
       {
       DSound_Play(explosion_ids[sound_index]);
       break;
       } // end if

     } // end for 

} // end Explosion_Sound


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

void Init_Projectiles(void)
{
// this function initializes the projectiles
memset(missiles, 0, sizeof(PROJECTILE)*NUM_PROJECTILES);

} // end Init_Projectiles

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

void Move_Projectiles(void)
{
// this function moves all the projectiles and does the physics model
for (int index=0; index<NUM_PROJECTILES; index++)
    {
    if (missiles[index].state==1)
       {
        // translate
        missiles[index].x+=missiles[index].xv;
        missiles[index].y+=missiles[index].yv;

        // apply forces
        missiles[index].xv+=wind_force;
        missiles[index].yv+=gravity_force;

        // update detonatation counter
        if (--missiles[index].detonate <= 0)
           {
           // select a normal or ring

           if (RAND_RANGE(0,3) == 0)
           {
           // start a particle explosion
           Start_Particle_Ring(PARTICLE_TYPE_FADE, PARTICLE_COLOR_RED+rand()%4, RAND_RANGE(2,5),
                              missiles[index].x, missiles[index].y, 
                              0, 0,RAND_RANGE(75,100));
           } // end if
            else
            {
             Start_Particle_Explosion(PARTICLE_TYPE_FADE, PARTICLE_COLOR_RED+rand()%4, RAND_RANGE(2,5),
                              missiles[index].x, missiles[index].y, 
                              0, 0,RAND_RANGE(20,50));
             } // end if


           // make some noise
           Explosion_Sound();

           // kill the missile
           missiles[index].state = 0;

           } // end if

        // test for off screen
        else
        if (missiles[index].x >= screen_width || 
            missiles[index].y >=screen_height || 
            missiles[index].y < 0) 
           {
           // kill the missile
           missiles[index].state = 0;
           } // end if

        } // end if on
 
    } // end for index

} // end Move_Projectiles

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

void Draw_Projectiles(void)
{
// this function draws all the projectiles 
for (int index=0; index < NUM_PROJECTILES; index++)
    {
    // is this one alive?
    if (missiles[index].state==1)
       {
       Draw_Rectangle(missiles[index].x-1,missiles[index].y-1, 
                      missiles[index].x+1,missiles[index].y+1,
                      95, lpddsback);
       } // end if

    } // end for index

} // end Draw_Projectiles

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

void Fire_Projectile(int angle, float vel)
{
// this function starts a projectile with the given angle and velocity 
// at the tip of the cannon
for (int index=0; index < NUM_PROJECTILES; index++)
    {
    // find an open projectile
    if (missiles[index].state==0)
       {
       // set this missile in motion at the head of cannon with the proper angle
       missiles[index].x = cannon.vlist[1].x+cannon.x0;
       missiles[index].y = cannon.vlist[1].y+cannon.y0;

       // compute velocity vector based on angle
       missiles[index].xv = vel*cos_look[angle];
       missiles[index].yv = -vel*sin_look[angle];

       // set detonation time
       missiles[index].detonate = RAND_RANGE(30,40);
 
       // mark as active
       missiles[index].state = 1;

       // make sound
       Cannon_Sound();

       // bail
       break;

       } // end if

    } // end for index

} // end Fire_Projectile

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

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 you game go here!

int index; // looping var

static int   curr_angle = 0; // current angle of elevation from horizon
static float curr_vel   = 10; // current velocity of projectile

// start the timing clock
Start_Clock();

// clear the drawing surface
//DDraw_Fill_Surface(lpddsback, 0);

// lock back buffer and copy background into it
DDraw_Lock_Back_Surface();

// draw background
Draw_Bitmap(&background_bmp, back_buffer, back_lpitch,0);

// do the graphics
Draw_Polygon2D(&cannon, back_buffer, back_lpitch);

// unlock back surface
DDraw_Unlock_Back_Surface();

// read keyboard
DInput_Read_Keyboard();

// test for rotate
if ((curr_angle < 90) && keyboard_state[DIK_UP]) // rotate left
   {
   Rotate_Polygon2D_Mat(&cannon, -5);
   curr_angle+=5;
   } // end if
else
if ((curr_angle > 0) &&keyboard_state[DIK_DOWN]) // rotate right
   {
   Rotate_Polygon2D_Mat(&cannon, 5);
   curr_angle-=5;
   } // end if

// test for projectile velocity
if (keyboard_state[DIK_RIGHT])  
   { 
   if (curr_vel < 30) curr_vel+=0.1;
   } // end if
else
if (keyboard_state[DIK_LEFT]) 
   { 
   if (curr_vel > 0) curr_vel-=0.1;
   } // end if

// test for wind force
if (keyboard_state[DIK_W])  
   { 
   if (particle_wind < 2) particle_wind+=0.01;
   } // end if
else
if (keyboard_state[DIK_E]) 
   { 
   if (particle_wind > -2) particle_wind-=0.01;
   } // end if

// test for gravity force
if (keyboard_state[DIK_G])  
   { 
   if (particle_gravity < 5) particle_gravity+=0.01;
   } // end if
else
if (keyboard_state[DIK_B]) 
   { 
   if (particle_gravity > -5) particle_gravity-=0.01;
   } // end if

// test for fire!
if (keyboard_state[DIK_LCONTROL]) 
   { 
   Fire_Projectile(curr_angle, curr_vel);

   } // end fire

// move all the projectiles
Move_Projectiles();

// move particles
Process_Particles();

// draw the projectiles
Draw_Projectiles();

// draw the particles
Draw_Particles();

// draw the title
Draw_Text_GDI("Particle System DEMO, Press <ESC> to Exit.",10, 10,RGB(0,255,0), lpddsback);
Draw_Text_GDI("<RIGHT>, <LEFT> to adjust velocity, <UP>, <DOWN> to adjust angle",10, 25, RGB(255,255,255), lpddsback);
Draw_Text_GDI("<G>, <B> adjusts particle gravity, <W>, <E> adjusts particle wind, <CTRL> to fire.",10, 40, RGB(255,255,255), lpddsback);

sprintf(buffer, "Cannon: Ang=%d, Vel=%f", curr_angle, curr_vel);
Draw_Text_GDI(buffer,10, 60, RGB(255,255,255), lpddsback);

sprintf(buffer, "Particle: Wind force=%f, Gravity Force=%f", particle_wind, particle_gravity);
Draw_Text_GDI(buffer,10, 75, RGB(255,255,255), lpddsback);

// flip the surfaces
DDraw_Flip();

// sync to 30 fps = 1/30sec = 33 ms
Wait_Clock(33);

// check of user is trying to exit
if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE])
    {
    PostMessage(main_window_handle, WM_DESTROY,0,0);

    // stop all sounds
    DSound_Stop_All_Sounds();

    // do a screen transition
    Screen_Transitions(SCREEN_DARKNESS,NULL,0);
    } // end if

// return success
return(1);

} // end Game_Main

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

⌨️ 快捷键说明

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