2
0

Swarm01.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. Particle Swarm
  3. Note : I'm not sure, but there is something wrong with the random. I have to do a -1.7 .. 1 for the
  4. swarm to stay in one spot. Not sure what I did wrong to cause that. ????
  5. Update: I added a float_rand function from the internet and this seemed to have fixed the problem.
  6. Optimalization : create a array[y][x][MAX_PARTICLES] of struct which contain
  7. the particles on that location.
  8. */
  9. #include "raylib.h"
  10. #include <math.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #define MAX_PARTICLES 240
  14. // This is out collision map. It is a array for each spot a particle can be on.
  15. // It is true if there is a particle there or false if not.
  16. // Before moving a particle we can check if there is a particle there already so
  17. // not to move there.
  18. //
  19. // We need to check this map every time a particle gets moved (uncheck move check)
  20. //
  21. // Functions : setcollisionmap and checkcollisionmap
  22. bool collisionmap[1024][1024]={false};
  23. typedef struct particle{
  24. Vector2 position;
  25. }particle;
  26. struct particle arr_particle[MAX_PARTICLES];
  27. static float edistance(float x1,float y1,float x2,float y2);
  28. void setcollisionmap(Vector2 position,bool value);
  29. bool checkcollisionmap(Vector2 position);
  30. float float_rand( float min, float max );
  31. int main(void)
  32. {
  33. // Initialization
  34. //--------------------------------------------------------------------------------------
  35. const int screenWidth = 800;
  36. const int screenHeight = 450;
  37. InitWindow(screenWidth, screenHeight, "raylib example.");
  38. SetTargetFPS(120); // Set our game to run at 60 frames-per-second
  39. //--------------------------------------------------------------------------------------
  40. //create a set of particles
  41. Vector2 p = (Vector2){200,200};
  42. for(int i=0;i<MAX_PARTICLES;i++){
  43. Vector2 pos=(Vector2){GetRandomValue(p.x-35,p.x+35),GetRandomValue(p.y-35,p.y+35)};
  44. while(checkcollisionmap(pos)==true){
  45. pos=(Vector2){GetRandomValue(p.x-35,p.x+35),GetRandomValue(p.y-35,p.y+35)};
  46. }
  47. arr_particle[i].position = pos;
  48. setcollisionmap(arr_particle[i].position,true);
  49. }
  50. int here=0;
  51. // Main game loop
  52. while (!WindowShouldClose()) // Detect window close button or ESC key
  53. {
  54. // Update
  55. //----------------------------------------------------------------------------------
  56. //update particles
  57. //move random
  58. for(int i=0;i<MAX_PARTICLES;i++){
  59. Vector2 np = arr_particle[i].position;
  60. //np.x+=floatuniform(-1.72,1);
  61. //np.y+=floatuniform(-1.72,1);
  62. np.x += float_rand(-1,1);
  63. np.y += float_rand(-1,1);
  64. if(checkcollisionmap(np)==false){
  65. setcollisionmap(arr_particle[i].position,false);
  66. arr_particle[i].position=np;
  67. setcollisionmap(arr_particle[i].position,true);
  68. }
  69. }
  70. //move to midpoint nearest
  71. for(int i=0;i<MAX_PARTICLES;i++){
  72. // find neigbours (3 of them)
  73. Vector2 p1 = arr_particle[i].position;
  74. int d1=0;
  75. int cnt=0;
  76. int timeout=0;
  77. Vector2 midpoint = (Vector2){0,0};
  78. while(cnt<5 && timeout<1000){
  79. for(int j=0;j<MAX_PARTICLES;j++){
  80. if(j==i || cnt>4)continue;
  81. Vector2 p2 = arr_particle[j].position;
  82. int d2 = (int)edistance(p1.x,p1.y,p2.x,p2.y);
  83. if(d2==d1 && cnt<5){
  84. if(cnt==0){
  85. midpoint.x = p2.x;
  86. midpoint.y = p2.y;
  87. }else{
  88. midpoint.x += p2.x;
  89. midpoint.y += p2.y;
  90. }
  91. cnt++;
  92. }
  93. }
  94. d1++;
  95. timeout++;
  96. }
  97. midpoint.x /= 5.0f;
  98. midpoint.y /= 5.0f;
  99. float angle=atan2(midpoint.y-p1.y,midpoint.x-p1.x);
  100. Vector2 newposition = (Vector2){ arr_particle[i].position.x + cos(angle)*.3,
  101. arr_particle[i].position.y + sin(angle)*.3};
  102. if( checkcollisionmap(newposition)==false ){
  103. setcollisionmap(arr_particle[i].position,false);
  104. arr_particle[i].position.x += cos(angle)*.3;
  105. arr_particle[i].position.y += sin(angle)*.3;
  106. setcollisionmap(newposition,true);
  107. }
  108. }
  109. //----------------------------------------------------------------------------------
  110. // Draw
  111. //----------------------------------------------------------------------------------
  112. BeginDrawing();
  113. ClearBackground(RAYWHITE);
  114. // Draw particles
  115. for(int i=0;i<MAX_PARTICLES;i++){
  116. Vector2 p = arr_particle[i].position;
  117. DrawCircle(p.x,p.y,2,RED);
  118. }
  119. DrawText(FormatText("%i",here),0,0,20,BLACK);
  120. EndDrawing();
  121. //----------------------------------------------------------------------------------
  122. }
  123. // De-Initialization
  124. //--------------------------------------------------------------------------------------
  125. CloseWindow(); // Close window and OpenGL context
  126. //--------------------------------------------------------------------------------------
  127. return 0;
  128. }
  129. // Euclidean distance (more precise)
  130. float edistance(float x1,float y1,float x2,float y2){
  131. return sqrt( (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2) );
  132. }
  133. void setcollisionmap(Vector2 position,bool value){
  134. if(position.x<0)return;
  135. if(position.x>1023)return;
  136. if(position.y<0)return;
  137. if(position.y>1023)return;
  138. collisionmap[(int)position.x][(int)position.y]=value;;
  139. }
  140. bool checkcollisionmap(Vector2 position){
  141. if(position.x<0)return true;
  142. if(position.x>1023)return true;
  143. if(position.y<0)return true;
  144. if(position.y>1023)return true;
  145. return (collisionmap[(int)position.x][(int)position.y]);
  146. }
  147. float float_rand( float min, float max ){
  148. float scale = rand() / (float) RAND_MAX; /* [0, 1.0] */
  149. return min + scale * ( max - min ); /* [min, max] */
  150. }