From 821c98e87637df7ba96296e801ff595fdd85b5d2 Mon Sep 17 00:00:00 2001 From: Cameron Reikes Date: Wed, 26 Oct 2022 14:20:59 -0700 Subject: [PATCH] Show glow on thruster usage --- gamestate.c | 29 ++++++++---- loaded/thruster.png | Bin 720 -> 5508 bytes loaded/thrusterburn.png | Bin 0 -> 6013 bytes main.c | 100 +++++++++++++++++++++++++++++++--------- server.c | 6 ++- types.h | 10 ++++ 6 files changed, 111 insertions(+), 34 deletions(-) create mode 100644 loaded/thrusterburn.png diff --git a/gamestate.c b/gamestate.c index 4b8d30b..bdda240 100644 --- a/gamestate.c +++ b/gamestate.c @@ -313,6 +313,8 @@ void ser_grid(char **out, struct Grid *g) ser_float(out, grid_rotation(g)); ser_float(out, grid_angular_velocity(g)); + ser_float(out, g->total_energy_capacity); + for (int i = 0; i < MAX_BOXES_PER_GRID; i++) { bool exists = g->boxes[i].shape != NULL; @@ -350,6 +352,8 @@ void des_grid(char **in, struct Grid *g, struct GameState *gs) cpBodySetAngle(g->body, rot); cpBodySetAngularVelocity(g->body, angular_vel); + des_float(in, &g->total_energy_capacity); + for (int i = 0; i < MAX_BOXES_PER_GRID; i++) { bool exists = false; @@ -543,15 +547,6 @@ struct Grid *closest_to_point_in_radius(struct GameState *gs, V2 point, float ra return NULL; } -// for random generation -static float hash11(float p) -{ - p = fract(p * .1031); - p *= p + 33.33; - p *= p + p; - return fract(p); -} - V2 thruster_direction(struct Box *box) { assert(box->type == BoxThruster); @@ -676,6 +671,8 @@ void process(struct GameState *gs, float dt) // set thruster thrust from movement { + float energy_available = g->total_energy_capacity; + V2 target_direction = {0}; if (V2length(p->input.movement) > 0.0f) { @@ -690,7 +687,13 @@ void process(struct GameState *gs, float dt) float wanted_thrust = -V2dot(target_direction, thruster_direction(&g->boxes[ii])); wanted_thrust = clamp01(wanted_thrust); - g->boxes[ii].thrust = wanted_thrust; + float needed_energy = wanted_thrust * THRUSTER_ENERGY_USED_PER_SECOND * dt; + energy_available -= needed_energy; + + if(energy_available > 0.0f) + g->boxes[ii].thrust = wanted_thrust; + else + g->boxes[ii].thrust = 0.0f; } } // cpBodyApplyForceAtWorldPoint(g->body, v2_to_cp(V2scale(p->input.movement, 5.0f)), v2_to_cp(grid_com(g))); @@ -814,6 +817,12 @@ void process(struct GameState *gs, float dt) } } } + + gs->grids[i].total_energy_capacity = 0.0f; + for(int ii = 0; ii < batteries_len; ii++) + { + gs->grids[i].total_energy_capacity += 1.0f - batteries[ii]->energy_used; + } } cpSpaceStep(gs->space, dt); diff --git a/loaded/thruster.png b/loaded/thruster.png index f1c69ce95a981eab73d457631a1f52a8c4657b29..2a6851b3bd0bde9396bf3fe2dc0fc663ced8df98 100644 GIT binary patch literal 5508 zcmeHKcT^ME8V?|_vVchMi~$vOQ%NIBM0zt2Vjux5OePbIq?rsPvKG`;VMPTV*b9mc zR1_?Ty3#Exf}pG-7A&h+5M>oyAL^R~3!b;82rE zORQ&ENl2UVj&~hgfJ{u;G!Y`c!*+_OELMyAemXd%iJVK%>%s>#G_PJZUUFvBYgJc7mp2%hxc78e~6J=RR9+f zP2Z1jhSv!jv)2LGSnkeq;kWVF z=;8*)X>~hBZnQZay*`(_yQxFGZh>Wjisx&0Jf^(SZdPEPbyO*@3R|=9;P%K>RO;of z$cwbA^S@^&N=xe7nVQZS1FXGxRzFg4O!7AUeJ1sALh<=4>m8$i2Q2Pzz)a}&oRy)Q%jLH3M&VS)3Zf3z8&rq(CQ68ful}@C)|khFur-UrfKV0&l;qt~`ASpVnvL{%~HcVK0AV z-hI`rEZZMl=*>}tPEKO5>-NN|{IxfnU%iRCdSKtZ;*Pl?XJ4<%b}2H;+9=yPx1*s_ z#7+`6pWvUiJ30EfXMM9n%b;K7-VM{& zw&gUm;Md#wwd5QUO$c_2Oc>ce*7$Mnlr7JHg;DFXQPOnl}$FO5fviR)WziUmLW$p|9NSMy`EHRDF% zGM7yrSKr0-tUSE<&C7Pl14bF8bHdiV=SpF$f5n4UagXVVTN6s6oh*&5yDj^+Mc^ko zk6#a3K0aNObZp(d>VUKJ7^UwGp7x09p4{nj!e9)RNrHkn5kWy8yC&KzH!sLzh1XAU zZJd>~i(6`$o_jZU`(t4MFL?9LUqTLXuA3cTuAlzKnC+Zz>kw9Zw5#i^u)Vf1fp5wW zuo}e7MO0iQ&-(p3+r$Q~^2Qp?fV-v_qbRPkElzdi@TSEyLV>i(iLYmkp5nM*edFG9 z=D56>O*LurZ`RjeJ?Y(|@*jBEUHGSok)PoU*UQMiv`e)am#;8-ZB_^(3bI?W&mt#) z7oJzguDH!`koEU9dHh z-@74xk^j3bs@t988)u-ew{!{m8WXUmG9iTw4~i5*7_XHn(bpUX0`q075uL zB4=THPgY|AiHL>eQ`tneG6Gz>!IeMy8!|h zRx8p}5FC;Y%Ms7v5F+T4zcNiF)u$tZ2(T2Ep{8ndRMHnihDESBpFDIFq)22+y%$RM z7nX=b{F$sTV$*5#=?o79b^nC>h4shW^~R_bo6QVXKxw-0B7#|1-S|wA0+NWBL$_2h zM4~dNIH4~E!cizRU!0Hz5^<0a6^n&FWROM~1{EP!BcL3Dbx9~?zQ z@xg&~^bTT(7(NU!#Gp`o^iU#*8LCjpKy*4KGB5=uDCH@7g^qA$04IWlCF6;oB^)V; zh*1Z04M^l7g+~2Z#goY3X$Yv}lSHG@7$hG$jYcOiD8AIsM)9ypjn<+Ll|;n*ko6kf z#4yoxP-;P4rJ?|OIhqYKNCkt4Ld8=kq%5p1C_v}=NzFzVln6w?U=V>(P$HSkBoUcp z8jnO~Qhd=H9Ffi>4zpK?B;tAh%UZX50KcJ050|LX@#pD9Lu+apJa_16=us-sFD3xc zFAF9J4W*z4)8V1%La~Na&}>ki0;B!oL&1KOOa7)9Xb{Mt&_!e%9j1zL6sicqF~mX; z=j%i9VZd}Bp^tEgyie$Ag&5I*DmWkofZ%Br=F0>O8KDELRe4%6ilb;Xs@J|i_0N)1r zDt^Dw^^LBtV&JQczg5>ay1t5muQL8tUH><_%swBcU^%)2(x68rd5zNn^q6HLj0y|J z1nIs%Ih}|@B_oyL32F=m@2R^Cw7dM%QK2ak!45HfVCHN?a-P1#{by9*RUbl%kM(tip zsTZ6~OJjezYM@i2AW(QZ=D-QD(Jfy$^ssr!Flx*-UiCCITuekrbZ}W<@{<1mi-k?S delta 633 zcmV-<0*3vBE6@dyBYy#eX+uL$Nkc;*aB^>EX>4Tx04R}tkv&MmKpe$iQ$;Bi2Md1S zkfFM0K~%(1s#pXIrLEAagUO{|(4-+rad8w}3l4rPRvlcNb#-tR1i=pwM<*vm7b)?7 zNufoI2gm(*ckglc4iM^PrkWiSfT~$WG8Ppx*;TRY6#)#QAAe(j#7sS&T1>-peBHyx z*SiSM@;>+H=uvVe1AHR!9McVpc!PLm)6zNb6Ngw)Qi#uq#|^q5@gvt|m)|%S92R(H z$VeyWi9^IW<^6Ko+b_}sz&)j#$|=`7H73wWzBo?7Y1|MN{Z_=hY`aP;z&S* zj4Dbf!$O2sjeisqN!pKk_=g;Sf?P7WN?_zzKm{r!#}EDozq>W_Q!(?&j>~?v>o!y^KyI#9%3vwo5xh-lHM;ZPzK6qh37D>!#ivhu)C|{(y55K^pw7 zpaCrkNPx2f6!0=n#WU-+!vb7jR0nF|t-z>H$OT0UaDqVr32-d0odqUf0w!Pr{wqGA z2o>vqggyu=4O5BMIpNb087tGWD^6=9iw}2NLn$aAA%YU%l&KcrTFum#Q}ucPpO#M{ T^S@8s00000NkvXXu0mjf!O0dF diff --git a/loaded/thrusterburn.png b/loaded/thrusterburn.png new file mode 100644 index 0000000000000000000000000000000000000000..d1e39643f70b993b4c24ee9e9d08e793363a17ee GIT binary patch literal 6013 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 0.0f) - { - sgp_set_color(0.5f, 0.1f, 0.1f, damage); - sgp_draw_filled_rect(boxpos.x - halfbox, boxpos.y - halfbox, BOX_SIZE, BOX_SIZE); - } +// sgp_set_image(0, boxinfo(type).image); +// sgp_rotate_at(rotangle(rotation), boxpos.x, boxpos.y); + +// sgp_reset_image(0); + +// if (damage > 0.0f) +// { +// sgp_set_color(0.5f, 0.1f, 0.1f, damage); + +// } + +// sgp_pop_transform(); +// } - sgp_pop_transform(); +static void draw_color_rect_centered(V2 center, float size) +{ + float halfbox = size / 2.0f; + + sgp_draw_filled_rect(center.x - halfbox, center.y - halfbox, size, size); +} + +static void draw_texture_centered(V2 center, float size) +{ + float halfbox = size / 2.0f; + sgp_draw_textured_rect(center.x - halfbox, center.y - halfbox, BOX_SIZE, BOX_SIZE); } static void draw_circle(V2 point, float radius) @@ -435,12 +450,12 @@ static void frame(void) }; cur_input_frame.movement = input; cur_input_frame.inhabit = keypressed[SAPP_KEYCODE_G].pressed; - cur_input_frame.dobuild = mouse_pressed; - cur_input_frame.grid_index = grid_index; - if (cur_input_frame.dobuild) + if (mouse_pressed && cur_editing_boxtype != -1) { + cur_input_frame.dobuild = mouse_pressed; cur_input_frame.build_type = cur_editing_boxtype; cur_input_frame.build_rotation = cur_editing_rotation; + cur_input_frame.grid_index = grid_index; if (grid_index != -1) { cur_input_frame.build = grid_world_to_local(&gs.grids[cur_input_frame.grid_index], build_preview.pos); @@ -535,9 +550,19 @@ static void frame(void) } // building preview - if(cur_editing_boxtype != -1){ + if (cur_editing_boxtype != -1) + { sgp_set_color(0.5f, 0.5f, 0.5f, (sin(time * 9.0f) + 1.0) / 3.0f + 0.2); - drawbox(build_preview.pos, build_preview.grid_rotation, 0.0f, cur_editing_boxtype, cur_editing_rotation); + + sgp_push_transform(); + + sgp_set_image(0, boxinfo(cur_editing_boxtype).image); + sgp_rotate_at(build_preview.grid_rotation + rotangle(cur_editing_rotation), build_preview.pos.x, build_preview.pos.y); + draw_texture_centered(build_preview.pos, BOX_SIZE); + // drawbox(build_preview.pos, build_preview.grid_rotation, 0.0f, cur_editing_boxtype, cur_editing_rotation); + sgp_reset_image(0); + + sgp_pop_transform(); } // grids @@ -560,7 +585,7 @@ static void frame(void) dbg_line(box_pos(b), V2add(box_pos(b), V2scale(thruster_force(b), -1.0f))); } } - if(b->type == BoxBattery) + if (b->type == BoxBattery) { float cur_alpha = sgp_get_color().a; Color from = WHITE; @@ -568,7 +593,36 @@ static void frame(void) Color result = Collerp(from, to, b->energy_used); sgp_set_color(result.r, result.g, result.b, cur_alpha); } - drawbox(box_pos(b), grid_rotation(g), b->damage, b->type, b->rotation); + sgp_push_transform(); + + sgp_rotate_at(grid_rotation(g) + rotangle(b->rotation), box_pos(b).x, box_pos(b).y); + + if (b->type == BoxThruster) + { + sgp_push_transform(); + sgp_set_color(1.0f, 1.0f, 1.0f, 1.0f); + sgp_set_image(0, image_thrusterburn); + // float scaling = 1.0 + (hash11(time*3.0)/2.0)*lerp(0.0, 0.07, b->thrust); + // printf("%f\n", b->thrust); + float scaling = 0.95 + lerp(0.0, 0.3,b->thrust); + // float scaling = 1.1; + // sgp_translate(-(scaling*BOX_SIZE - BOX_SIZE), 0.0); + // sgp_scale(scaling, 1.0); + sgp_scale_at(scaling, 1.0, box_pos(b).x, box_pos(b).y); + draw_texture_centered(box_pos(b), BOX_SIZE); + sgp_reset_image(0); + sgp_pop_transform(); + } + + + sgp_set_image(0, boxinfo(b->type).image); + draw_texture_centered(box_pos(b), BOX_SIZE); + sgp_reset_image(0); + + sgp_set_color(0.5f, 0.1f, 0.1f, b->damage); + draw_color_rect_centered(box_pos(b), BOX_SIZE); + + sgp_pop_transform(); } sgp_set_color(1.0f, 0.0f, 0.0f, 1.0f); V2 vel = grid_vel(&gs.grids[i]); @@ -650,7 +704,7 @@ void event(const sapp_event *e) } int key_num = e->key_code - SAPP_KEYCODE_0; int target_box = key_num - 1; - if(target_box < BoxLast) + if (target_box < BoxLast) { cur_editing_boxtype = target_box; } diff --git a/server.c b/server.c index b0d8ad7..47e928d 100644 --- a/server.c +++ b/server.c @@ -21,13 +21,17 @@ void server(void *data) box_new(&gs.grids[0].boxes[0], &gs, &gs.grids[0], (V2){0}); box_new(&gs.grids[0].boxes[1], &gs, &gs.grids[0], (V2){0, BOX_SIZE}); box_new(&gs.grids[0].boxes[2], &gs, &gs.grids[0], (V2){0, BOX_SIZE*2.0}); + gs.grids[0].boxes[2].type = BoxBattery; + box_new(&gs.grids[0].boxes[3], &gs, &gs.grids[0], (V2){BOX_SIZE, BOX_SIZE*2.0}); gs.grids[0].boxes[3].type = BoxThruster; gs.grids[0].boxes[3].rotation = Right; + box_new(&gs.grids[0].boxes[4], &gs, &gs.grids[0], (V2){0, BOX_SIZE*3.0}); gs.grids[0].boxes[4].type = BoxThruster; gs.grids[0].boxes[4].rotation = Up; + grid_new(&gs.grids[1], &gs, (V2){.x = -BOX_SIZE*1.5, .y = 0.0}); box_new(&gs.grids[1].boxes[0], &gs, &gs.grids[1], (V2){0}); @@ -158,7 +162,6 @@ void server(void *data) continue; // don't reprocess inputs already processed struct InputFrame cur_input = received.inputs[i]; gs.players[player_slot].input.movement = cur_input.movement; - gs.players[player_slot].input.grid_index = cur_input.grid_index; // for these "event" inputs, only modify the current input if the event is true. // while processing the gamestate, will mark it as false once processed. This @@ -169,6 +172,7 @@ void server(void *data) } if (cur_input.dobuild) { + gs.players[player_slot].input.grid_index = cur_input.grid_index; gs.players[player_slot].input.build = cur_input.build; gs.players[player_slot].input.dobuild = cur_input.dobuild; gs.players[player_slot].input.build_type = cur_input.build_type; diff --git a/types.h b/types.h index 2f57e85..c09f690 100644 --- a/types.h +++ b/types.h @@ -126,6 +126,7 @@ struct GameState struct Grid { cpBody *body; + float total_energy_capacity; // updated every frame by thruster logic struct Box { @@ -338,6 +339,15 @@ static V2 V2lerp(V2 a, V2 b, float factor) return to_return; } +// for random generation +static float hash11(float p) +{ + p = fract(p * .1031); + p *= p + 33.33; + p *= p + p; + return fract(p); +} + typedef struct Color { float r, g, b, a;