Advertisement
Guest User

zombie.cc

a guest
Jun 29th, 2012
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.62 KB | None | 0 0
  1. #include <math.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <SDL/SDL.h>
  5. #include <stdio.h>
  6.  
  7. double rad = 10;
  8. double PI = 3.1415926535;
  9.  
  10. SDL_Surface *screen;
  11.  
  12. enum types
  13. {
  14.     human = 0,
  15.     zombie = 1
  16. };
  17.  
  18. class alive
  19. {
  20. protected:
  21.     double tx, ty, tvx, tvy, tview; //временные величины
  22.     double fx, fy; 
  23. public:
  24.     Uint8 color;
  25.     double rad;
  26.     types type;
  27.     double x, y;
  28.     double vx, vy;
  29.     double view;
  30.  
  31.     double tired;
  32.    
  33.    
  34.     double max_tired;
  35.  
  36.     double max_vel;
  37.  
  38.     void ready(double dt); 
  39.    
  40.     virtual void react(alive &obj) = 0;
  41.     void walls(double nx, double ny);
  42.     void go(double dt);
  43. };
  44.  
  45. void alive::go(double dt)
  46. {
  47.     if (max_tired < 0)
  48.         tired = 0;
  49.    
  50.     double k = 1;
  51.     if (max_tired > 0)
  52.         k = 1-(tired / max_tired)*(tired / max_tired);
  53.     if (k >= 0)
  54.     {
  55.         tvx = fx*k;
  56.         tvy = fy*k;
  57.     }
  58.     else
  59.     {  
  60.         tired = 0;
  61.         tvx = 0;
  62.         tvy = 0;
  63.     }
  64.  
  65.     double vel = sqrt(tvx*tvx + tvy*tvy);
  66.     if (vel > max_vel)
  67.     {
  68.         tvx *= max_vel/vel;
  69.         tvy *= max_vel/vel;
  70.         tired += dt*max_vel;
  71.     }
  72.     else
  73.         tired += dt*(vel+0.1);
  74.    
  75.    
  76.  
  77. }
  78.  
  79. void alive::ready(double dt)
  80. {
  81.     x = x + tvx*dt;
  82.     y = y + tvy*dt;
  83.     vx = tvx;
  84.     vy = tvy;
  85.     view = tview;
  86.     tvx = 0;
  87.     tvy = 0;
  88.     fx = 0;
  89.     fy = 0;
  90. }
  91.  
  92.  
  93. void alive::walls(double nx, double ny) // взаимодействие со стенами
  94. {
  95.     double nr = sqrt(nx*nx+ny*ny);
  96.     nx /= nr;
  97.     ny /= nr;
  98.     double pr = nx*tvx + ny*tvy;
  99.     if (pr < 0) // смотрим в стену
  100.     {
  101.         double vel = sqrt(tvx*tvx + tvy*tvy);
  102.         tvx += -pr*nx*1.1;
  103.         tvy += -pr*ny*1.1;
  104. //      x += 3*nx;
  105. //      y += 3*ny;
  106.         double nvel=sqrt(tvx*tvx + tvy*tvy);
  107.         if (nvel > 1e-6)
  108.         {
  109.             tvx *= vel/nvel;
  110.             tvy *= vel/nvel;   
  111.         }
  112.     }
  113.  
  114. }
  115.  
  116.  
  117.  
  118. class a_human:public alive
  119. {
  120.     public:
  121.         int zombify;
  122.         void react(alive &obj);
  123.         a_human();
  124.        
  125. };
  126.  
  127.  
  128. a_human::a_human()
  129. {
  130.     zombify = 0;
  131.     type = human;
  132.     tired = 0;
  133.     max_tired = 10;
  134.     max_vel = 1;
  135.         color = SDL_MapRGB( screen->format, 0, 255, 0 );
  136.     rad = 0.5;
  137. }
  138.  
  139. void a_human::react(alive &obj)
  140. {  
  141.     double dx = x-obj.x;
  142.     double dy = y-obj.y;
  143.     double l = sqrt(dx*dx+dy*dy);
  144.            
  145.     switch(obj.type)
  146.     {
  147.         case human:
  148.             if (l > 1e-6 && l < rad + obj.rad)  // взаимодействие
  149.             {
  150.                 double dfx = (dx/l)/(l*l);  //отталкивание
  151.                 double dfy = (dy/l)/(l*l);
  152.                
  153.                 fx += dfx;
  154.                 fy += dfy;
  155.             }
  156.             break;
  157.         case zombie:
  158.             if (l < rad + obj.rad)  // упс, покусали
  159.             {
  160.                 zombify = 1;
  161.                 printf("Зомбификация!\n");
  162.             }
  163.             else            // убегаем
  164.             {
  165.                 double dfx = (dx/l);      //отталкивание
  166.                                 double dfy = (dy/l);
  167.  
  168.                                 fx += dfx;
  169.                                 fy += dfy;
  170.             }
  171.             break;
  172.     }
  173. }
  174.  
  175. class a_zombie : public alive
  176. {
  177.     public:
  178.         void react(alive &obj);
  179.         a_zombie();
  180. };
  181.  
  182.  
  183. a_zombie::a_zombie()
  184. {
  185.     max_tired = -1;
  186.     type = zombie;
  187.     max_vel = 0.7;
  188.         color = SDL_MapRGB( screen->format, 255, 0, 0 );
  189.     rad = 0.5;
  190. }
  191.  
  192.  
  193. void a_zombie::react(alive &obj)
  194. {  
  195.     double dx = x-obj.x;
  196.     double dy = y-obj.y;
  197.     double l = sqrt(dx*dx+dy*dy);
  198.            
  199.     switch(obj.type)
  200.     {
  201.         case zombie:
  202.             if (l > 1e-6 && l < rad + obj.rad)  // взаимодействие
  203.             {
  204.                 double dfx = (dx/l)/(l*l);  //отталкивание
  205.                 double dfy = (dy/l)/(l*l);
  206.                
  207.                 fx += dfx;
  208.                 fy += dfy;
  209.             }
  210.             break;
  211.         case human:
  212.             double dfx = -(dx/l)/(l);      // в погоню!
  213.                         double dfy = -(dy/l)/(l);
  214.  
  215.                         fx += dfx;
  216.                         fy += dfy;
  217.            
  218.             break;
  219.     }
  220. }
  221.  
  222.  
  223. typedef alive* palive;
  224.  
  225. palive *mass;
  226. int n = 30;
  227.  
  228. Uint8 colour_h, colour_z;
  229.  
  230. void init()
  231. {
  232.     int i;
  233.     mass = new palive[n];
  234.     mass[0] = new a_zombie;
  235.     for (i = 1; i < n; i++)
  236.         mass[i] = new a_human;
  237.    
  238.     for (i = 0; i < n; i++)
  239.     {
  240.         double r, an;
  241.        
  242.         r = rand()/((double)RAND_MAX)*rad;
  243.         an = rand()/((double)RAND_MAX)*2*PI;
  244.         mass[i]->x = r*cos(an);
  245.         mass[i]->y = r*sin(an);
  246.     }
  247. }
  248.  
  249. void deinit()
  250. {
  251.     int i;
  252.     for (i = 0; i < n; i++)
  253.         delete mass[i];
  254.     delete mass;
  255. }
  256.  
  257. void step(double dt)
  258. {
  259.     int i, j;
  260.    
  261.     for (i = 0; i < n; i++)
  262.     {
  263.         for (j = 0; j < n; j++)
  264.         {
  265.             if (i == j)
  266.                 continue;
  267.             mass[i]->react(*(mass[j]));
  268.         }
  269.     }
  270.     for (i = 0; i < n; i++)
  271.     {
  272.         mass[i]->go(dt);
  273.        
  274.         double x, y;
  275.         x = mass[i]->x;
  276.         y = mass[i]->y;
  277.         if (x*x + y*y > rad*rad)
  278.         {
  279.             mass[i]->walls(-x, -y);
  280.         }
  281.         mass[i]->ready(dt);
  282.     }
  283.  
  284.     for (i = 0; i < n; i++)
  285.     {
  286.         if (mass[i]->type == human && ((a_human*)mass[i])->zombify == 1)
  287.         {
  288.             double x, y, view;
  289.             x = mass[i]->x;
  290.             y = mass[i]->y;
  291.             view = mass[i]->view;
  292.             delete mass[i];
  293.             mass[i] = new a_zombie();
  294.             mass[i]->x = x;
  295.             mass[i]->y = y;
  296.             mass[i]->view = view;
  297.         }
  298.     }
  299. }
  300.  
  301.  
  302.  
  303. void draw_pixel(int X, int Y, Uint8 color, SDL_Surface *screen)
  304. {
  305.         Uint8 *pixmem;
  306.         if (X < 10)
  307.                 X = 10;
  308.         if (Y < 10)
  309.                 Y = 10;
  310.         if (X >= 890)
  311.                 X = 889;
  312.         if (Y >= 890)
  313.                 Y = 889;
  314.  
  315.         pixmem = (Uint8 *)screen->pixels + Y * screen->pitch + X * screen->format->BytesPerPixel;
  316.         *pixmem = color;
  317. }
  318.  
  319. void draw_per(int i, SDL_Surface *screen)
  320. {
  321.         Uint8 color = mass[i]->color;
  322.         int X, Y;
  323.         double x, y;
  324.  
  325.         X = mass[i]->x/(rad)*400 + 450;
  326.         Y = mass[i]->y/(rad)*400 + 450;
  327.  
  328.         draw_pixel(X-1, Y-1, color, screen);
  329.         draw_pixel(X-1, Y, color, screen);
  330.         draw_pixel(X-1, Y+1, color, screen);
  331.         draw_pixel(X, Y-1, color, screen);
  332.         draw_pixel(X, Y, color, screen);
  333.         draw_pixel(X, Y+1, color, screen);
  334.         draw_pixel(X+1, Y-1, color, screen);
  335.         draw_pixel(X+1, Y, color, screen);
  336.         draw_pixel(X+1, Y+1, color, screen);
  337.  
  338.         int dx = 8*cos(mass[i]->view);
  339.         int dy = 8*sin(mass[i]->view);
  340.         draw_pixel(X+dx, Y+dy, color, screen);
  341. }
  342.  
  343.  
  344.  
  345.  
  346. void draw_wall()
  347. {
  348.         double an;
  349.         for (an = 0; an < 2*PI; an+=0.001)
  350.         {
  351.                 double x = (rad+0.2)*cos(an);
  352.                 double y = (rad+0.2)*sin(an);
  353.                 int X = x/(rad)*400 + 450;
  354.                 int Y = y/(rad)*400 + 450;
  355.                 Uint8 color_wall = SDL_MapRGB( screen->format, 255, 255, 0 );
  356.                 draw_pixel(X, Y, color_wall, screen);
  357.         }
  358. }
  359.  
  360.  
  361. int main()
  362. {
  363.         SDL_Event event;
  364.  
  365.     SDL_Init(SDL_INIT_VIDEO);
  366.         screen = SDL_SetVideoMode(900, 900,8,SDL_HWSURFACE|SDL_DOUBLEBUF);
  367.  
  368. //  srand(time(NULL)); 
  369.    
  370.     init();
  371.    
  372.     int keypress = 0;
  373.    
  374.     double dt = 0.1;
  375.     while(!keypress)
  376.         {  
  377.         int i;
  378.         SDL_FillRect(screen, NULL, 0x000000);
  379.         step(dt);
  380.         draw_wall();       
  381.        
  382.                 for (i = 0; i < n; i++)
  383.                 {
  384.                         draw_per(i, screen);
  385.         }
  386.        
  387.         SDL_Flip(screen);
  388.                 while(SDL_PollEvent(&event))
  389.                 {
  390.                         switch (event.type)
  391.                         {
  392.                                 case SDL_QUIT:
  393.                                         keypress = 1;
  394.                                         break;
  395.                                 case SDL_KEYDOWN:
  396.                                         keypress = 1;
  397.                                         break;
  398.                         }
  399.                 }
  400.  
  401.     }
  402.     deinit();
  403.     SDL_Quit();
  404.     return 0;
  405. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement