SinglePlayer.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #include "cglm/vec4.h"
  2. #include "scufeng/Scene.h"
  3. #include "SinglePlayer.h"
  4. #include "screen.h"
  5. SinglePlayer SinglePlayer_alloc(
  6. unsigned int screen_w,
  7. unsigned int screen_h,
  8. float paddles_w,
  9. float paddles_h,
  10. float paddle_l_x,
  11. float paddle_speed,
  12. float ball_w,
  13. vec2 ball_pos,
  14. float ball_speed
  15. ) {
  16. SinglePlayer sp = {
  17. .screen_w = screen_w,
  18. .screen_h = screen_h,
  19. .state = GameState_new(
  20. paddles_w,
  21. paddles_h,
  22. paddle_l_x,
  23. paddle_speed,
  24. ball_w,
  25. ball_pos,
  26. ball_speed
  27. ),
  28. .paddle_l = SEMesh_rect_color_alloc(GLM_VEC4_ONE),
  29. .paddle_r = SEMesh_rect_color_alloc(GLM_VEC4_ONE),
  30. .ball = SEMesh_rect_color_alloc(GLM_VEC4_ONE),
  31. };
  32. sp.paddle_l.transform.scale[0] = screen_w * paddles_w;
  33. sp.paddle_l.transform.scale[1] = screen_h * paddles_h;
  34. sp.paddle_l.transform.pos[0] = screen_w * paddle_l_x;
  35. sp.paddle_l.transform.pos[1] = screen_h / 2.0f;
  36. sp.paddle_r.transform.scale[0] = screen_w * paddles_w;
  37. sp.paddle_r.transform.scale[1] = screen_h * paddles_h;
  38. sp.paddle_r.transform.pos[0] = screen_w * (1.0f - paddle_l_x);
  39. sp.paddle_r.transform.pos[1] = screen_h / 2.0f;
  40. sp.ball.transform.scale[0] = screen_w * ball_w;
  41. sp.ball.transform.scale[1] = sp.ball.transform.scale[0];
  42. sp.ball.transform.pos[0] = screen_w * ball_pos[0];
  43. sp.ball.transform.pos[1] = screen_h * ball_pos[1];
  44. return sp;
  45. }
  46. void SinglePlayer_free(SinglePlayer *sp) {
  47. SEMesh_free(&sp->paddle_l);
  48. SEMesh_free(&sp->paddle_r);
  49. SEMesh_free(&sp->ball);
  50. }
  51. static void pos_convert(
  52. vec3 render_pos,
  53. const vec3 state_pos,
  54. const unsigned int screen_w,
  55. const unsigned int screen_h
  56. ) {
  57. render_pos[0] = state_pos[0] * screen_w;
  58. render_pos[1] = (1.0f - state_pos[1]) * screen_h;
  59. }
  60. static void update_shapes(
  61. const GameState *const state,
  62. SEMesh *const paddle_l,
  63. SEMesh *const paddle_r,
  64. SEMesh *const ball,
  65. const unsigned int screen_w,
  66. const unsigned int screen_h
  67. ) {
  68. // Paddles
  69. pos_convert(paddle_l->transform.pos, state->paddle_l.pos, screen_w, screen_h);
  70. pos_convert(paddle_r->transform.pos, state->paddle_r.pos, screen_w, screen_h);
  71. // Ball
  72. pos_convert(ball->transform.pos, state->ball.pos, screen_w, screen_h);
  73. }
  74. static bool key_input_handle(GameState *const state) {
  75. if (se_get_key(SE_KEY_W) == SE_KEY_ACTION_PRESS) {
  76. GameState_move_paddle_l(state, SE_UP);
  77. } else if (se_get_key(SE_KEY_S) == SE_KEY_ACTION_PRESS) {
  78. GameState_move_paddle_l(state, SE_DOWN);
  79. } else {
  80. GameState_move_paddle_l(state, SE_NONE);
  81. }
  82. if (se_get_key(SE_KEY_ESCAPE) == SE_KEY_ACTION_PRESS) {
  83. return true;
  84. }
  85. return false;
  86. }
  87. Screen SinglePlayer_tick(SinglePlayer *const sp, const double delta) {
  88. if (key_input_handle(&sp->state)) {
  89. return PONG_MAIN_MENU;
  90. }
  91. GameState_update(&sp->state, delta);
  92. update_shapes(
  93. &sp->state,
  94. &sp->paddle_l,
  95. &sp->paddle_r,
  96. &sp->ball,
  97. sp->screen_w,
  98. sp->screen_h
  99. );
  100. SEMesh *meshes[] = {
  101. &sp->paddle_l,
  102. &sp->paddle_r,
  103. &sp->ball
  104. };
  105. se_render_meshes_2d(meshes, sizeof(meshes) / sizeof(meshes[0]));
  106. return PONG_SINGLEPLAYER;
  107. }