Y+ is up on coord system, send build rel to grid

main
Cameron Murphy Reikes 2 years ago
parent 471892d374
commit 5c94921eb5

@ -189,6 +189,10 @@ V2 grid_world_to_local(struct Grid *grid, V2 world)
{ {
return cp_to_v2(cpBodyWorldToLocal(grid->body, v2_to_cp(world))); return cp_to_v2(cpBodyWorldToLocal(grid->body, v2_to_cp(world)));
} }
V2 grid_local_to_world(struct Grid *grid, V2 local)
{
return cp_to_v2(cpBodyLocalToWorld(grid->body, v2_to_cp(local)));
}
// returned snapped position is in world coordinates // returned snapped position is in world coordinates
V2 grid_snapped_box_pos(struct Grid *grid, V2 world) V2 grid_snapped_box_pos(struct Grid *grid, V2 world)
{ {
@ -511,63 +515,13 @@ void process(struct GameState *gs, float dt)
if (!p->connected) if (!p->connected)
continue; continue;
// update gold win condition
if (V2length(V2sub(p->pos, gs->goldpos)) < GOLD_COLLECT_RADIUS) if (V2length(V2sub(p->pos, gs->goldpos)) < GOLD_COLLECT_RADIUS)
{ {
p->goldness += 0.2; p->goldness += 0.2;
gs->goldpos = (V2){.x = hash11(gs->time) * 20.0f, .y = hash11(gs->time - 13.6f) * 20.0f}; gs->goldpos = (V2){.x = hash11(gs->time) * 20.0f, .y = hash11(gs->time - 13.6f) * 20.0f};
} }
if (p->dobuild)
{
p->dobuild = false; // handle the input. if didn't do this, after destruction of hovered box, would try to build on its grid with grid_index...
cpPointQueryInfo info = {0};
// @Robust make sure to query only against boxes...
cpShape *nearest = cpSpacePointQueryNearest(gs->space, v2_to_cp(p->build), 0.01f, cpShapeFilterNew(CP_NO_GROUP, CP_ALL_CATEGORIES, CP_ALL_CATEGORIES), &info);
if (nearest != NULL)
{
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)
{
// @Robust better memory mgmt
struct Grid *empty_grid = NULL;
for (int ii = 0; ii < MAX_GRIDS; ii++)
{
if (gs->grids[ii].body == NULL)
{
empty_grid = &gs->grids[ii];
break;
}
}
p->spice_taken_away += 0.2f;
grid_new(empty_grid, gs, p->build);
cpBodySetVelocity(empty_grid->body, v2_to_cp(p->vel));
box_new(&empty_grid->boxes[0], gs, empty_grid, (V2){0});
}
else
{
struct Grid *g = &gs->grids[p->grid_index];
struct Box *empty_box = NULL;
for (int ii = 0; ii < MAX_BOXES_PER_GRID; ii++)
{
if (g->boxes[ii].shape == NULL)
{
empty_box = &g->boxes[ii];
break;
}
}
// @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));
}
}
if (gs->grids[p->currently_inhabiting_index].body == NULL) if (gs->grids[p->currently_inhabiting_index].body == NULL)
{ {
p->currently_inhabiting_index = -1; p->currently_inhabiting_index = -1;
@ -612,21 +566,82 @@ void process(struct GameState *gs, float dt)
} }
} }
// process movement
{
if (p->currently_inhabiting_index == -1) if (p->currently_inhabiting_index == -1)
{ {
// @Robust make sure movement vector is normalized so player can't cheat // @Robust make sure movement vector is normalized so player can't cheat
p->vel = V2add(p->vel, V2scale(p->movement, dt * 0.5f)); 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); p->spice_taken_away += dt * 0.15f * V2length(p->movement);
} }
else else
{ {
struct Grid *g = &gs->grids[p->currently_inhabiting_index]; struct Grid *g = &gs->grids[p->currently_inhabiting_index];
p->pos = V2lerp(p->pos, grid_com(g), dt * 20.0f); V2 target_new_pos = V2lerp(p->pos, grid_com(g), dt * 20.0f);
p->vel = V2scale(V2sub(target_new_pos, p->pos), 1.0f / dt);
cpBodyApplyForceAtWorldPoint(g->body, v2_to_cp(V2scale(p->movement, 5.0f)), v2_to_cp(grid_com(g))); cpBodyApplyForceAtWorldPoint(g->body, v2_to_cp(V2scale(p->movement, 5.0f)), v2_to_cp(grid_com(g)));
// bigger the ship, the more efficient the spice usage // bigger the ship, the more efficient the spice usage
p->spice_taken_away += dt * 0.15f / (cpBodyGetMass(g->body) * 2.0f) * V2length(p->movement); p->spice_taken_away += dt * 0.15f / (cpBodyGetMass(g->body) * 2.0f) * V2length(p->movement);
} }
p->pos = V2add(p->pos, V2scale(p->vel, dt));
}
if (p->dobuild)
{
p->dobuild = false; // handle the input. if didn't do this, after destruction of hovered box, would try to build on its grid with grid_index...
cpPointQueryInfo info = {0};
// @Robust make sure to query only against boxes...
V2 world_build = p->build;
if (p->grid_index != -1)
{
world_build = grid_local_to_world(&gs->grids[p->grid_index], p->build);
}
cpShape *nearest = cpSpacePointQueryNearest(gs->space, v2_to_cp(world_build), 0.01f, cpShapeFilterNew(CP_NO_GROUP, CP_ALL_CATEGORIES, CP_ALL_CATEGORIES), &info);
if (nearest != NULL)
{
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)
{
// @Robust better memory mgmt
struct Grid *empty_grid = NULL;
for (int ii = 0; ii < MAX_GRIDS; ii++)
{
if (gs->grids[ii].body == NULL)
{
empty_grid = &gs->grids[ii];
break;
}
}
assert(empty_grid != NULL);
p->spice_taken_away += 0.2f;
grid_new(empty_grid, gs, world_build);
box_new(&empty_grid->boxes[0], gs, empty_grid, (V2){0});
cpBodySetVelocity(empty_grid->body, v2_to_cp(p->vel));
}
else
{
struct Grid *g = &gs->grids[p->grid_index];
struct Box *empty_box = NULL;
for (int ii = 0; ii < MAX_BOXES_PER_GRID; ii++)
{
if (g->boxes[ii].shape == NULL)
{
empty_box = &g->boxes[ii];
break;
}
}
// @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, world_build));
}
}
if (p->spice_taken_away >= 1.0f) if (p->spice_taken_away >= 1.0f)
{ {

@ -233,7 +233,7 @@ static void frame(void)
} }
world_mouse_pos = V2sub(world_mouse_pos, (V2){.x = width / 2.0f, .y = height / 2.0f}); world_mouse_pos = V2sub(world_mouse_pos, (V2){.x = width / 2.0f, .y = height / 2.0f});
world_mouse_pos.x /= zoom; world_mouse_pos.x /= zoom;
world_mouse_pos.y /= zoom; world_mouse_pos.y /= -zoom;
world_mouse_pos = V2add(world_mouse_pos, (V2){.x = camera_pos.x, .y = camera_pos.y}); world_mouse_pos = V2add(world_mouse_pos, (V2){.x = camera_pos.x, .y = camera_pos.y});
} }
@ -288,13 +288,25 @@ static void frame(void)
struct ClientToServer curmsg = {0}; struct ClientToServer curmsg = {0};
V2 input = (V2){ V2 input = (V2){
.x = (float)keydown[SAPP_KEYCODE_D] - (float)keydown[SAPP_KEYCODE_A], .x = (float)keydown[SAPP_KEYCODE_D] - (float)keydown[SAPP_KEYCODE_A],
.y = (float)keydown[SAPP_KEYCODE_S] - (float)keydown[SAPP_KEYCODE_W], .y = (float)keydown[SAPP_KEYCODE_W] - (float)keydown[SAPP_KEYCODE_S],
}; };
curmsg.movement = input; curmsg.movement = input;
curmsg.inhabit = keypressed[SAPP_KEYCODE_G].pressed; curmsg.inhabit = keypressed[SAPP_KEYCODE_G].pressed;
curmsg.build = build_preview.pos;
curmsg.dobuild = mouse_pressed; curmsg.dobuild = mouse_pressed;
curmsg.grid_index = grid_index; curmsg.grid_index = grid_index;
if (curmsg.dobuild)
{
if (grid_index != -1)
{
curmsg.build = grid_world_to_local(&gs.grids[curmsg.grid_index], build_preview.pos);
V2 untransformed = grid_local_to_world(&gs.grids[curmsg.grid_index], curmsg.build);
untransformed.x += 5.0f;
}
else
{
curmsg.build = build_preview.pos;
}
}
// @BeforeShip figure out why tf the possess ship key is so unreliable // @BeforeShip figure out why tf the possess ship key is so unreliable
ENetPacket *packet = enet_packet_create((void *)&curmsg, sizeof(curmsg), ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT); ENetPacket *packet = enet_packet_create((void *)&curmsg, sizeof(curmsg), ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT);
@ -303,7 +315,7 @@ static void frame(void)
// @BeforeShip client side prediction and rollback to previous server authoritative state, then replay inputs // @BeforeShip client side prediction and rollback to previous server authoritative state, then replay inputs
// no need to store copies of game state, just player input frame to frame. Then know how many frames ago the server game state arrived, it's that easy! // no need to store copies of game state, just player input frame to frame. Then know how many frames ago the server game state arrived, it's that easy!
process(&gs, (float)sapp_frame_duration()); // process(&gs, (float)sapp_frame_duration());
} }
// drawing // drawing
@ -329,9 +341,10 @@ static void frame(void)
} }
// sokol drawing library draw in world space // sokol drawing library draw in world space
// world space coordinates are +Y up, -Y down. Like normal cartesian coords
{ {
sgp_translate(width / 2, height / 2); sgp_translate(width / 2, height / 2);
sgp_scale_at(zoom, zoom, 0.0f, 0.0f); sgp_scale_at(zoom, -zoom, 0.0f, 0.0f);
// camera go to player // camera go to player
@ -411,10 +424,6 @@ static void frame(void)
struct Box *b = &g->boxes[ii]; struct Box *b = &g->boxes[ii];
sgp_set_color(0.5f, 0.5f, 0.5f, 1.0f); sgp_set_color(0.5f, 0.5f, 0.5f, 1.0f);
drawbox(grid_pos(g), grid_rotation(g), box_pos(b), b->damage, true); drawbox(grid_pos(g), grid_rotation(g), box_pos(b), b->damage, true);
if (b->damage > 0.01f)
{
Log("Damage: %f\n", b->damage);
}
} }
sgp_set_color(1.0f, 0.0f, 0.0f, 1.0f); sgp_set_color(1.0f, 0.0f, 0.0f, 1.0f);
V2 vel = grid_vel(&gs.grids[i]); V2 vel = grid_vel(&gs.grids[i]);
@ -423,12 +432,13 @@ static void frame(void)
} }
} }
set_color(RED);
sgp_draw_filled_rect(1.0f, 0.5f, 0.3f, 0.3f);
// gold target // gold target
set_color(GOLD); set_color(GOLD);
sgp_draw_filled_rect(gs.goldpos.x, gs.goldpos.y, 0.1f, 0.1f); sgp_draw_filled_rect(gs.goldpos.x, gs.goldpos.y, 0.1f, 0.1f);
sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f); sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f);
dbg_drawall(); dbg_drawall();

@ -73,6 +73,7 @@ struct GameState
V2 movement; V2 movement;
bool inhabit; bool inhabit;
// if grid_index != -1, this is in local coordinates to the grid
V2 build; // @Robust this is messy, clean up? V2 build; // @Robust this is messy, clean up?
bool dobuild; bool dobuild;
int grid_index; int grid_index;
@ -103,6 +104,8 @@ struct ClientToServer
{ {
V2 movement; V2 movement;
bool inhabit; bool inhabit;
// if grid_index != -1, this is in local coordinates to the grid
V2 build; V2 build;
bool dobuild; bool dobuild;
int grid_index; int grid_index;
@ -127,6 +130,8 @@ void grid_new(struct Grid *to_modify, struct GameState *gs, V2 pos);
V2 grid_com(struct Grid *grid); V2 grid_com(struct Grid *grid);
V2 grid_pos(struct Grid *grid); V2 grid_pos(struct Grid *grid);
V2 grid_vel(struct Grid *grid); V2 grid_vel(struct Grid *grid);
V2 grid_local_to_world(struct Grid *grid, V2 local);
V2 grid_world_to_local(struct Grid *grid, V2 world);
V2 grid_snapped_box_pos(struct Grid *grid, V2 world); // returns the snapped pos in world coords V2 grid_snapped_box_pos(struct Grid *grid, V2 world); // returns the snapped pos in world coords
float grid_rotation(struct Grid *grid); float grid_rotation(struct Grid *grid);
float grid_angular_velocity(struct Grid *grid); float grid_angular_velocity(struct Grid *grid);
@ -268,4 +273,5 @@ static void set_color(Color c)
} }
#define WHITE (Color){.r=1.0f,.g=1.0f,.b=1.0f,.a=1.0f} #define WHITE (Color){.r=1.0f,.g=1.0f,.b=1.0f,.a=1.0f}
#define RED (Color){.r=1.0f,.g=0.0f,.b=0.0f,.a=1.0f}
#define GOLD colhex(255, 215, 0) #define GOLD colhex(255, 215, 0)
Loading…
Cancel
Save