Added simple player movement with jump, gravity and collision

dev
Shariq Shah 6 years ago
parent 4986df6fb6
commit eb91c66d36
  1. 14
      assets/entities/cube.symtres
  2. 67
      assets/scenes/Level_1.symtres
  3. 2
      src/common/version.h
  4. 11
      src/game/debug_vars.c
  5. 1
      src/game/debug_vars.h
  6. 1
      src/game/entity.h
  7. 2
      src/game/input.c
  8. 142
      src/game/player.c
  9. 2
      src/game/scene.c

@ -0,0 +1,14 @@
Entity
{
type : 6
material : 0
diffuse_color : 1.000 1.000 1.000 1.000
geometry : cube.symbres
specular : 1.0000
active : true
diffuse_texture : default.tga
diffuse : 1.0000
specular_strength : 1.0000
name : Cube
}

@ -16,9 +16,9 @@ Player
{
type : 2
scale : 1.000 1.000 1.000
rotation : 0.000 -0.760 0.000 0.651
rotation : 0.000 -0.654 0.000 0.758
active : true
position : -68.875 1.832 -69.569
position : -38.848 2.992 -29.629
bouding_box_min : -0.500 -0.500 -0.500
name : Player
bouding_box_max : 0.500 0.500 0.500
@ -43,3 +43,66 @@ Scene_Entity_Entry
name : Cube
}
Scene_Entity_Entry
{
scale : 68.000 3.000 1.000
rotation : 0.000 0.000 0.000 1.000
position : -17.000 4.000 47.000
filename : cube_uv
name : Cube
}
Scene_Entity_Entry
{
scale : 68.000 3.000 1.000
rotation : 0.000 0.707 0.000 0.707
position : 50.000 4.000 -20.000
filename : cube_uv
name : Cube
}
Scene_Entity_Entry
{
scale : 68.000 3.000 1.000
rotation : 0.000 -0.707 0.000 0.707
position : -84.000 4.000 -20.000
filename : cube_uv
name : Cube
}
Scene_Entity_Entry
{
scale : 18.900 3.000 1.000
rotation : 0.000 0.000 0.000 1.000
position : -64.000 4.000 2.000
filename : cube_uv
name : Cube
}
Scene_Entity_Entry
{
scale : 68.000 3.000 1.000
rotation : 0.000 0.000 0.000 1.000
position : -17.000 4.000 -87.000
filename : cube_uv
name : Cube
}
Scene_Entity_Entry
{
scale : 68.000 3.000 1.000
rotation : 0.000 0.000 0.000 1.000
position : -17.000 4.000 -87.000
filename : cube_uv
name : Cube
}
Scene_Entity_Entry
{
scale : 35.500 3.000 1.000
rotation : 0.000 0.000 0.000 1.000
position : 15.000 4.000 -30.000
filename : cube_uv
name : Cube
}

@ -4,7 +4,7 @@
/* Auto generated version file. DO NOT MODIFY */
#define SYMMETRY_VERSION_MAJOR 0
#define SYMMETRY_VERSION_MINOR 1
#define SYMMETRY_VERSION_REVISION 306
#define SYMMETRY_VERSION_REVISION 307
#define SYMMETRY_VERSION_BRANCH "dev"
#endif

@ -106,6 +106,10 @@ void debug_vars_post_update(struct Debug_Vars* debug_vars)
nk_label(context, &variable->name[0], name_flags);
nk_labelf(context, value_flags, "%d", variable->value.val_int);
break;
case VT_BOOL:
nk_label(context, &variable->name[0], name_flags);
nk_labelf(context, value_flags, "%s", variable->value.val_bool ? "True" : "False");
break;
case VT_FLOAT:
nk_label(context, &variable->name[0], name_flags);
nk_labelf(context, value_flags, "%.3f", variable->value.val_float);
@ -211,6 +215,13 @@ void debug_vars_show_int(const char* name, int value)
debug_vars_show(name, &temp_var, true);
}
void debug_vars_show_bool(const char* name, bool value)
{
struct Variant temp_var;
variant_assign_bool(&temp_var, value);
debug_vars_show(name, &temp_var, true);
}
void debug_vars_show_float(const char* name, float value)
{
struct Variant temp_var;

@ -44,6 +44,7 @@ void debug_vars_cycle_location(struct Debug_Vars* debug_vars);
void debug_vars_show(const char* name, const struct Variant* value, bool is_numeric);
void debug_vars_show_int(const char* name, int value);
void debug_vars_show_bool(const char* name, bool value);
void debug_vars_show_float(const char* name, float value);
void debug_vars_show_texture(const char* name, int texture_index);
void debug_vars_show_vec3(const char* name, const vec3* value);

@ -175,6 +175,7 @@ struct Player
float move_speed;
float move_speed_multiplier;
float turn_speed;
bool grounded;
};
void entity_init(struct Entity* entity, const char* name, struct Entity* parent);

@ -38,6 +38,7 @@ void input_init(void)
struct Key_Binding turn_left_keys = {KEY_H, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE};
struct Key_Binding turn_up_keys = {KEY_K, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE};
struct Key_Binding turn_down_keys = {KEY_J, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE};
struct Key_Binding jump_keys = {KEY_SPACE, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE};
struct Key_Binding sprint_keys = {KEY_LSHIFT, KMOD_NONE, KEY_RSHIFT, KMOD_NONE, KS_INACTIVE};
struct Key_Binding editor_toggle_keys = {KEY_F1, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE};
struct Key_Binding console_toggle_keys = {KEY_TILDE, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE};
@ -56,6 +57,7 @@ void input_init(void)
input_map_create("Turn_Up", turn_up_keys);
input_map_create("Turn_Down", turn_down_keys);
input_map_create("Sprint", sprint_keys);
input_map_create("Jump", jump_keys);
input_map_create("Editor_Toggle", editor_toggle_keys);
input_map_create("Console_Toggle", console_toggle_keys);
input_map_create("Debug_Vars_Toggle", debug_vars_toggle_keys);

@ -26,6 +26,7 @@ void player_init(struct Player* player, struct Scene* scene)
player->move_speed = hashmap_int_get(config, "player_move_speed");
player->move_speed_multiplier = hashmap_int_get(config, "player_move_speed_multiplier");
player->turn_speed = hashmap_int_get(config, "player_turn_speed");
player->grounded = true;
player->mesh = scene_static_mesh_create(scene, "Player_Mesh", player, "sphere.symbres", MAT_BLINN);
@ -114,45 +115,136 @@ void player_update(struct Player* player, struct Scene* scene, float dt)
transform_rotate(player->camera_node, &rot_axis_pitch, pitch, TS_LOCAL);
/* Movement */
float gravity = 0.1f;
float dampening_x = 0.08f;
float dampening_z = 0.08f;
float jump_velocity = 20.f;
float move_speed = player->move_speed;
vec3 offset = {0.f, 0.f, 0.f};
static vec3 velocity = { 0.f, 0.f, 0.f };
vec3 max_velocity = { player->move_speed * player->move_speed_multiplier, jump_velocity, player->move_speed * player->move_speed_multiplier };
static bool jumping = false;
// If we started jumping last frame, set jumpig to false
if(jumping) jumping = false;
if(input_map_state_get("Sprint", KS_PRESSED)) move_speed *= player->move_speed_multiplier;
if(input_map_state_get("Move_Forward", KS_PRESSED)) offset.z -= move_speed;
if(input_map_state_get("Move_Backward", KS_PRESSED)) offset.z += move_speed;
if(input_map_state_get("Move_Left", KS_PRESSED)) offset.x -= move_speed;
if(input_map_state_get("Move_Right", KS_PRESSED)) offset.x += move_speed;
if(input_map_state_get("Move_Up", KS_PRESSED)) offset.y += move_speed;
if(input_map_state_get("Move_Down", KS_PRESSED)) offset.y -= move_speed;
if(input_map_state_get("Move_Forward", KS_PRESSED)) velocity.z -= move_speed;
if(input_map_state_get("Move_Backward", KS_PRESSED)) velocity.z += move_speed;
if(input_map_state_get("Move_Left", KS_PRESSED)) velocity.x -= move_speed;
if(input_map_state_get("Move_Right", KS_PRESSED)) velocity.x += move_speed;
if(input_map_state_get("Jump", KS_PRESSED))
{
if(player->grounded)
{
velocity.y += jump_velocity;
jumping = true;
player->grounded = false;
}
}
// Dampen Velocity
if(velocity.x > 0.f)
velocity.x -= dampening_x;
else if(velocity.x < 0.f)
velocity.x += dampening_x;
//if(velocity.y >= 0.f)
velocity.y -= gravity;
if(velocity.z > 0.f)
velocity.z -= dampening_z;
else if(velocity.z < 0.f)
velocity.z += dampening_z;
// Clamp velocity to min/max
if(velocity.x > max_velocity.x)
velocity.x = max_velocity.x;
else if(velocity.x < -max_velocity.x)
velocity.x = -max_velocity.x;
if(velocity.y > max_velocity.y)
velocity.y = max_velocity.y;
if(velocity.y < -max_velocity.y)
velocity.y = -max_velocity.y;
if(velocity.z > max_velocity.z)
velocity.z = max_velocity.z;
if(velocity.z < -max_velocity.z)
velocity.z = -max_velocity.z;
/* Check for collisions ahead */
int mouse_x = 0, mouse_y = 0;
platform_mouse_position_get(&mouse_x, &mouse_y);
struct Ray forward_ray = camera_screen_coord_to_ray(player->camera_node, mouse_x, mouse_y);
float min_collision_distance = 2.0f;
// Get all the entities that intersect then check the distance if it is less than
// or equal to min_collision_distance then we are colliding
struct Raycast_Result ray_result;
scene_ray_intersect(scene, &forward_ray, &ray_result, ERM_STATIC_MESH);
debug_vars_show_int("Colliding Entities", ray_result.num_entities_intersected);
if(ray_result.num_entities_intersected > 0)
{
for(int i = 0; i < ray_result.num_entities_intersected; i++)
{
struct Entity* colliding_entity = ray_result.entities_intersected[i];
float distance = bv_distance_ray_bounding_box(&forward_ray, &colliding_entity->derived_bounding_box);
debug_vars_show_float("Collision ahead", distance);
if(distance > 0.f && distance <= min_collision_distance && colliding_entity != player->mesh)
{
velocity.x = 0.f;
velocity.z = 0.f;
}
}
}
/* Check for collisions below */
struct Ray downward_ray;
transform_get_absolute_position(player->mesh, &downward_ray.origin);
vec3_fill(&downward_ray.direction, 0.f, -1.f, 0.f);
struct Raycast_Result down_ray_result;
scene_ray_intersect(scene, &downward_ray, &down_ray_result, ERM_STATIC_MESH);
if(down_ray_result.num_entities_intersected > 0)
{
float min_downward_distance = 2.f;
for(int i = 0; i < down_ray_result.num_entities_intersected; i++)
{
struct Entity* colliding_entity = down_ray_result.entities_intersected[i];
float distance = bv_distance_ray_bounding_box(&downward_ray, &colliding_entity->derived_bounding_box);
debug_vars_show_float("Collision below", distance);
if(distance > 0.f && distance <= min_downward_distance && colliding_entity != player->mesh && !jumping)
{
velocity.y = 0.f;
player->grounded = true;
}
}
}
vec3 offset = {0.f, 0.f, 0.f};
debug_vars_show_vec3("velocity", &velocity);
debug_vars_show_bool("Grounded", player->grounded);
vec3_assign(&offset, &velocity);
vec3_scale(&offset, &offset, dt);
if(offset.x != 0 || offset.y != 0 || offset.z != 0)
if(offset.x != 0 || offset.z != 0)
{
quat_mul_vec3(&offset, &player->camera_node->base.transform.rotation, &offset);
transform_translate(player, &offset, TS_LOCAL);
offset.y = 0.f;
}
if(velocity.y != 0.f)
offset.y = velocity.y * dt;
transform_translate(player, &offset, TS_LOCAL);
/* Aiming and Projectiles*/
if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED))
{
int mouse_x = 0, mouse_y = 0;
platform_mouse_position_get(&mouse_x, &mouse_y);
struct Ray ray = camera_screen_coord_to_ray(player->camera_node, mouse_x, mouse_y);
log_message("Ray: %.3f, %.3f, %.3f", ray.direction.x, ray.direction.y, ray.direction.z);
struct Ray bullet_ray = camera_screen_coord_to_ray(player->camera_node, mouse_x, mouse_y);
log_message("Ray: %.3f, %.3f, %.3f", bullet_ray.direction.x, bullet_ray.direction.y, bullet_ray.direction.z);
struct Raycast_Result ray_result;
scene_ray_intersect(scene, &ray, &ray_result, ERM_ALL);
}
vec3 mesh_abs = { 0.f, 0.f, 0.f };
transform_get_absolute_position(player->mesh, &mesh_abs);
debug_vars_show_vec3("Player Position", &player->base.transform.position);
debug_vars_show_vec3("Mesh Position", &mesh_abs);
debug_vars_show_vec3("Min", &player->mesh->base.derived_bounding_box.min);
debug_vars_show_vec3("Max", &player->mesh->base.derived_bounding_box.max);
struct Geometry* geom = geom_get(player->mesh->model.geometry_index);
debug_vars_show_vec3("Geom Min", &geom->bounding_box.min);
debug_vars_show_vec3("Geom Max", &geom->bounding_box.max);
debug_vars_show_texture("Player Camera Render", player->camera_node->render_tex);
debug_vars_show_texture("Player Camera Depth", player->camera_node->depth_tex);
scene_ray_intersect(scene, &bullet_ray, &ray_result, ERM_ALL);
}
}

@ -866,7 +866,7 @@ void scene_ray_intersect(struct Scene* scene, struct Ray* ray, struct Raycast_Re
int result = bv_intersect_bounding_box_ray(&entity->derived_bounding_box, ray);
if(result == IT_INTERSECT || result == IT_INSIDE)
{
out_results->entities_intersected[out_results->num_entities_intersected] = &entity;
out_results->entities_intersected[out_results->num_entities_intersected] = entity;
out_results->num_entities_intersected++;
}
}

Loading…
Cancel
Save