diff --git a/gamestate.c b/gamestate.c index 178da2d..ae7b260 100644 --- a/gamestate.c +++ b/gamestate.c @@ -342,6 +342,7 @@ void ser_player(char **out, struct Player *p) ser_int(out, p->currently_inhabiting_index); ser_V2(out, p->pos); ser_V2(out, p->vel); + ser_float(out, p->spice_taken_away); // input ser_V2(out, p->movement); @@ -361,6 +362,7 @@ void des_player(char **in, struct Player *p, struct GameState *gs) des_int(in, &p->currently_inhabiting_index); des_V2(in, &p->pos); des_V2(in, &p->vel); + des_float(in, &p->spice_taken_away); // input des_V2(in, &p->movement); @@ -499,6 +501,7 @@ void process(struct GameState *gs, float dt) struct Box *cur_box = (struct Box *)cpShapeGetUserData(nearest); struct Grid *cur_grid = (struct Grid *)cpBodyGetUserData(cpShapeGetBody(nearest)); grid_remove_box(gs->space, cur_grid, cur_box); + p->spice_taken_away -= 0.1f; } else if(p->grid_index == -1) { @@ -512,6 +515,7 @@ void process(struct GameState *gs, float dt) break; } } + p->spice_taken_away += 0.2f; grid_new(empty_grid, gs, p->build); box_new(&empty_grid->boxes[0], gs, empty_grid, (V2){0}); } @@ -530,6 +534,7 @@ void process(struct GameState *gs, float dt) } // @Robust cleanly fail when not enough boxes assert(empty_box != NULL); + p->spice_taken_away += 0.1f; box_new(empty_box, gs, g, grid_world_to_local(g, p->build)); } } @@ -580,8 +585,10 @@ void process(struct GameState *gs, float dt) if (p->currently_inhabiting_index == -1) { - p->vel = V2add(p->vel, V2scale(p->movement, dt*3.0f)); + // @Robust make sure movement vector is normalized so player can't cheat + p->vel = V2add(p->vel, V2scale(p->movement, dt*0.5f)); p->pos = V2add(p->pos, V2scale(p->vel, dt)); + p->spice_taken_away += dt*0.15f*V2length(p->movement); } else { @@ -589,6 +596,14 @@ void process(struct GameState *gs, float dt) p->pos = V2lerp(p->pos, grid_com(g), dt * 20.0f); cpBodyApplyForceAtWorldPoint(g->body, v2_to_cp(V2scale(p->movement, 5.0f)), v2_to_cp(grid_com(g))); } + + if(p->spice_taken_away >= 1.0f) + { + reset_player(p); + p->connected = true; + } + + p->spice_taken_away = clamp01(p->spice_taken_away); } cpSpaceStep(gs->space, dt); diff --git a/main.c b/main.c index bf507b8..5ea38e0 100644 --- a/main.c +++ b/main.c @@ -129,6 +129,22 @@ static void drawbox(V2 gridpos, float rot, V2 bpos, float damage, bool offset_fr sgp_pop_transform(); } +static void draw_circle(V2 point, float radius) +{ +#define POINTS 64 + sgp_line lines[POINTS]; + for (int i = 0; i < POINTS; i++) + { + float progress = (float)i / (float)POINTS; + float next_progress = (float)(i + 1) / (float)POINTS; + lines[i].a = (V2){.x = cos(progress * 2.0f * PI) * radius, .y = sin(progress * 2.0f * PI) * radius}; + lines[i].b = (V2){.x = cos(next_progress * 2.0f * PI) * radius, .y = sin(next_progress * 2.0f * PI) * radius}; + lines[i].a = V2add(lines[i].a, point); + lines[i].b = V2add(lines[i].b, point); + } + sgp_draw_lines(lines, POINTS); +} + static void frame(void) { int width = sapp_width(), height = sapp_height(); @@ -207,6 +223,7 @@ static void frame(void) float grid_rotation; V2 pos; } build_preview = {0}; + bool hand_at_arms_length = false; { // calculate world position and camera { @@ -222,14 +239,29 @@ static void frame(void) // calculate build preview stuff int grid_index = -1; + if (myplayer != -1) { - struct Grid *placing_grid = closest_to_point_in_radius(&gs, world_mouse_pos, 0.35f); + V2 hand_pos = V2sub(world_mouse_pos, gs.players[myplayer].pos); + float hand_len = V2length(hand_pos); + if (hand_len > MAX_HAND_REACH) + { + hand_at_arms_length = true; + hand_len = MAX_HAND_REACH; + } + else + { + hand_at_arms_length = false; + } + hand_pos = V2scale(V2normalize(hand_pos), hand_len); + hand_pos = V2add(hand_pos, gs.players[myplayer].pos); + + struct Grid *placing_grid = closest_to_point_in_radius(&gs, hand_pos, 0.35f); if (placing_grid == NULL) { build_preview = (struct BuildPreviewInfo){ - .grid_pos = world_mouse_pos, + .grid_pos = hand_pos, .grid_rotation = 0.0f, - .pos = world_mouse_pos, + .pos = hand_pos, }; } else @@ -242,7 +274,7 @@ static void frame(void) break; } } - V2 pos = grid_snapped_box_pos(placing_grid, world_mouse_pos); + V2 pos = grid_snapped_box_pos(placing_grid, hand_pos); build_preview = (struct BuildPreviewInfo){ .grid_pos = grid_pos(placing_grid), .grid_rotation = grid_rotation(placing_grid), @@ -285,6 +317,17 @@ static void frame(void) sgp_set_color(0.1f, 0.1f, 0.1f, 1.0f); sgp_clear(); + // draw spice bar + if (myplayer != -1) + { + sgp_set_color(0.5f, 0.5f, 0.5f, 1.0f); + float margin = width * 0.1; + float bar_width = width - margin * 2.0f; + sgp_draw_filled_rect(margin, 80.0f, bar_width, 30.0f); + sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f); + sgp_draw_filled_rect(margin, 80.0f, bar_width * (1.0f - gs.players[myplayer].spice_taken_away), 30.0f); + } + // sokol drawing library draw in world space { sgp_translate(width / 2, height / 2); @@ -295,9 +338,16 @@ static void frame(void) sgp_translate(-camera_pos.x, -camera_pos.y); } - sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f); + if (myplayer != -1) + { + static float hand_reach_alpha = 1.0f; + hand_reach_alpha = lerp(hand_reach_alpha, hand_at_arms_length ? 1.0f : 0.0f, dt*5.0); + sgp_set_color(1.0f, 1.0f, 1.0f, hand_reach_alpha); + draw_circle(gs.players[myplayer].pos, MAX_HAND_REACH); + } // stars + sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f); const int num = 50; for (int x = -num; x < num; x++) { diff --git a/types.h b/types.h index 03c8a9a..8c7fd21 100644 --- a/types.h +++ b/types.h @@ -2,6 +2,7 @@ #define MAX_PLAYERS 4 #define BOX_SIZE 0.5f +#define MAX_HAND_REACH 1.0f #define MAX_GRIDS 32 #define MAX_BOXES_PER_GRID 32 #define BOX_MASS 1.0f @@ -52,10 +53,12 @@ struct GameState cpSpace *space; struct Player { - int currently_inhabiting_index; // is equal to -1 when not inhabiting a grid bool connected; + + int currently_inhabiting_index; // is equal to -1 when not inhabiting a grid V2 pos; V2 vel; + float spice_taken_away; // at 1.0, out of spice // input V2 movement; @@ -200,6 +203,11 @@ static V2 V2sub(V2 a, V2 b) }; } +static inline float clamp01(float f) +{ + return fmax(0.0f, fmin(f, 1.0f)); +} + static float lerp(float a, float b, float f) { return a * (1.0f - f) + (b * f);