world_menu.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #include "game.h"
  2. #include "stdlib.h"
  3. #include "sdl_helper.h"
  4. // works best if it is an even number
  5. #define SHAKE_POWER 4
  6. /* main menu
  7. * for now, it only displays a simple background image
  8. */
  9. struct world_menu {
  10. struct world w;
  11. // background image and its rect
  12. SDL_Texture *bg;
  13. SDL_Rect bg_rect;
  14. SDL_Texture *buttons[3];
  15. SDL_Rect buttons_rect[3];
  16. // currently selected button
  17. int selected;
  18. };
  19. /* Initialize menu data */
  20. void world_menu_init(struct world_menu *world) {
  21. // init background image and its rect
  22. world->bg = load_image("engine/dd_logo2.png");
  23. world->bg_rect.x = 0;
  24. world->bg_rect.y = 0;
  25. world->bg_rect.w = 640;
  26. world->bg_rect.h = 480;
  27. //SDL_QueryTexture(world->bg, NULL, NULL, &world->bg_rect.w, &world->bg_rect.h);
  28. world->buttons[0] = load_image("images/button_options.png");
  29. world->buttons[1] = load_image("engine/dd_logo.png");
  30. world->buttons[2] = load_image("images/button_close.png");
  31. for (int i = 0; i < 3; i++) {
  32. world->buttons_rect[i].x = 640 *(i+1) /4 -24;
  33. world->buttons_rect[i].y = i == 1 ? 480/3 : 10;
  34. world->buttons_rect[i].w = 48;
  35. world->buttons_rect[i].h = 48;
  36. }
  37. world->buttons_rect[0].x = 10;
  38. world->buttons_rect[0].y = 10;
  39. world->buttons_rect[2].x = 640 -10 -48;
  40. world->buttons_rect[2].y = 10;
  41. // default button is the middle one
  42. world->selected = 1;
  43. // init randomiser
  44. srand((unsigned int) time(NULL));
  45. } // init
  46. // update
  47. void world_menu_update(struct world_menu *world) {
  48. // flag is set to change to another world
  49. if (world->w.next == 1) {
  50. // free previous world, move to the next one
  51. free(c_world);
  52. c_world = world_game_create();
  53. // when a new world is created, it's best to not execute much more
  54. return;
  55. }
  56. } // update
  57. // draw
  58. void world_menu_draw(struct world_menu *world) {
  59. // background
  60. SDL_RenderCopy(ren, world->bg, NULL, &world->bg_rect);
  61. /* draw buttons
  62. * the active button is drawn bigger, until I decide a better way
  63. * to do it at least
  64. * the rest are drawn as-is
  65. */
  66. for (int i = 0; i < 3; i++) {
  67. if (i == world->selected) {
  68. int randx = rand() %3 == 0 ? (rand() %SHAKE_POWER) -SHAKE_POWER/2 : 0;
  69. int randy = rand() %3 == 0 ? (rand() %SHAKE_POWER) -SHAKE_POWER/2 : 0;
  70. world->buttons_rect[i].x += randx;
  71. world->buttons_rect[i].y += randy;
  72. SDL_RenderCopy(ren, world->buttons[i], NULL, &world->buttons_rect[i]);
  73. world->buttons_rect[i].x -= randx;
  74. world->buttons_rect[i].y -= randy;
  75. }
  76. else {
  77. SDL_RenderCopy(ren, world->buttons[i], NULL, &world->buttons_rect[i]);
  78. }
  79. }
  80. } // draw
  81. /* handle key input
  82. * when return is pressed, set flag to move to new world
  83. */
  84. void world_menu_key(struct world_menu *world, SDL_Scancode key, int state) {
  85. switch (key) {
  86. // move to the previous choice
  87. case SDL_SCANCODE_A:
  88. if (state == KEY_PRESSED) {
  89. if (--world->selected < 0) {
  90. world->selected = 2;
  91. }
  92. }
  93. break;
  94. // move to the next choice
  95. case SDL_SCANCODE_D:
  96. if (state == KEY_PRESSED) {
  97. if (++world->selected >= 3) {
  98. world->selected = 0;
  99. }
  100. }
  101. break;
  102. // select the top-most button
  103. case SDL_SCANCODE_W:
  104. if (state == KEY_PRESSED) {
  105. world->selected = 1;
  106. }
  107. break;
  108. // apply choice
  109. case SDL_SCANCODE_RETURN:
  110. /* do action depending on current button
  111. * 0: options
  112. * 1: start game
  113. * 2: exit
  114. */
  115. switch (world->selected) {
  116. case 0: break;
  117. case 1: world->w.next = 1; break;
  118. case 2: world->w.next = -1; break;
  119. }
  120. break;
  121. default:
  122. break;
  123. }
  124. } // key
  125. /* mouse input not yet implemented
  126. */
  127. void world_menu_mouse(struct world_menu *world,
  128. int button, int state, int x, int y) {
  129. (void) world;
  130. (void) button;
  131. (void) state;
  132. (void) x;
  133. (void) y;
  134. }
  135. /* responsible on initialising a new world of this type
  136. * and initialising any variable that needs to
  137. * returns a new instance of this world
  138. */
  139. struct world *world_menu_create() {
  140. // initialise world
  141. struct world_menu *world = malloc(sizeof(struct world_menu));
  142. // set the world's callbacks to this world's
  143. world->w.update = (void (*)(void*)) world_menu_update;
  144. world->w.draw = (void (*)(void*)) world_menu_draw;
  145. world->w.key = (void (*)(void*, SDL_Scancode, int)) world_menu_key;
  146. world->w.mouse = (void (*)(void*, int, int, int, int)) world_menu_mouse;
  147. world->w.next = 0;
  148. // init
  149. world_menu_init(world);
  150. // return the instance of this world
  151. return (struct world*) world;
  152. }