basic smooth movement
This commit is contained in:
+65
-11
@@ -71,6 +71,7 @@ static mat4x4 inverse_view_matrix;
|
|||||||
static mat4x4 projection_matrix;
|
static mat4x4 projection_matrix;
|
||||||
static mat4x4 inverse_projection_matrix;
|
static mat4x4 inverse_projection_matrix;
|
||||||
|
|
||||||
|
static SDL_Time last_time;
|
||||||
static SDL_Time current_time;
|
static SDL_Time current_time;
|
||||||
|
|
||||||
static bool enable_time_tints = true;
|
static bool enable_time_tints = true;
|
||||||
@@ -89,6 +90,8 @@ static bool show_demo_window;
|
|||||||
static bool show_tile_picker;
|
static bool show_tile_picker;
|
||||||
static bool show_settings;
|
static bool show_settings;
|
||||||
|
|
||||||
|
static float character_speed = 4.0f;
|
||||||
|
|
||||||
#define log_error(...) SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, __VA_ARGS__)
|
#define log_error(...) SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, __VA_ARGS__)
|
||||||
|
|
||||||
float remap(float in_a, float in_b, float out_a, float out_b, float v) {
|
float remap(float in_a, float in_b, float out_a, float out_b, float v) {
|
||||||
@@ -204,6 +207,10 @@ static Map current_map;
|
|||||||
|
|
||||||
struct Player {
|
struct Player {
|
||||||
i32vec2 position;
|
i32vec2 position;
|
||||||
|
i32vec2 target_position;
|
||||||
|
|
||||||
|
bool is_moving;
|
||||||
|
vec2 visual_position;
|
||||||
};
|
};
|
||||||
|
|
||||||
static Player player;
|
static Player player;
|
||||||
@@ -219,6 +226,13 @@ struct alignas(16) PerFrame {
|
|||||||
|
|
||||||
static PerFrame per_frame = {};
|
static PerFrame per_frame = {};
|
||||||
|
|
||||||
|
typedef enum : Uint8 {
|
||||||
|
DIR_DOWN,
|
||||||
|
DIR_UP,
|
||||||
|
DIR_LEFT,
|
||||||
|
DIR_RIGHT,
|
||||||
|
} Direction;
|
||||||
|
|
||||||
typedef enum : Uint8 {
|
typedef enum : Uint8 {
|
||||||
TILEKIND_ERROR = 0,
|
TILEKIND_ERROR = 0,
|
||||||
TILEKIND_NONE = 1,
|
TILEKIND_NONE = 1,
|
||||||
@@ -402,6 +416,9 @@ static bool dragging_tile_change;
|
|||||||
static bool dragging_camera_change;
|
static bool dragging_camera_change;
|
||||||
static vec2 drag_start_pos;
|
static vec2 drag_start_pos;
|
||||||
|
|
||||||
|
static bool queued_movement;
|
||||||
|
static Direction queued_movement_direction;
|
||||||
|
|
||||||
static R_Texture create_texture(const char *path) {
|
static R_Texture create_texture(const char *path) {
|
||||||
char path_to_load[256] = ASSETS_PATH;
|
char path_to_load[256] = ASSETS_PATH;
|
||||||
SDL_strlcat(path_to_load, path, SDL_arraysize(path_to_load));
|
SDL_strlcat(path_to_load, path, SDL_arraysize(path_to_load));
|
||||||
@@ -1357,20 +1374,26 @@ static void process_event_game(SDL_Event event) {
|
|||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case SDL_EVENT_KEY_DOWN: {
|
case SDL_EVENT_KEY_DOWN: {
|
||||||
|
if (event.key.repeat) return;
|
||||||
|
|
||||||
if (event.key.key == SDLK_UP || event.key.key == SDLK_W) {
|
if (event.key.key == SDLK_UP || event.key.key == SDLK_W) {
|
||||||
player.position.y = clamp(0, player.position.y + 1, current_map.size.y - 2);
|
queued_movement = true;
|
||||||
|
queued_movement_direction = DIR_UP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.key.key == SDLK_LEFT || event.key.key == SDLK_A) {
|
if (event.key.key == SDLK_LEFT || event.key.key == SDLK_A) {
|
||||||
player.position.x = clamp(0, player.position.x - 1, current_map.size.x - 2);
|
queued_movement = true;
|
||||||
|
queued_movement_direction = DIR_LEFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.key.key == SDLK_DOWN || event.key.key == SDLK_S) {
|
if (event.key.key == SDLK_DOWN || event.key.key == SDLK_S) {
|
||||||
player.position.y = clamp(0, player.position.y - 1, current_map.size.y - 2);
|
queued_movement = true;
|
||||||
|
queued_movement_direction = DIR_DOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.key.key == SDLK_RIGHT || event.key.key == SDLK_D) {
|
if (event.key.key == SDLK_RIGHT || event.key.key == SDLK_D) {
|
||||||
player.position.x = clamp(0, player.position.x + 1, current_map.size.x - 2);
|
queued_movement = true;
|
||||||
|
queued_movement_direction = DIR_RIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.key.key == SDLK_F9) {
|
if (event.key.key == SDLK_F9) {
|
||||||
@@ -1380,19 +1403,23 @@ static void process_event_game(SDL_Event event) {
|
|||||||
|
|
||||||
case SDL_EVENT_GAMEPAD_BUTTON_DOWN: {
|
case SDL_EVENT_GAMEPAD_BUTTON_DOWN: {
|
||||||
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_DPAD_UP) {
|
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_DPAD_UP) {
|
||||||
player.position.y = clamp(0, player.position.y + 1, current_map.size.y - 2);
|
queued_movement = true;
|
||||||
|
queued_movement_direction = DIR_UP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_DPAD_LEFT) {
|
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_DPAD_LEFT) {
|
||||||
player.position.x = clamp(0, player.position.x - 1, current_map.size.x - 2);
|
queued_movement = true;
|
||||||
|
queued_movement_direction = DIR_LEFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_DPAD_DOWN) {
|
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_DPAD_DOWN) {
|
||||||
player.position.y = clamp(0, player.position.y - 1, current_map.size.y - 2);
|
queued_movement = true;
|
||||||
|
queued_movement_direction = DIR_DOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_DPAD_RIGHT) {
|
if (event.gbutton.button == SDL_GAMEPAD_BUTTON_DPAD_RIGHT) {
|
||||||
player.position.x = clamp(0, player.position.x + 1, current_map.size.x - 2);
|
queued_movement = true;
|
||||||
|
queued_movement_direction = DIR_RIGHT;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@@ -1401,6 +1428,32 @@ static void process_event_game(SDL_Event event) {
|
|||||||
static void update_state_game() {
|
static void update_state_game() {
|
||||||
ZoneScopedN("update_state_game");
|
ZoneScopedN("update_state_game");
|
||||||
|
|
||||||
|
SDL_Time delta_time = current_time - last_time;
|
||||||
|
float delta_t = delta_time / (float)SDL_NS_PER_SECOND;
|
||||||
|
|
||||||
|
const bool *keyboard_state = SDL_GetKeyboardState(NULL);
|
||||||
|
|
||||||
|
if (player.is_moving) {
|
||||||
|
vec2 leftover_movement = vec2(player.target_position) - player.visual_position;
|
||||||
|
vec2 movement = clamp(min(vec2(0, 0), leftover_movement), normalize(leftover_movement) * (delta_t * character_speed * (keyboard_state[SDL_SCANCODE_LSHIFT] ? 2.0f : 1.0f)), max(vec2(0, 0), leftover_movement));
|
||||||
|
player.visual_position += movement;
|
||||||
|
|
||||||
|
if (movement == leftover_movement) {
|
||||||
|
player.is_moving = false;
|
||||||
|
player.position = player.target_position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!player.is_moving && (queued_movement || keyboard_state[SDL_SCANCODE_W] || keyboard_state[SDL_SCANCODE_A] || keyboard_state[SDL_SCANCODE_S] || keyboard_state[SDL_SCANCODE_D])) {
|
||||||
|
switch (queued_movement_direction) {
|
||||||
|
case DIR_UP: { player.target_position = player.position + ivec2( 0, 1); if (player.target_position != player.position) player.is_moving = true; } break;
|
||||||
|
case DIR_LEFT: { player.target_position = player.position + ivec2(-1, 0); if (player.target_position != player.position) player.is_moving = true; } break;
|
||||||
|
case DIR_DOWN: { player.target_position = player.position + ivec2( 0, -1); if (player.target_position != player.position) player.is_moving = true; } break;
|
||||||
|
case DIR_RIGHT: { player.target_position = player.position + ivec2( 1, 0); if (player.target_position != player.position) player.is_moving = true; } break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
queued_movement = false;
|
||||||
|
|
||||||
if (!MIX_TrackPlaying(music_track)) {
|
if (!MIX_TrackPlaying(music_track)) {
|
||||||
MIX_SetTrackAudio(music_track, music_setting_off_piano);
|
MIX_SetTrackAudio(music_track, music_setting_off_piano);
|
||||||
MIX_PlayTrack(music_track, 0);
|
MIX_PlayTrack(music_track, 0);
|
||||||
@@ -1414,7 +1467,7 @@ static void render_game() {
|
|||||||
ZoneScopedN("update buffers");
|
ZoneScopedN("update buffers");
|
||||||
{
|
{
|
||||||
ZoneScopedN("player_instance_buffer");
|
ZoneScopedN("player_instance_buffer");
|
||||||
player_instance.pos = player.position;
|
player_instance.pos = player.visual_position;
|
||||||
|
|
||||||
renderer_buffer_update(player_instance_buffer, 0, sizeof(player_instance), &player_instance);
|
renderer_buffer_update(player_instance_buffer, 0, sizeof(player_instance), &player_instance);
|
||||||
}
|
}
|
||||||
@@ -1424,8 +1477,8 @@ static void render_game() {
|
|||||||
|
|
||||||
float aspect_ratio = ((float)window_size.x / (float)window_size.y);
|
float aspect_ratio = ((float)window_size.x / (float)window_size.y);
|
||||||
|
|
||||||
view_matrix = view (vec3(player.position, 0), radians(camera_tilt), camera_distance);
|
view_matrix = view (vec3(player.visual_position, 0), radians(camera_tilt), camera_distance);
|
||||||
inverse_view_matrix = inverse_view(vec3(player.position, 0), radians(camera_tilt), camera_distance);
|
inverse_view_matrix = inverse_view(vec3(player.visual_position, 0), radians(camera_tilt), camera_distance);
|
||||||
|
|
||||||
projection_matrix = projection (radians(camera_fovy_degrees), aspect_ratio, NEAR_PLANE);
|
projection_matrix = projection (radians(camera_fovy_degrees), aspect_ratio, NEAR_PLANE);
|
||||||
inverse_projection_matrix = inverse_projection(radians(camera_fovy_degrees), aspect_ratio, NEAR_PLANE);
|
inverse_projection_matrix = inverse_projection(radians(camera_fovy_degrees), aspect_ratio, NEAR_PLANE);
|
||||||
@@ -1530,6 +1583,7 @@ static void process_events() {
|
|||||||
static void update_state() {
|
static void update_state() {
|
||||||
ZoneScopedN("update_state");
|
ZoneScopedN("update_state");
|
||||||
|
|
||||||
|
last_time = current_time;
|
||||||
SDL_GetCurrentTime(¤t_time);
|
SDL_GetCurrentTime(¤t_time);
|
||||||
|
|
||||||
if (use_actual_time)
|
if (use_actual_time)
|
||||||
|
|||||||
Reference in New Issue
Block a user