📄 demo13_10.cpp
字号:
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 + -