Advertisement
imposerfromamongsus

Untitled

Dec 16th, 2021
153
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.50 KB | None | 0 0
  1. /*******************************************************************************************
  2. *
  3. * raylib [core] example - 2d camera platformer
  4. *
  5. * This example has been created using raylib 2.5 (www.raylib.com)
  6. * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
  7. *
  8. * Example contributed by arvyy (@arvyy) and reviewed by Ramon Santamaria (@raysan5)
  9. *
  10. * Copyright (c) 2019 arvyy (@arvyy)
  11. * ABOUTSALUTESECURE
  12. *
  13. ********************************************************************************************/
  14.  
  15. #include "raylib.h"
  16. #include "raymath.h"
  17. #include <stdio.h>
  18.  
  19. #define G 400
  20. #define PLAYER_JUMP_SPD 350.0f
  21. #define PLAYER_HOR_SPD 200.0f
  22.  
  23. typedef struct Player {
  24. Vector2 position;
  25. float downspeed;
  26. bool canJump;
  27. } Player;
  28.  
  29. typedef struct EnvItem {
  30. Rectangle rect;
  31. int blocking;
  32. Color color;
  33. } EnvItem;
  34.  
  35.  
  36. void UpdatePlayer(Player *player, EnvItem *envItems, int envItemsLength, float delta);
  37.  
  38. void UpdateCameraCenter(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height);
  39. void UpdateCameraCenterInsideMap(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height);
  40. void UpdateCameraCenterSmoothFollow(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height);
  41. void UpdateCameraEvenOutOnLanding(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height);
  42. void UpdateCameraPlayerBoundsPush(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height);
  43.  
  44.  
  45. int main(void)
  46. {
  47. // Initialization
  48. //--------------------------------------------------------------------------------------
  49. const int screenWidth = 800;
  50. const int screenHeight = 450;
  51.  
  52. InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera");
  53.  
  54. Player player = { 0 };
  55. player.position = (Vector2){ 400, 280 };
  56. player.downspeed = 0;
  57. player.canJump = false;
  58. EnvItem envItems[] = {
  59. {{ 0, 0, 1000, 400 }, 0, LIGHTGRAY },
  60. {{ 0, 400, 1000, 200 }, 1, GRAY },
  61. {{ 300, 200, 400, 10 }, 1, GRAY },
  62. {{ 250, 300, 100, 10 }, 1, GRAY },
  63. {{ 650, 300, 100, 10 }, 1, GRAY }
  64. };
  65.  
  66. int envItemsLength = sizeof(envItems)/sizeof(envItems[0]);
  67.  
  68. Camera2D camera = { 0 };
  69. camera.target = player.position;
  70. camera.offset = (Vector2){ screenWidth/2.0f, screenHeight/2.0f };
  71. camera.rotation = 0.0f;
  72. camera.zoom = 1.0f;
  73.  
  74. // Store pointers to the multiple update camera functions
  75. void (*cameraUpdaters[])(Camera2D*, Player*, EnvItem*, int, float, int, int) = {
  76. UpdateCameraCenter,
  77. UpdateCameraCenterInsideMap,
  78. UpdateCameraCenterSmoothFollow,
  79. UpdateCameraEvenOutOnLanding,
  80. UpdateCameraPlayerBoundsPush
  81. };
  82.  
  83. int cameraOption = 0;
  84. int cameraUpdatersLength = sizeof(cameraUpdaters)/sizeof(cameraUpdaters[0]);
  85.  
  86. char *cameraDescriptions[] = {
  87. "Follow player center",
  88. "Follow player center, but clamp to map edges",
  89. "Follow player center; smoothed",
  90. "Follow player center horizontally; updateplayer center vertically after landing",
  91. "Player push camera on getting too close to screen edge"
  92. };
  93.  
  94. char* x_pos_txt;
  95. char* y_pos_txt;
  96.  
  97. SetTargetFPS(60);
  98. //--------------------------------------------------------------------------------------
  99.  
  100. // Main game loop
  101. while (!WindowShouldClose())
  102. {
  103. // Update
  104. //----------------------------------------------------------------------------------
  105. float deltaTime = GetFrameTime();
  106.  
  107. UpdatePlayer(&player, envItems, envItemsLength, deltaTime);
  108.  
  109. camera.zoom += ((float)GetMouseWheelMove()*0.05f);
  110.  
  111. if (camera.zoom > 3.0f) camera.zoom = 3.0f;
  112. else if (camera.zoom < 0.25f) camera.zoom = 0.25f;
  113.  
  114. if (IsKeyPressed(KEY_R))
  115. {
  116. camera.zoom = 1.0f;
  117. player.position = (Vector2){ 400, 280 };
  118. }
  119.  
  120. if (IsKeyPressed(KEY_C)) cameraOption = (cameraOption + 1)%cameraUpdatersLength;
  121.  
  122. // Call update camera function by its pointer
  123. cameraUpdaters[cameraOption](&camera, &player, envItems, envItemsLength, deltaTime, screenWidth, screenHeight);
  124. //----------------------------------------------------------------------------------
  125.  
  126. // Draw
  127. //----------------------------------------------------------------------------------
  128. BeginDrawing();
  129.  
  130. ClearBackground(LIGHTGRAY);
  131.  
  132. BeginMode2D(camera);
  133.  
  134. for (int i = 0; i < envItemsLength; i++) DrawRectangleRec(envItems[i].rect, envItems[i].color);
  135.  
  136. Rectangle playerRect = { player.position.x - 20, player.position.y - 40, 40, 40 };
  137. DrawRectangleRec(playerRect, RED);
  138.  
  139. EndMode2D();
  140.  
  141. DrawText("Controls:", 20, 20, 10, BLACK);
  142. DrawText("- Right/Left to move", 40, 40, 10, DARKGRAY);
  143. DrawText("- Space to jump", 40, 60, 10, DARKGRAY);
  144. DrawText("- Mouse Wheel to Zoom in-out, R to reset zoom", 40, 80, 10, DARKGRAY);
  145. DrawText("- C to change camera mode", 40, 100, 10, DARKGRAY);
  146. DrawText("Current camera mode:", 20, 120, 10, BLACK);
  147. DrawText(cameraDescriptions[cameraOption], 40, 140, 10, DARKGRAY);
  148.  
  149.  
  150. asprintf(&x_pos_txt, "X pos: %f", player.position.x);
  151. asprintf(&y_pos_txt, "y pos: %f", player.position.y);
  152.  
  153. DrawText(x_pos_txt, 20, 180, 10, BLACK);
  154. DrawText(y_pos_txt, 20, 200, 10, BLACK);
  155.  
  156.  
  157. EndDrawing();
  158. //----------------------------------------------------------------------------------
  159. }
  160.  
  161. // De-Initialization
  162. //--------------------------------------------------------------------------------------
  163. CloseWindow(); // Close window and OpenGL context
  164. //--------------------------------------------------------------------------------------
  165.  
  166. return 0;
  167. }
  168.  
  169. void UpdatePlayer(Player *player, EnvItem *envItems, int envItemsLength, float delta)
  170. {
  171. if (IsKeyDown(KEY_SPACE) && player->canJump)
  172. {
  173. player->downspeed = -PLAYER_JUMP_SPD;
  174. player->canJump = false;
  175. }
  176.  
  177. int hitObstacle = 0;
  178. int onGround = 0;
  179. for (int i = 0; i < envItemsLength; i++)
  180. {
  181. EnvItem *ei = envItems + i;
  182. Vector2 *p = &(player->position);
  183. if (ei->blocking &&
  184. ei->rect.x <= p->x &&
  185. ei->rect.x + ei->rect.width >= p->x &&
  186. ei->rect.y >= p->y &&
  187. ei->rect.y < p->y + player->downspeed*delta
  188. )
  189. {
  190. onGround = 1;
  191. player->downspeed = 0.0f;
  192. p->y = ei->rect.y;
  193. }
  194. else if (ei->blocking &&
  195. ei->rect.y >= p->y &&
  196. ei->rect.y + ei->rect.height <= p->y
  197. //ei->rect.y >= p->y &&
  198. //ei->rect.y < p->y + player->downspeed*delta
  199. )
  200. {
  201. hitObstacle = 1;
  202. }
  203.  
  204. }
  205.  
  206. if (!onGround)
  207. {
  208. player->position.y += player->downspeed*delta;
  209. player->downspeed += G*delta;
  210. player->canJump = true;
  211. }
  212. if (!hitObstacle) {
  213. if (IsKeyDown(KEY_LEFT)) player->position.x -= PLAYER_HOR_SPD*delta;
  214. if (IsKeyDown(KEY_RIGHT)) player->position.x += PLAYER_HOR_SPD*delta;
  215. }
  216. else player->canJump = true;
  217. }
  218.  
  219. void UpdateCameraCenter(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height)
  220. {
  221. camera->offset = (Vector2){ width/2.0f, height/2.0f };
  222. camera->target = player->position;
  223. }
  224.  
  225. void UpdateCameraCenterInsideMap(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height)
  226. {
  227. camera->target = player->position;
  228. camera->offset = (Vector2){ width/2.0f, height/2.0f };
  229. float minX = 1000, minY = 1000, maxX = -1000, maxY = -1000;
  230.  
  231. for (int i = 0; i < envItemsLength; i++)
  232. {
  233. EnvItem *ei = envItems + i;
  234. minX = fminf(ei->rect.x, minX);
  235. maxX = fmaxf(ei->rect.x + ei->rect.width, maxX);
  236. minY = fminf(ei->rect.y, minY);
  237. maxY = fmaxf(ei->rect.y + ei->rect.height, maxY);
  238. }
  239.  
  240. Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, *camera);
  241. Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, *camera);
  242.  
  243. if (max.x < width) camera->offset.x = width - (max.x - width/2);
  244. if (max.y < height) camera->offset.y = height - (max.y - height/2);
  245. if (min.x > 0) camera->offset.x = width/2 - min.x;
  246. if (min.y > 0) camera->offset.y = height/2 - min.y;
  247. }
  248.  
  249. void UpdateCameraCenterSmoothFollow(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height)
  250. {
  251. static float minSpeed = 30;
  252. static float minEffectLength = 10;
  253. static float fractionSpeed = 0.8f;
  254.  
  255. camera->offset = (Vector2){ width/2.0f, height/2.0f };
  256. Vector2 diff = Vector2Subtract(player->position, camera->target);
  257. float length = Vector2Length(diff);
  258.  
  259. if (length > minEffectLength)
  260. {
  261. float speed = fmaxf(fractionSpeed*length, minSpeed);
  262. camera->target = Vector2Add(camera->target, Vector2Scale(diff, speed*delta/length));
  263. }
  264. }
  265.  
  266. void UpdateCameraEvenOutOnLanding(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height)
  267. {
  268. static float evenOutSpeed = 700;
  269. static int eveningOut = false;
  270. static float evenOutTarget;
  271.  
  272. camera->offset = (Vector2){ width/2.0f, height/2.0f };
  273. camera->target.x = player->position.x;
  274.  
  275. if (eveningOut)
  276. {
  277. if (evenOutTarget > camera->target.y)
  278. {
  279. camera->target.y += evenOutSpeed*delta;
  280.  
  281. if (camera->target.y > evenOutTarget)
  282. {
  283. camera->target.y = evenOutTarget;
  284. eveningOut = 0;
  285. }
  286. }
  287. else
  288. {
  289. camera->target.y -= evenOutSpeed*delta;
  290.  
  291. if (camera->target.y < evenOutTarget)
  292. {
  293. camera->target.y = evenOutTarget;
  294. eveningOut = 0;
  295. }
  296. }
  297. }
  298. else
  299. {
  300. if (player->canJump && (player->downspeed == 0) && (player->position.y != camera->target.y))
  301. {
  302. eveningOut = 1;
  303. evenOutTarget = player->position.y;
  304. }
  305. }
  306. }
  307.  
  308. void UpdateCameraPlayerBoundsPush(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height)
  309. {
  310. static Vector2 bbox = { 0.2f, 0.2f };
  311.  
  312. Vector2 bboxWorldMin = GetScreenToWorld2D((Vector2){ (1 - bbox.x)*0.5f*width, (1 - bbox.y)*0.5f*height }, *camera);
  313. Vector2 bboxWorldMax = GetScreenToWorld2D((Vector2){ (1 + bbox.x)*0.5f*width, (1 + bbox.y)*0.5f*height }, *camera);
  314. camera->offset = (Vector2){ (1 - bbox.x)*0.5f * width, (1 - bbox.y)*0.5f*height };
  315.  
  316. if (player->position.x < bboxWorldMin.x) camera->target.x = player->position.x;
  317. if (player->position.y < bboxWorldMin.y) camera->target.y = player->position.y;
  318. if (player->position.x > bboxWorldMax.x) camera->target.x = bboxWorldMin.x + (player->position.x - bboxWorldMax.x);
  319. if (player->position.y > bboxWorldMax.y) camera->target.y = bboxWorldMin.y + (player->position.y - bboxWorldMax.y);
  320. }
  321.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement