world_game.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #include "game.h"
  2. #include "stdlib.h"
  3. #include "sdl_helper.h"
  4. #include "game_player.h"
  5. #include "game_map.h"
  6. #include "game_item.h"
  7. /* game world
  8. * contains a number of characters that can run around
  9. */
  10. struct world_game {
  11. struct world w;
  12. // players (0: user 1: AI)
  13. struct game_player p[2];
  14. // map
  15. struct game_map map;
  16. // item manager
  17. struct game_item_manager item_manager;
  18. enum { GAME_STATE_PLAYING, GAME_STATE_OVER } state;
  19. };
  20. void world_game_init(struct world_game *world) {
  21. /* Initialize game data */
  22. game_map_init(&world->map);
  23. for (int i = 0; i < 2; i++) {
  24. world->p[i].players = world->p;
  25. game_player_init(&world->p[i], &world->map);
  26. }
  27. world->p[1].rect.x += 100;
  28. game_item_manager_init(&world->item_manager);
  29. world->item_manager.map = &world->map;
  30. world->state = GAME_STATE_PLAYING;
  31. } // init
  32. // update objects
  33. void world_game_update(struct world_game *world) {
  34. /* when game over triggers, ideally there's an animation
  35. * running for a few frames, then move away
  36. * for now, just move to main menu
  37. */
  38. if (world->state == GAME_STATE_OVER) {
  39. // free previous world, move to the next one
  40. free(c_world);
  41. c_world = world_menu_create();
  42. return;
  43. }
  44. game_player_ai(&world->p[1]);
  45. game_map_update(&world->map);
  46. game_item_manager_update(&world->item_manager);
  47. // Update players, and keep track how many are alive
  48. int living_players = 2;
  49. for (int i = 0; i < 2; i++) {
  50. if (game_player_get_state(&world->p[i]) != DROWN) {
  51. game_player_update(&world->p[i]);
  52. }
  53. else {
  54. living_players--;
  55. }
  56. }
  57. // 1 or less players means its game over
  58. if (living_players <= 1) {
  59. world->state = GAME_STATE_OVER;
  60. }
  61. /* calculage offset to center the active player on the screen
  62. * then offset everything affected
  63. */
  64. int offset_x = (GAME_WIDTH /2 -world->p[0].rect.x) *0.1;
  65. int offset_y = (GAME_HEIGHT/2 -world->p[0].rect.y) *0.1;
  66. game_item_manager_scroll(&world->item_manager,
  67. -offset_x,
  68. -offset_y);
  69. for (int i = 0; i < 2; i++) {
  70. game_player_offset(&world->p[i], offset_x, offset_y);
  71. }
  72. game_map_offset(&world->map, offset_x, offset_y);
  73. // each player has a chance to pick up items
  74. for (int i = 0; i < 2; i++) {
  75. game_item_manager_collide(&world->item_manager, &world->p[i]);
  76. }
  77. }
  78. // draw objects
  79. void world_game_draw(struct world_game *world) {
  80. game_map_draw(&world->map);
  81. for (int i = 0; i < 2; i++) {
  82. game_player_draw(&world->p[i]);
  83. }
  84. game_map_draw_front(&world->map);
  85. game_item_manager_draw(&world->item_manager);
  86. }
  87. void world_game_key(struct world_game *world, SDL_Scancode key, int state) {
  88. if (world->state != GAME_STATE_PLAYING) return;
  89. switch (key) {
  90. case SDL_SCANCODE_D:
  91. if (state == KEY_PRESSED) {
  92. game_player_moveright(&world->p[0]);
  93. }
  94. else {
  95. game_player_movestop(&world->p[0]);
  96. }
  97. break;
  98. case SDL_SCANCODE_A:
  99. if (state == KEY_PRESSED) {
  100. game_player_moveleft(&world->p[0]);
  101. }
  102. else {
  103. game_player_movestop(&world->p[0]);
  104. }
  105. break;
  106. case SDL_SCANCODE_W:
  107. if (state == KEY_PRESSED) {
  108. game_player_jump(&world->p[0]);
  109. }
  110. break;
  111. case SDL_SCANCODE_S:
  112. if (state == KEY_PRESSED) {
  113. game_player_useskill(&world->p[0]);
  114. }
  115. break;
  116. case SDL_SCANCODE_SPACE:
  117. if (state == KEY_PRESSED) {
  118. game_player_attack(&world->p[0]);
  119. }
  120. break;
  121. default:
  122. break;
  123. }
  124. }
  125. void world_game_mouse(struct world_game *world,
  126. int button, int state, int x, int y) {
  127. (void) world;
  128. (void) button;
  129. (void) state;
  130. (void) x;
  131. (void) y;
  132. }
  133. /* responsible on initialising a new world of this type
  134. * and initialising any variable that needs to
  135. * returns a new instance of this world
  136. */
  137. struct world *world_game_create() {
  138. // initialise world
  139. struct world_game *world = malloc(sizeof(struct world_game));
  140. // set the world's callbacks to this world's
  141. world->w.update = (void (*)(void*)) world_game_update;
  142. world->w.draw = (void (*)(void*)) world_game_draw;
  143. world->w.key = (void (*)(void*, SDL_Scancode, int)) world_game_key;
  144. world->w.mouse = (void (*)(void*, int, int, int, int)) world_game_mouse;
  145. // init
  146. world_game_init(world);
  147. // return the instance of this world
  148. return (struct world*) world;
  149. }