diff --git a/src/core/bridge.c b/src/core/bridge.c
index 02a9840..35f2304 100644
--- a/src/core/bridge.c
+++ b/src/core/bridge.c
@@ -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) {
@@ -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);
}
diff --git a/src/core/keyboard.c b/src/core/keyboard.c
index c40ca75..eceb60a 100644
--- a/src/core/keyboard.c
+++ b/src/core/keyboard.c
@@ -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; }
diff --git a/src/core/keyboard.h b/src/core/keyboard.h
index 6d01db1..7543a2e 100644
--- a/src/core/keyboard.h
+++ b/src/core/keyboard.h
@@ -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;
};
diff --git a/src/core/view.c b/src/core/view.c
index 4a5b82e..e91ae2f 100644
--- a/src/core/view.c
+++ b/src/core/view.c
@@ -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;
+}
diff --git a/src/core/view.h b/src/core/view.h
index b7f02ea..59e732b 100644
--- a/src/core/view.h
+++ b/src/core/view.h
@@ -1,6 +1,18 @@
#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);
@@ -8,5 +20,9 @@
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);
diff --git a/src/entities/player.c b/src/entities/player.c
new file mode 100644
index 0000000..08dd105
--- /dev/null
+++ b/src/entities/player.c
@@ -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});
+}
diff --git a/src/entities/player.h b/src/entities/player.h
index b90c283..b5edcce 100644
--- a/src/entities/player.h
+++ b/src/entities/player.h
@@ -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 }
@@ -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);
diff --git a/src/screen/game.c b/src/screen/game.c
index fc4c294..a521d38 100644
--- a/src/screen/game.c
+++ b/src/screen/game.c
@@ -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);
diff --git a/src/terrain/chunk.c b/src/terrain/chunk.c
index bd4b377..0bea7d0 100644
--- a/src/terrain/chunk.c
+++ b/src/terrain/chunk.c
@@ -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;
diff --git a/wispy-c.vcxproj b/wispy-c.vcxproj
index a279cfc..29bb8da 100644
--- a/wispy-c.vcxproj
+++ b/wispy-c.vcxproj
@@ -331,6 +331,7 @@
+