Skip to content

Commit

Permalink
physics update (todo)
Browse files Browse the repository at this point in the history
  • Loading branch information
julesgrc0 committed Feb 8, 2024
1 parent 9f9c726 commit b08e597
Show file tree
Hide file tree
Showing 10 changed files with 157 additions and 81 deletions.
104 changes: 44 additions & 60 deletions src/core/bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ w_bridge *create_bridge() {
td->player->position = (Vector2){
.x = (td->chunk_group->position + CHUNK_GROUP_MID_LEN) * CHUNK_W * CUBE_W,
.y = CHUNK_MID_H * CUBE_H};
td->player->collision = (w_collision){0};

td->camera = malloc(sizeof(Camera2D));
if (td->camera == NULL) {
Expand Down Expand Up @@ -95,79 +96,62 @@ void destroy_bridge(w_bridge *td) {
}

void physics_update(w_bridge *td) {
if (td->keyboard->left) {
if (td->player->src.width > 0) {
td->player->src.width = -td->player->src.width;
}
td->player->velocity.x -= 1;
} else if (td->keyboard->right) {
if (td->player->src.width < 0) {
td->player->src.width = -td->player->src.width;
}
td->player->velocity.x += 1;
}

if (td->keyboard->left || td->keyboard->right || !td->player->is_onground) {
update_player_input(td->player, td->keyboard);

if (!td->player->is_onground) {
td->player->velocity.y += 1;
} else {
td->player->velocity.y = 1;
td->player->is_onground = false;
}
if (td->player->velocity.x != 0 || td->player->velocity.y != 0) {

/*
td->player->velocity = Vector2Normalize(td->player->velocity);
td->player->position = Vector2Add(
*/
td->player->velocity.x = Clamp(
td->player->velocity.x, -MAX_PLAYER_VELOCITY_X, MAX_PLAYER_VELOCITY_X);
td->player->velocity.y = Clamp(
td->player->velocity.y, -MAX_PLAYER_VELOCITY_Y, MAX_PLAYER_VELOCITY_Y);

Vector2 next_position = Vector2Add(
td->player->position,
Vector2Scale(td->player->velocity, PLAYER_SPEED * PHYSICS_TICK));
td->player->velocity = Vector2Scale(td->player->velocity, PLAYER_FRICTION);

Rectangle player_rect = (Rectangle){.x = next_position.x,
.y = next_position.y,
.width = td->player->dst.width,
.height = td->player->dst.height};

td->player->collision = (w_collision){0};
unsigned int count = 0;
for (size_t i = 0; i < td->chunk_view->len; i++) {
Rectangle block_rect = td->chunk_view->blocks[i].dst;

if (!td->player->is_onground) {
Rectangle player_rect = {td->player->position.x, td->player->position.y,
td->player->dst.width, td->player->dst.height};
for (size_t i = 0; i < td->chunk_view->len; i++) {

Rectangle block_rect = td->chunk_view->blocks[i].dst;
if (CheckCollisionRecs(player_rect, block_rect)) {
/*
td->player->position = Vector2Subtract(
td->player->position,
Vector2Scale(td->player->velocity, PLAYER_SPEED * PHYSICS_TICK));
*/

if (td->player->position.y + td->player->dst.height >= block_rect.y) {
td->player->is_onground = true;
td->player->position.y = block_rect.y - td->player->dst.height;
td->player->velocity.y = 0;
}
if (td->player->position.x + td->player->dst.width >= block_rect.x &&
td->player->position.x <= block_rect.x + block_rect.width) {
td->player->velocity.x = 0;
}
if (CheckCollisionRecs(player_rect, block_rect)) {

// TODO: implement collision detection
//
//
// check if the collision is on left:
// if left -> set stop on left
// => stop velocity x
// => set collision at left(true) and set right(false)
// => set player position to be the right side of the block

// etc...

count++;
if (count >= 3) {
break;
}
}
}

td->camera_target = center_camera_on_object(
td->camera, (Rectangle){.x = td->player->position.x,
.y = td->player->position.y,
.width = td->player->dst.width,
.height = td->player->dst.height});
}

td->player->animation += PHYSICS_TICK;
td->player->velocity = Vector2Scale(td->player->velocity, 0.9f);
if (abs(td->player->velocity.x) > 0.1f || td->keyboard->key != 0) {
if (td->player->animation > PHYSICS_TICK * 2) {
td->player->animation = 0;
td->player->state = (td->player->state == P_WALK_1) ? P_WALK_2 : P_WALK_1;
}
} else {
if (td->player->animation > PHYSICS_TICK * 12) {
td->player->animation = 0;
td->player->state = (td->player->state == P_IDLE_1) ? P_IDLE_2 : P_IDLE_1;
if (td->player->collision.all == 0) {
td->player->position = next_position;
}
td->camera_target = get_camera_target_player(td->player, td->camera);

LOG("velocity: %f, %f", td->player->velocity.x, td->player->velocity.y);
}

animate_player(td->player, PHYSICS_TICK, td->keyboard->key != 0);
clear_keyboard(td->keyboard);
}

Expand Down
3 changes: 1 addition & 2 deletions src/core/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
void update_keyboard(w_keyboard *kb) {
kb->left = IsKeyDown(KEY_LEFT);
kb->right = IsKeyDown(KEY_RIGHT);
kb->space = IsKeyDown(KEY_SPACE);
kb->shift = IsKeyDown(KEY_LEFT_SHIFT);
kb->jump = IsKeyDown(KEY_SPACE);
}

void clear_keyboard(w_keyboard *kb) { kb->key = 0; }
3 changes: 1 addition & 2 deletions src/core/keyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
#pragma pack(push, 1)
typedef union w_keyboard {
struct {
unsigned int space : 1;
unsigned int shift : 1;
unsigned int jump : 1;
unsigned int left : 1;
unsigned int right : 1;
};
Expand Down
34 changes: 34 additions & 0 deletions src/core/view.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,37 @@ void smooth_rect(Rectangle *box, Rectangle target, float move) {
smooth_float(box->x, target.x, move);
smooth_float(box->y, target.y, move);
}

Vector2 get_collision_resolution(w_collision *bc, Rectangle self_rect,
Rectangle other_rect) {
Vector2 resolution = VEC_ZERO;
float overlapX = 0.0f, overlapY = 0.0f;

bc->left = self_rect.x < other_rect.x + other_rect.width &&
self_rect.x + self_rect.width > other_rect.x;
bc->right = self_rect.x + self_rect.width > other_rect.x &&
self_rect.x < other_rect.x;
bc->top = self_rect.y < other_rect.y + other_rect.height &&
self_rect.y + self_rect.height > other_rect.y;
bc->bottom = self_rect.y + self_rect.height > other_rect.y &&
self_rect.y < other_rect.y;

if (bc->left && !bc->right) {
overlapX = other_rect.x + other_rect.width - self_rect.x;
} else if (!bc->left && bc->right) {
overlapX = other_rect.x - (self_rect.x + self_rect.width);
}
if (bc->top && !bc->bottom) {
overlapY = other_rect.y + other_rect.height - self_rect.y;
} else if (!bc->top && bc->bottom) {
overlapY = other_rect.y - (self_rect.y + self_rect.height);
}

if (fabsf(overlapX) < fabsf(overlapY)) {
resolution.x = overlapX;
} else {
resolution.y = overlapY;
}

return resolution;
}
16 changes: 16 additions & 0 deletions src/core/view.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
#pragma once
#include "../stdafx.h"

#pragma pack(push, 1)
typedef struct w_collision {
struct {
bool left : 1;
bool right : 1;
bool top : 1;
bool bottom : 1;
};
uint8_t all;
} w_collision;
#pragma pack(pop)

#define smooth_float(current, target, speed) \
current = (current < target) ? fmin(current + speed, target) \
: fmax(current - speed, target);

Vector2 center_camera_on_object(Camera2D *camera, Rectangle box);
Vector2 center_object_on_camera(Rectangle box, Camera2D *camera);
Rectangle get_camera_view(Camera2D *camera);

void smooth_vec(Vector2 *position, Vector2 target, float move);
void smooth_rect(Rectangle *box, Rectangle target, float move);

Vector2 get_collision_resolution(w_collision *bc, Rectangle box,
Rectangle target);
46 changes: 46 additions & 0 deletions src/entities/player.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "player.h"

void animate_player(w_player *player, float dt, bool should_walk) {
player->animation += dt;
if (abs(player->velocity.x) > 0.01f || should_walk) {
if (player->animation > dt * 2) {
player->animation = 0;
player->state = (player->state == P_WALK_1) ? P_WALK_2 : P_WALK_1;
}
} else {
if (player->animation > dt * 12) {
player->animation = 0;
player->state = (player->state == P_IDLE_1) ? P_IDLE_2 : P_IDLE_1;
}
}
}

void update_player_input(w_player *player, w_keyboard *keyboard) {
if (keyboard->left && !player->collision.left) {
if (player->src.width > 0) {
player->src.width = -player->src.width;
}
player->velocity.x -= 1;
} else if (keyboard->right && !player->collision.right) {
if (player->src.width < 0) {
player->src.width = -player->src.width;
}
player->velocity.x += 1;
}

/*
if (keyboard->jump && player->collision.bottom) {
player->velocity.y -= 10;
} else if (!player->collision.bottom) {
player->velocity.y += 1;
}
*/
}

Vector2 get_camera_target_player(w_player *player, Camera2D *camera) {
return center_camera_on_object(camera,
(Rectangle){.x = player->position.x,
.y = player->position.y,
.width = player->dst.width,
.height = player->dst.height});
}
14 changes: 12 additions & 2 deletions src/entities/player.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
#pragma once
#include "../core/keyboard.h"
#include "../core/state.h"
#include "../core/view.h"
#include "../stdafx.h"
#include "../terrain/chunk_view.h"

#define PLAYER_SPEED 1000.f
#define PLAYER_JUMP 10.f
#define PLAYER_FRICTION 0.8f
#define MAX_PLAYER_VELOCITY_X 1.f
#define MAX_PLAYER_VELOCITY_Y 10.f

#define PLAYER_SRC_RECT \
(Rectangle) { 0, 0, 8, 16 }

Expand All @@ -24,7 +31,10 @@ typedef struct w_player {
float delay;
float animation;

unsigned int nearest_y;
bool is_onground;
w_collision collision;
w_playerstate state;
} w_player;

void animate_player(w_player *player, float dt, bool should_walk);
void update_player_input(w_player *player, w_keyboard *keyboard);
Vector2 get_camera_target_player(w_player *player, Camera2D *camera);
15 changes: 1 addition & 14 deletions src/screen/game.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,10 @@ void game_screen(w_state *state) {
BeginMode2D(*(td->camera));
smooth_vec(&td->camera->target, td->camera_target, speed);
for (unsigned int i = 0; i < td->chunk_view->len; i++) {

bool is_current = round(td->player->position.x / FULL_CHUNK_W) ==
round(td->chunk_view->blocks[i].dst.x / FULL_CHUNK_W);
bool is_hover = round(td->player->position.x / CUBE_W) ==
round(td->chunk_view->blocks[i].dst.x / CUBE_W);

DrawTexturePro(block_textures[td->chunk_view->blocks[i].block.type - 1],
td->chunk_view->blocks[i].src,
td->chunk_view->blocks[i].dst, VEC_ZERO, 0,
// WHITE);
is_current ? (is_hover ? BLUE : GREEN)
: (is_hover ? GREEN : WHITE));
td->chunk_view->blocks[i].dst, VEC_ZERO, 0, WHITE);
}
/*
DrawRectangleLines(td->player->position.x, td->player->position.y,
td->player->dst.width, td->player->dst.height, RED);
*/
EndMode2D();
DrawTexturePro(player_textures[td->player->state], td->player->src,
td->player->dst, VEC_ZERO, 0, WHITE);
Expand Down
2 changes: 1 addition & 1 deletion src/terrain/chunk.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void *create_chunk_thread(void *arg)
#endif // _WIN32
{
if (!arg)
return;
return EXIT_FAILURE;
LOG("creating chunk");
w_chunk *chunk = arg;

Expand Down
1 change: 1 addition & 0 deletions wispy-c.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@
<ClCompile Include="src\core\bridge.c" />
<ClCompile Include="src\core\keyboard.c" />
<ClCompile Include="src\core\view.c" />
<ClCompile Include="src\entities\player.c" />
<ClCompile Include="src\screen\game.c" />
<ClCompile Include="src\screen\loading.c" />
<ClCompile Include="src\screen\menu.c" />
Expand Down

0 comments on commit b08e597

Please sign in to comment.