positiontogridpositions.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. //
  2. // Line of sight or raycasting.
  3. // The method I used is by taking an area around the player. In this area each tile is indexed. Than
  4. // a invisible bullet is shot from the player position into the direction of this tile. The area underneath
  5. // this invisible bullet is marked as visible area. If the bullet hits a wall then the line of sight stops.
  6. // I think this method will make sure that every tile is handled!
  7. //
  8. #include "raylib.h"
  9. #include <math.h>
  10. typedef struct player{
  11. Vector2 position;
  12. }player;
  13. float tilewidth;
  14. float tileheight;
  15. // This is out collision map.
  16. bool colmap[10][20] = {false};
  17. bool losmap[10][20] = {false};
  18. // This is our tile map.
  19. int map[10][20] = { {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
  20. {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,1,1,1},
  21. {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1},
  22. {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,1,1,1},
  23. {1,1,1,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,1,1},
  24. {1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1},
  25. {1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1},
  26. {1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1},
  27. {1,0,0,0,0,0,0,1,0,0,0,1,1,1,1,0,0,0,0,1},
  28. {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};
  29. // Our player setup
  30. player myplayer = {0};
  31. static void makelos(void);
  32. static float getangle(float x1,float y1,float x2,float y2);
  33. int main(void)
  34. {
  35. // Initialization
  36. //--------------------------------------------------------------------------------------
  37. const int screenWidth = 800;
  38. const int screenHeight = 450;
  39. InitWindow(screenWidth, screenHeight, "raylib LOS example.");
  40. myplayer.position = (Vector2){5,5};
  41. // Our tile width and height. We use the screen dimension and the map dimension to
  42. // get tile dimensions that fill up the entire screen.
  43. tilewidth = (float)screenWidth/20.0f;
  44. tileheight = (float)screenHeight/10.0f;
  45. // Copy the contents of the map into the collision map.
  46. for(int y=0;y<10;y++){
  47. for(int x=0;x<20;x++){
  48. if(map[y][x]>0)colmap[y][x]=true;
  49. }
  50. }
  51. SetTargetFPS(60); // Set our game to run at 60 frames-per-second
  52. //--------------------------------------------------------------------------------------
  53. // Main game loop
  54. while (!WindowShouldClose()) // Detect window close button or ESC key
  55. {
  56. // Update
  57. //----------------------------------------------------------------------------------
  58. // Below here we read the key. If the l/r/u/d cursor is pressed then we check the new position is inside
  59. // the array bounds and then we check if the collision map on the new position is not set to flag true on that tile.
  60. if(IsKeyPressed(KEY_RIGHT)&& myplayer.position.x+1<20 && colmap[(int)myplayer.position.y][(int)myplayer.position.x+1]==false) {
  61. myplayer.position.x+=1;
  62. makelos();
  63. }
  64. if(IsKeyPressed(KEY_LEFT) && myplayer.position.x-1>-1 && colmap[(int)myplayer.position.y][(int)myplayer.position.x-1]==false) {
  65. myplayer.position.x-=1;
  66. makelos();
  67. }
  68. if(IsKeyPressed(KEY_UP)&& myplayer.position.y-1>-1 && colmap[(int)myplayer.position.y-1][(int)myplayer.position.x]==false) {
  69. myplayer.position.y-=1;
  70. makelos();
  71. }
  72. if(IsKeyPressed(KEY_DOWN) && myplayer.position.y+1<20 && colmap[(int)myplayer.position.y+1][(int)myplayer.position.x]==false) {
  73. myplayer.position.y+=1;
  74. makelos();
  75. }
  76. //----------------------------------------------------------------------------------
  77. // Draw
  78. //----------------------------------------------------------------------------------
  79. BeginDrawing();
  80. ClearBackground(RAYWHITE);
  81. // Draw our tilemap.
  82. for(int y=0;y<10;y++){
  83. for(int x=0;x<20;x++){
  84. if(map[y][x]==1){
  85. DrawRectangle(x*tilewidth,y*tileheight,tilewidth,tileheight,BLACK);
  86. }
  87. if(map[y][x]==2){
  88. DrawRectangle(x*tilewidth,y*tileheight,tilewidth,tileheight,YELLOW);
  89. }
  90. if(map[y][x]==3){
  91. DrawRectangle(x*tilewidth,y*tileheight,tilewidth,tileheight,BLUE);
  92. }
  93. }
  94. }
  95. // Draw our player
  96. DrawRectangle(myplayer.position.x*tilewidth,myplayer.position.y*tileheight,tilewidth,tileheight,RED);
  97. DrawText("Use Cursor Keys to move around..",0,0,20,WHITE);
  98. EndDrawing();
  99. //----------------------------------------------------------------------------------
  100. }
  101. // De-Initialization
  102. //--------------------------------------------------------------------------------------
  103. CloseWindow(); // Close window and OpenGL context
  104. //--------------------------------------------------------------------------------------
  105. return 0;
  106. }
  107. void makelos(){
  108. for(int y=0;y<10;y++){ // erase the map lighted tiles
  109. for(int x=0;x<20;x++){
  110. if(map[y][x]!=1)map[y][x]=0;
  111. }}
  112. float x1 = myplayer.position.y; // x1 and y1 is the tile position of the player
  113. float y1 = myplayer.position.x;
  114. for(int y=y1-8;y<y1+8;y++){ // x and y is the area we check for line of sight
  115. for(int x=x1-8;x<x1+8;x++){
  116. float x4 = x1*tilewidth+tilewidth/2; // x4 and y4 is the screen position of the player
  117. float y4 = y1*tileheight+tileheight/2;
  118. float x2=(float)x*tilewidth; // x2 and y2 is the screen position of the tiles in the area around the player
  119. float y2=(float)y*tileheight;
  120. float angle = getangle(x2,y2,x4,y4); //get the angle from the player screen position and the tile screen position.
  121. bool donot=false; // donot is a variable that is true! if the ray has hit a wall/obstacle
  122. for(int z=0;z<200;z++){ // our ray distance traveled (set shorter for circular lighted area!)
  123. x4+=cos(angle)*1; // x4 and y4 are the rays position(inc!)
  124. y4+=sin(angle)*1;
  125. int x3 = x4/tilewidth; // x3 and y3 is the tile position under the ray
  126. int y3 = y4/tileheight;
  127. if(x3!=x1 || y3!=y1){ // If the ray is not on the starting tile
  128. if(x3>-1 && y3>-1){ // if we are inside the map bounds
  129. if(x3<10 && y3<20){ // ,,
  130. if(map[x3][y3]==1)donot=true; // If the ray hits a wall/obstacle
  131. if(donot==false){ // if we have not hit a obstacle/wall
  132. map[x3][y3]=GetRandomValue(2,3); // set the ground to a color(lighted area)
  133. }
  134. }}
  135. }
  136. }
  137. }}
  138. };
  139. // Return the angle from - to in float
  140. float getangle(float x1,float y1,float x2,float y2){
  141. return (float)atan2(y2-y1, x2-x1);
  142. }