coin.c 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #include <stdlib.h>
  2. #include <stdbool.h>
  3. #include <jetpack_joyride_icons.h>
  4. #include <gui/gui.h>
  5. #include "coin.h"
  6. #include "barry.h"
  7. // Patterns
  8. const COIN_PATTERN coin_patterns[] = {
  9. {// Square pattern
  10. .count = 9,
  11. .coins = {{0, 0}, {8, 0}, {16, 0}, {0, 8}, {8, 8}, {16, 8}, {0, 16}, {8, 16}, {16, 16}}},
  12. {// Wavy pattern (approximate sine wave)
  13. .count = 8,
  14. .coins = {{0, 8}, {8, 16}, {16, 24}, {24, 16}, {32, 8}, {40, 0}, {48, 8}, {56, 16}}},
  15. {// Diagonal pattern
  16. .count = 5,
  17. .coins = {{0, 0}, {8, 8}, {16, 16}, {24, 24}, {32, 32}}},
  18. // Add more patterns here
  19. };
  20. void coin_tick(COIN* const coins, BARRY* const barry, int* const poins) {
  21. // Move coins towards the player
  22. for(int i = 0; i < COINS_MAX; i++) {
  23. if(coin_colides(&coins[i], barry)) {
  24. coins[i].point.x = 0; // Remove the coin
  25. (*poins)++;
  26. }
  27. if(coins[i].point.x > 0) {
  28. coins[i].point.x -= 1; // move left by 1 unit
  29. if(coins[i].point.x < -16) { // if the coin is out of screen
  30. coins[i].point.x = 0; // set coin x coordinate to 0 to mark it as "inactive"
  31. }
  32. }
  33. }
  34. }
  35. bool coin_colides(COIN* const coin, BARRY* const barry) {
  36. return !(
  37. barry->point.x > coin->point.x + 7 || // Barry is to the right of the coin
  38. barry->point.x + 11 < coin->point.x || // Barry is to the left of the coin
  39. barry->point.y > coin->point.y + 7 || // Barry is below the coin
  40. barry->point.y + 15 < coin->point.y); // Barry is above the coin
  41. }
  42. void spawn_random_coin(COIN* const coins) {
  43. // Select a random pattern
  44. int pattern_index = rand() % (sizeof(coin_patterns) / sizeof(coin_patterns[0]));
  45. const COIN_PATTERN* pattern = &coin_patterns[pattern_index];
  46. // Count available slots for new coins
  47. int available_slots = 0;
  48. for(int i = 0; i < COINS_MAX; ++i) {
  49. if(coins[i].point.x <= 0) {
  50. ++available_slots;
  51. }
  52. }
  53. // If there aren't enough slots, return without spawning coins
  54. if(available_slots < pattern->count) return;
  55. // Spawn coins according to the selected pattern
  56. int coin_index = 0;
  57. int random_offset = rand() % (64 - 32);
  58. for(int i = 0; i < pattern->count; ++i) {
  59. // Find an available slot for a new coin
  60. while(coins[coin_index].point.x > 0 && coin_index < COINS_MAX) {
  61. ++coin_index;
  62. }
  63. // If no slot is available, stop spawning coins
  64. if(coin_index == COINS_MAX) break;
  65. // Spawn the coin
  66. coins[coin_index].point.x = 127 + pattern->coins[i].x;
  67. coins[coin_index].point.y =
  68. random_offset +
  69. pattern->coins[i]
  70. .y; // The pattern is spawned at a random y position, but not too close to the screen edge
  71. }
  72. }
  73. void draw_coins(const COIN* coins, Canvas* const canvas) {
  74. canvas_set_color(canvas, ColorBlack);
  75. for(int i = 0; i < COINS_MAX; ++i) {
  76. if(coins[i].point.x > 0) {
  77. canvas_set_color(canvas, ColorBlack);
  78. canvas_draw_icon(canvas, coins[i].point.x, coins[i].point.y, &I_coin);
  79. canvas_set_color(canvas, ColorWhite);
  80. canvas_draw_icon(canvas, coins[i].point.x, coins[i].point.y, &I_coin_infill);
  81. }
  82. }
  83. }