2
0

VectorForceObjectSteering.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. //
  2. // Looking through a book trying to understand code.
  3. // This, points on the map that repulse a unit traveling to a target.
  4. //
  5. #define MAX_UNIT 64
  6. #define MAX_VFO 64
  7. #include "raylib.h"
  8. #include <math.h>
  9. typedef struct unit{
  10. bool active;
  11. int width;
  12. int height;
  13. float mx;
  14. float my;
  15. Vector2 target;
  16. Vector2 position;
  17. }unit;
  18. typedef struct vfo{
  19. bool active;
  20. Vector2 position;
  21. }vfo;
  22. static unit arr_unit[MAX_UNIT];
  23. static vfo arr_vfo[MAX_VFO];
  24. static void drawunits();
  25. static void drawvfo();
  26. static float getangle(float x1,float y1,float x2,float y2);
  27. static float distance(float x1,float y1,float x2,float y2);
  28. int main(void)
  29. {
  30. // Initialization
  31. //--------------------------------------------------------------------------------------
  32. const int screenWidth = 800;
  33. const int screenHeight = 450;
  34. InitWindow(screenWidth, screenHeight, "raylib example.");
  35. arr_unit[0].active = true;
  36. arr_unit[0].position = (Vector2){500,200};
  37. arr_unit[0].width = 16;
  38. arr_unit[0].height = 16;
  39. arr_unit[0].target = (Vector2){10*16,12*16};
  40. for(int i=0;i<15;i++){
  41. arr_vfo[i].active = true;
  42. arr_vfo[i].position = (Vector2){GetRandomValue(50,screenWidth-50),GetRandomValue(50,screenHeight-50)};
  43. }
  44. SetTargetFPS(60); // Set our game to run at 60 frames-per-second
  45. //--------------------------------------------------------------------------------------
  46. // Main game loop
  47. while (!WindowShouldClose()) // Detect window close button or ESC key
  48. {
  49. // Update
  50. //----------------------------------------------------------------------------------
  51. arr_unit[0].mx = 0;
  52. arr_unit[0].my = 0;
  53. float an = getangle(arr_unit[0].position.x,arr_unit[0].position.y,arr_unit[0].target.x,arr_unit[0].target.y);
  54. arr_unit[0].mx += cos(an)*1.2;
  55. arr_unit[0].my += sin(an)*1.2;
  56. int numvfo = 0;
  57. float mx=0;
  58. float my=0;
  59. for(int i=0;i<MAX_VFO;i++){
  60. float d = distance(arr_unit[0].position.x,arr_unit[0].position.y,arr_vfo[i].position.x,arr_vfo[i].position.y);
  61. if(d>64)continue; //preferable distance to keep from the vfo's
  62. numvfo++;
  63. float an = getangle(arr_unit[0].position.x,arr_unit[0].position.y,arr_vfo[i].position.x,arr_vfo[i].position.y);
  64. mx -= (float)cos(an);
  65. my -= (float)sin(an);
  66. if(d<32){//if closer than this stear away extra
  67. mx -= (float)cos(an);
  68. my -= (float)sin(an);
  69. numvfo+=1;
  70. }
  71. }
  72. if(numvfo>0){
  73. arr_unit[0].mx += mx/(numvfo);
  74. arr_unit[0].my += my/(numvfo);
  75. }
  76. if(distance(arr_unit[0].position.x,arr_unit[0].position.y,arr_unit[0].target.x,arr_unit[0].target.y)>16){
  77. //
  78. // Keep the movement speed between -1.0f and 1.0f
  79. // We get the angle using atan2 and then recreate the mx and my using cos and sin
  80. // this puts the speed back between -1 and 1.
  81. float an=atan2(arr_unit[0].my,arr_unit[0].mx);
  82. arr_unit[0].mx = cos(an);
  83. arr_unit[0].my = sin(an);
  84. // move our unit
  85. arr_unit[0].position.x += arr_unit[0].mx;
  86. arr_unit[0].position.y += arr_unit[0].my;
  87. }else{// Here we have arived and now we create another target and new vfo's
  88. arr_unit[0].target = (Vector2){GetRandomValue(50,screenWidth-50),GetRandomValue(50,screenHeight-50)};
  89. for(int i=0;i<MAX_VFO;i++){
  90. if(arr_vfo[i].active){
  91. arr_vfo[i].position = (Vector2){GetRandomValue(50,screenWidth-50),GetRandomValue(50,screenHeight-50)};
  92. }
  93. }
  94. }
  95. //----------------------------------------------------------------------------------
  96. // Draw
  97. //----------------------------------------------------------------------------------
  98. BeginDrawing();
  99. ClearBackground(RAYWHITE);
  100. drawvfo();
  101. drawunits();
  102. DrawRectangle(10,screenHeight-40,screenWidth-20,30,(Color){100,100,100,100});
  103. DrawCircle(64,screenHeight-34+8,8,RED);
  104. DrawCircleLines(64,screenHeight-34+8,8,BLACK);
  105. DrawText("- Vector Force Object.",80,screenHeight-34,20,BLACK);
  106. DrawRectangle(400,screenHeight-34,arr_unit[0].width,arr_unit[0].height,YELLOW);
  107. DrawRectangleLines(400,screenHeight-34,arr_unit[0].width,arr_unit[0].height,BLACK);
  108. DrawText("- CPU Player.",440,screenHeight-34,20,BLACK);
  109. DrawText("Press Escape to End.",0,0,15,DARKGRAY);
  110. EndDrawing();
  111. //----------------------------------------------------------------------------------
  112. }
  113. // De-Initialization
  114. //--------------------------------------------------------------------------------------
  115. CloseWindow(); // Close window and OpenGL context
  116. //--------------------------------------------------------------------------------------
  117. return 0;
  118. }
  119. void drawunits(){
  120. for(int i=0;i<MAX_UNIT;i++){
  121. if(arr_unit[i].active==false)continue;
  122. int w = arr_unit[i].width;
  123. int h = arr_unit[i].height;
  124. DrawRectangle(arr_unit[i].position.x-w/2,arr_unit[i].position.y-h/2,arr_unit[i].width,arr_unit[i].height,YELLOW);
  125. DrawRectangleLines(arr_unit[i].position.x-w/2,arr_unit[i].position.y-h/2,arr_unit[i].width,arr_unit[i].height,BLACK);
  126. // target
  127. DrawCircle(arr_unit[i].target.x,arr_unit[i].target.y,8,DARKGRAY);
  128. DrawText("Target",arr_unit[i].target.x,arr_unit[i].target.y,10,BLACK);
  129. }
  130. }
  131. void drawvfo(){
  132. for(int i=0;i<MAX_VFO;i++){
  133. if(arr_vfo[i].active==false)continue;
  134. DrawCircle(arr_vfo[i].position.x,arr_vfo[i].position.y,8,RED);
  135. DrawCircleLines(arr_vfo[i].position.x,arr_vfo[i].position.y,8,BLACK);
  136. }
  137. }
  138. //' Return the angle from - to in float
  139. float getangle(float x1,float y1,float x2,float y2){
  140. return (float)atan2(y2-y1, x2-x1);
  141. }
  142. // Manhattan Distance (less precise)
  143. float distance(float x1,float y1,float x2,float y2){
  144. return (float)abs(x2-x1)+abs(y2-y1);
  145. }