home *** CD-ROM | disk | FTP | other *** search
/ Game Programming - All in One (3rd Edition) / game_prog_all_in_one_3rd_ed.iso / sources / StarBuilder / main.c next >
Encoding:
C/C++ Source or Header  |  2006-09-09  |  4.8 KB  |  232 lines

  1. /////////////////////////////////////////////////////////////////////////
  2. // Game Programming All In One, Third Edition
  3. // Particles Program
  4. /////////////////////////////////////////////////////////////////////////
  5.  
  6. #include "math.h"
  7. #include "allegro.h"
  8.  
  9. #define NUM 4000
  10. #define STARTING_MASS 0.00001
  11.  
  12. #define GRAY makecol(30,30,30)
  13. #define RED makecol(150,0,0)
  14.  
  15. //particle structure
  16. struct particle
  17. {
  18.     int alive;
  19.     double mass;
  20.     double x, y;
  21.     long oldX, oldY;
  22.     long xp;
  23.     long yp;
  24.     double ax;
  25.     double ay;
  26.     double vx;
  27.     double vy;
  28.  
  29. }p[NUM];
  30.  
  31. int CX, CY;
  32. int living=0;
  33. int biggest=0;
  34.  
  35. void resetparticle(int n);
  36. void updateparticles();
  37. void resetall();
  38.  
  39.  
  40. void attract(struct particle *A, struct particle *B)
  41. {
  42.     double distance;
  43.     double dist, distX, distY;
  44.     double transX, transY;
  45.  
  46.     //increase position by velocity value
  47.     A->x += A->vx;
  48.     A->y += A->vy;
  49.     
  50.     //calculate distance between particles
  51.     distX = A->x - B->x;
  52.     distY = A->y - B->y;
  53.     dist = distX * distX + distY * distY;
  54.     if (dist != 0)
  55.         distance = 1 / dist;
  56.     else
  57.         distance = 0;
  58.  
  59.     transX = distX * distance;
  60.     transY = distY * distance;
  61.     
  62.     //acceleration = mass * distance
  63.     A->ax = -1 * B->mass * transX;
  64.     A->ay = -1 * B->mass * transY;
  65.     
  66.     //increase velocity by acceleration value
  67.     A->vx += A->ax;
  68.     A->vy += A->ay;
  69.  
  70.     //scale position to the screen
  71.     A->xp = A->x;
  72.     A->yp = A->y;
  73.  
  74. }
  75.  
  76. void drawparticle(int n, int color)
  77. {
  78.     int rad=1;
  79.     float m=p[n].mass;
  80.  
  81.     if (m > STARTING_MASS * 10) {
  82.         rad++;
  83.         if (m > STARTING_MASS * 50) rad++;
  84.         if (m > STARTING_MASS * 100) rad++;
  85.         if (m > STARTING_MASS * 200) rad++;
  86.         if (m > STARTING_MASS * 400) rad++;
  87.         if (m > STARTING_MASS * 800) rad++;
  88.         circle(screen, p[n].xp, p[n].yp, rad, color);
  89.     }
  90.     else
  91.         putpixel(screen, p[n].xp, p[n].yp, color);
  92. }
  93.  
  94. int collided(int p1, int p2)
  95. {
  96.     return (p[p1].xp == p[p2].xp && p[p1].yp == p[p2].yp);
  97. }
  98.  
  99. void update()
  100. {
  101.     int n;
  102.     int i;
  103.     living=0;
  104.  
  105.     //calculate gravity for each particle
  106.     for (n = 0; n < NUM; n++)
  107.       if (p[n].alive)
  108.       {   
  109.         living++;
  110.         
  111.         //track the biggest object
  112.         if (p[n].mass > p[biggest].mass)
  113.             biggest = n;
  114.  
  115.         //erase old particle
  116.         drawparticle(n, GRAY);
  117.  
  118.         //apply gravity from every particle to every other particle
  119.         for (i = 0; i < NUM; i++)
  120.           if (p[i].alive)
  121.           {
  122.             if (i != n)
  123.             {
  124.                 attract(&p[n], &p[i]);
  125.                 if (collided(n,i))
  126.                 {
  127.                     //collision: larger object absorbs smaller one
  128.                     if (p[n].mass >= p[i].mass)
  129.                     {
  130.                         p[n].mass += p[i].mass;
  131.                         p[i].alive = 0;
  132.                         drawparticle(i, RED);
  133.                     }
  134.                     else
  135.                     {
  136.                         p[i].mass += p[n].mass;
  137.                         p[n].alive = 0;
  138.                         drawparticle(n, RED);
  139.                     }
  140.  
  141.                 }
  142.             }
  143.           }
  144.  
  145.         //plot the particle
  146.         drawparticle(n, 7);
  147.  
  148.         //keep track of the current position
  149.         p[n].oldX = p[n].xp;
  150.         p[n].oldY = p[n].yp;
  151.       }
  152.  
  153. }
  154.  
  155.  
  156. void resetparticle(int n)
  157. {
  158.     p[n].alive = 1;
  159.     p[n].mass = STARTING_MASS;
  160.     p[n].ax = 0;
  161.     p[n].ay = 0;
  162.     p[n].xp = 0;
  163.     p[n].yp = 0;
  164.     p[n].x = rand() % SCREEN_W;
  165.     p[n].y = rand() % SCREEN_H;
  166.     p[n].vx = 0;
  167.     p[n].vy = 0;
  168. }
  169.  
  170.  
  171. void resetall()
  172. {
  173.     int n;
  174.  
  175.     for (n = 0; n < NUM; n++)
  176.         resetparticle(n);
  177.  
  178. }
  179.  
  180. void main(void)
  181. {
  182.     int done=0;
  183.     int start=0;
  184.     int counter;
  185.  
  186.     //initialize some stuff
  187.     allegro_init(); 
  188.     install_keyboard(); 
  189.     install_timer();
  190.     srand(time(NULL));
  191.  
  192.     //initialize video mode
  193.     int ret = set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, 800, 600, 0, 0);
  194.     if (ret != 0) {
  195.         allegro_message(allegro_error);
  196.         return;
  197.     }
  198.  
  199.     //display screen resolution
  200.     textprintf_ex(screen, font, 0, 0, 15, 0,
  201.         "Star Builder  %dx%d  ESC to quit", 
  202.         SCREEN_W, SCREEN_H);
  203.  
  204.     resetall();
  205.  
  206.     while(!done)
  207.     {
  208.         
  209.         //slow down the simulation
  210.         if (clock() > start + 1) {
  211.             start = clock();
  212.  
  213.             update();
  214.             textprintf_ex(screen, font, 400, 0, 15, 0,
  215.                 "Count:%4d - Biggest:%4d (mass=%1.6f)", 
  216.                 living, biggest, p[biggest].mass);
  217.         }
  218.  
  219.  
  220.         if (keypressed())  {
  221.             if (key[KEY_ESC])
  222.                 done++;
  223.         }
  224.     }
  225.  
  226.     //end program
  227.     allegro_exit();
  228. }
  229.  
  230. END_OF_MAIN();
  231.  
  232.