Some kind of physics? Something wrong...

main
Cameron Murphy Reikes 2 years ago
parent 05d805f03d
commit 23c2e18a70

@ -28,6 +28,7 @@
"stdbool.h": "c", "stdbool.h": "c",
"sokol_time.h": "c", "sokol_time.h": "c",
"enet.h": "c", "enet.h": "c",
"types.h": "c" "types.h": "c",
"cmath": "c"
} }
} }

@ -1,7 +1,23 @@
#include "types.h" #include "types.h"
#include <stdlib.h> // malloc
#include <stdio.h>
void __assert(bool cond, const char * file, int line, const char * cond_string)
{
if(!cond)
{
fprintf(stderr, "%s:%d | Assertion %s failed\n", file, line, cond_string);
}
}
#define assert(condition) __assert(condition, __FILE__, __LINE__, #condition)
// do not use any global variables to process gamestate // do not use any global variables to process gamestate
// super try not to depend on external libraries like enet or sokol to keep build process simple,
// gamestate its own portable submodule. If need to link to other stuff document here:
static void integrate_acceleration(struct Body *body, float dt) static void integrate_acceleration(struct Body *body, float dt)
{ {
// position // position
@ -21,8 +37,31 @@ static void integrate_acceleration(struct Body *body, float dt)
} }
} }
static void modify_interval(struct Body *from, float *from_interval, V2 center, V2 axis)
{
V2 points[4] = {
V2add(from->position, V2rotate((V2){.x = 0.5f, .y = -0.5f}, from->rotation)), // upper right
V2add(from->position, V2rotate((V2){.x = 0.5f, .y = 0.5f}, from->rotation)), // bottom right
V2add(from->position, V2rotate((V2){.x = -0.5f, .y = 0.5f}, from->rotation)), // lower left
V2add(from->position, V2rotate((V2){.x = -0.5f, .y = -0.5f}, from->rotation)), // upper left
};
for (int point_i = 0; point_i < 4; point_i++)
{
float value = V2projectvalue(V2sub(points[point_i], center), axis);
if (value > from_interval[1])
{
from_interval[1] = value;
}
if (value < from_interval[0])
{
from_interval[0] = value;
}
}
}
void process(struct GameState *gs, float dt) void process(struct GameState *gs, float dt)
{ {
int num_bodies = gs->num_boxes;
for (int i = 0; i < MAX_PLAYERS; i++) for (int i = 0; i < MAX_PLAYERS; i++)
{ {
struct Player *p = &gs->players[i]; struct Player *p = &gs->players[i];
@ -30,13 +69,63 @@ void process(struct GameState *gs, float dt)
continue; continue;
p->body.acceleration = V2scale(p->input, 5.0f); p->body.acceleration = V2scale(p->input, 5.0f);
p->body.angular_acceleration = p->input.x * 10.0f; p->body.angular_acceleration = p->input.x * 10.0f;
integrate_acceleration(&p->body, dt); num_bodies += 1;
}
// @Robust do this without malloc
struct Body **bodies = malloc(sizeof *bodies * num_bodies);
int cur_body_index = 0;
for (int i = 0; i < MAX_PLAYERS; i++)
{
struct Player *p = &gs->players[i];
if (!p->connected)
continue;
bodies[cur_body_index] = &p->body;
cur_body_index++;
} }
for (int i = 0; i < gs->num_boxes; i++) for (int i = 0; i < gs->num_boxes; i++)
{ {
integrate_acceleration(&gs->boxes[i].body, dt); bodies[cur_body_index] = &gs->boxes[i].body;
cur_body_index++;
}
assert(cur_body_index == num_bodies);
for (int i = 0; i < num_bodies; i++)
{
struct Body *body = bodies[i];
integrate_acceleration(body, dt);
}
// @Robust handle when bodies are overlapping (even perfectly)
for (int i = 0; i < num_bodies; i++)
{
for (int ii = 0; ii < num_bodies; ii++)
{
if (ii == i)
continue;
struct Body *from = bodies[i];
struct Body *to = bodies[ii];
V2 axis = V2normalize(V2sub(to->position, from->position));
V2 center = V2scale(V2add(to->position, from->position), 0.5f);
float from_interval[2] = {1000.0f, -1000.0f};
float to_interval[2] = {1000.0f, -1000.0f};
modify_interval(from, from_interval, center, axis);
modify_interval(to, to_interval, center, axis);
assert(from_interval[0] < from_interval[1]);
assert(to_interval[0] < to_interval[1]);
if (to_interval[0] < from_interval[1]) // intersecting
{
from->position = V2add(from->position, V2scale(axis, -0.5f));
to->position = V2add(from->position, V2scale(axis, 0.5f));
}
}
} }
free(bodies);
} }

@ -92,7 +92,11 @@ void server(void *data)
else else
{ {
event.peer->data = (void *)player_slot; event.peer->data = (void *)player_slot;
gs.players[player_slot] = (struct Player){ 0 }; gs.players[player_slot] = (struct Player){ .body.position = (V2){
.x = 0.0f,
.y = 1.0f*(float)player_slot,
}};
gs.players[player_slot].body.old_position = gs.players[player_slot].body.position;
gs.players[player_slot].connected = true; gs.players[player_slot].connected = true;
} }

@ -1,5 +1,8 @@
#pragma once #pragma once
// @Robust remove this include somehow, needed for sqrt and cos
#include <math.h>
// including headers from headers bad // including headers from headers bad
#ifndef SOKOL_GP_INCLUDED #ifndef SOKOL_GP_INCLUDED
@ -25,7 +28,9 @@ typedef sgp_vec2 sgp_point;
typedef sgp_vec2 V2; typedef sgp_vec2 V2;
typedef sgp_point P2; typedef sgp_point P2;
#define Log(...) fprintf(stdout, "%s:%d | ", __FILE__, __LINE__); fprintf(stdout, __VA_ARGS__) #define Log(...) \
fprintf(stdout, "%s:%d | ", __FILE__, __LINE__); \
fprintf(stdout, __VA_ARGS__)
#define MAX_BOXES 32 #define MAX_BOXES 32
#define MAX_PLAYERS 4 #define MAX_PLAYERS 4
#define BOX_SIZE 0.5f #define BOX_SIZE 0.5f
@ -96,6 +101,40 @@ static V2 V2scale(V2 a, float f)
}; };
} }
static float V2length(V2 v)
{
return sqrtf(v.x * v.x + v.y * v.y);
}
static V2 V2normalize(V2 v)
{
return V2scale(v, 1.0f / V2length(v));
}
static float V2dot(V2 a, V2 b)
{
return a.x * b.x + a.y * b.y;
}
static float V2projectvalue(V2 vec, V2 onto)
{
float length_onto = V2length(onto);
return V2dot(vec, onto) / (length_onto * length_onto);
}
static V2 V2project(V2 vec, V2 onto)
{
return V2scale(onto, V2projectvalue(vec, onto));
}
static V2 V2rotate(V2 vec, float theta)
{
return (V2){
.x = vec.x * cos(theta) - vec.y * sin(theta),
.y = vec.x * sin(theta) + vec.y * cos(theta),
};
}
static V2 V2sub(V2 a, V2 b) static V2 V2sub(V2 a, V2 b)
{ {
return (V2){ return (V2){

Loading…
Cancel
Save