#include "cglm/vec4.h" #include "scufeng/Scene.h" #include "SinglePlayer.h" #include "screen.h" SinglePlayer SinglePlayer_alloc( unsigned int screen_w, unsigned int screen_h, float paddles_w, float paddles_h, float paddle_l_x, float paddle_speed, float ball_w, vec2 ball_pos, float ball_speed ) { SinglePlayer sp = { .screen_w = screen_w, .screen_h = screen_h, .state = GameState_new( paddles_w, paddles_h, paddle_l_x, paddle_speed, ball_w, ball_pos, ball_speed ), .paddle_l = SEMesh_rect_color_alloc(GLM_VEC4_ONE), .paddle_r = SEMesh_rect_color_alloc(GLM_VEC4_ONE), .ball = SEMesh_rect_color_alloc(GLM_VEC4_ONE), }; sp.paddle_l.transform.scale[0] = screen_w * paddles_w; sp.paddle_l.transform.scale[1] = screen_h * paddles_h; sp.paddle_l.transform.pos[0] = screen_w * paddle_l_x; sp.paddle_l.transform.pos[1] = screen_h / 2.0f; sp.paddle_r.transform.scale[0] = screen_w * paddles_w; sp.paddle_r.transform.scale[1] = screen_h * paddles_h; sp.paddle_r.transform.pos[0] = screen_w * (1.0f - paddle_l_x); sp.paddle_r.transform.pos[1] = screen_h / 2.0f; sp.ball.transform.scale[0] = screen_w * ball_w; sp.ball.transform.scale[1] = sp.ball.transform.scale[0]; sp.ball.transform.pos[0] = screen_w * ball_pos[0]; sp.ball.transform.pos[1] = screen_h * ball_pos[1]; return sp; } void SinglePlayer_free(SinglePlayer *sp) { SEMesh_free(&sp->paddle_l); SEMesh_free(&sp->paddle_r); SEMesh_free(&sp->ball); } static void pos_convert( vec3 render_pos, const vec3 state_pos, const unsigned int screen_w, const unsigned int screen_h ) { render_pos[0] = state_pos[0] * screen_w; render_pos[1] = (1.0f - state_pos[1]) * screen_h; } static void update_shapes( const GameState *const state, SEMesh *const paddle_l, SEMesh *const paddle_r, SEMesh *const ball, const unsigned int screen_w, const unsigned int screen_h ) { // Paddles pos_convert(paddle_l->transform.pos, state->paddle_l.pos, screen_w, screen_h); pos_convert(paddle_r->transform.pos, state->paddle_r.pos, screen_w, screen_h); // Ball pos_convert(ball->transform.pos, state->ball.pos, screen_w, screen_h); } static bool key_input_handle(GameState *const state) { if (se_get_key(SE_KEY_W) == SE_KEY_ACTION_PRESS) { GameState_move_paddle_l(state, SE_UP); } else if (se_get_key(SE_KEY_S) == SE_KEY_ACTION_PRESS) { GameState_move_paddle_l(state, SE_DOWN); } else { GameState_move_paddle_l(state, SE_NONE); } if (se_get_key(SE_KEY_ESCAPE) == SE_KEY_ACTION_PRESS) { return true; } return false; } Screen SinglePlayer_tick(SinglePlayer *const sp, const double delta) { if (key_input_handle(&sp->state)) { return PONG_MAIN_MENU; } GameState_update(&sp->state, delta); update_shapes( &sp->state, &sp->paddle_l, &sp->paddle_r, &sp->ball, sp->screen_w, sp->screen_h ); SEMesh *meshes[] = { &sp->paddle_l, &sp->paddle_r, &sp->ball }; se_render_meshes_2d(meshes, sizeof(meshes) / sizeof(meshes[0])); return PONG_SINGLEPLAYER; }