diff --git a/src/game.c b/src/game.c index 2e9f8bf..f00b63e 100644 --- a/src/game.c +++ b/src/game.c @@ -5,6 +5,7 @@ #include "game.h" #include "render.h" #include "camera.h" +#include "shape.h" GameState *Game_New() { @@ -59,38 +60,41 @@ void Game_Update(GameState *gs) if (gs->input.q) move[1] = 1.0f; else if (gs->input.e) move[1] = -1.0f; - gs->charIsMoving = gs->input.w || gs->input.s || gs->input.a || gs->input.d; + Player *player = &gs->player; + player->isMoving = gs->input.w || gs->input.s || gs->input.a || gs->input.d; // blend idle and run animations - if (gs->charIsMoving) + if (player->isMoving) { - gs->animBlend += delta / 500.0f; - if (gs->animBlend > 1.0f) gs->animBlend = 1.0f; + player->animBlend += delta / 500.0f; + if (player->animBlend > 1.0f) player->animBlend = 1.0f; } else { - gs->animBlend -= delta / 500.0f; - if (gs->animBlend < 0.0f) gs->animBlend = 0.0f; + player->animBlend -= delta / 500.0f; + if (player->animBlend < 0.0f) player->animBlend = 0.0f; } // apply acceleration - ShapeInstance *target = &(gs->testModel.instance); + ShapeInstance *target = &player->model.instance; float accel = 0.005f * delta; + vec3 vel; glm_vec3_scale_as(move, accel, move); glm_vec3_add(target->velocity, move, target->velocity); glm_vec3_clamp(target->velocity, -1.0f, 1.0f); + glm_vec3_scale(target->velocity, delta * 60.0f / 1000.0f, vel); // apply velocity, make camera follow vec3 displacement; glm_vec3_scale(gs->camera.front, -30.0f, displacement); displacement[1] += 10.0f; - glm_vec3_add(target->position, target->velocity, target->position); + glm_vec3_add(target->position, vel, target->position); glm_vec3_add(target->position, displacement, gs->camera.position); // decelerate glm_vec3_scale(target->velocity, 1.0f / ((0.01f * delta) + 1.0f), target->velocity); - if (gs->charIsMoving) + if (player->isMoving) { // gradually rotate model to face toward direction of velocity float alpha = delta > 200.0f ? 1.0f : delta / 200.0f; @@ -124,6 +128,16 @@ void Game_Update(GameState *gs) } Camera_UpdateVectors(&gs->camera); + + Shape *shape = gs->shapes[0]; + + for (int i = 0; i < shape->numInstances; i++) + { + ShapeInstance *instance = shape->instances + i; + glm_vec3_scale(instance->velocity, delta * 60.0f / 1000.0f, vel); + glm_vec3_add(instance->position, vel, instance->position); + glm_vec3_scale(instance->velocity, 1.0f / ((0.001f * delta) + 1.0f), instance->velocity); + } } void Game_Destroy(GameState *gs) diff --git a/src/game.h b/src/game.h index e2f841f..2a399dd 100644 --- a/src/game.h +++ b/src/game.h @@ -21,9 +21,15 @@ typedef struct typedef struct { - bool running; - bool charIsMoving; + Model model; float animBlend; + bool isMoving; + int shotIndex; +} Player; + +typedef struct +{ + bool running; uint64_t previousTicks; InputState input; SDL_Window *window; @@ -32,9 +38,9 @@ typedef struct int shaderProgramId; int modelShaderProgramId; Camera camera; + Player player; Shape **shapes; int numShapes; - Model testModel; mat4 projMatrix; mat4 viewMatrix; } GameState; diff --git a/src/input.c b/src/input.c index e35bc52..711b605 100644 --- a/src/input.c +++ b/src/input.c @@ -2,6 +2,7 @@ #include "input.h" #include "camera.h" #include "game.h" +#include "shape.h" static void HandleKeyDown(GameState *gs, SDL_KeyCode sym) { @@ -23,6 +24,25 @@ static void HandleKeyDown(GameState *gs, SDL_KeyCode sym) } break; + case SDLK_SPACE: + { + Shape *shape = gs->shapes[0]; + Player *player = &gs->player; + int i = player->shotIndex + 1; + if (i >= shape->numInstances) i = 0; + player->shotIndex = i; + ShapeInstance *projectile = shape->instances + i; + ShapeInstance *playerI = &player->model.instance; + glm_vec3_copy(playerI->position, projectile->position); + projectile->position[1] += 18.0f; + glm_vec3_scale_as(gs->camera.front, 5.0f, projectile->velocity); + glm_quat_copy(gs->camera.rotation, projectile->rotation); + versor q; + glm_quat_from_vecs(GLM_YUP, GLM_FORWARD, q); + glm_quat_mul(projectile->rotation, q, projectile->rotation); + } + break; + case SDLK_w: gs->input.w = true; break; case SDLK_a: gs->input.a = true; break; case SDLK_s: gs->input.s = true; break; diff --git a/src/render.c b/src/render.c index d3d5254..63b37be 100644 --- a/src/render.c +++ b/src/render.c @@ -270,14 +270,14 @@ bool Render_Init(GameState *gs) InitShapeBuffers(gs->shapes[1]); printf("Initialized buffers.\n"); - gs->testModel = Model_LoadGltf("res/model/human.glb"); + gs->player.model = Model_LoadGltf("res/model/human.glb"); return true; } void Render_Destroy(GameState *gs) { - Model_Free(gs->testModel); + Model_Free(gs->player.model); SDL_GL_DeleteContext(gs->glContext); SDL_DestroyWindow(gs->window); } @@ -410,7 +410,7 @@ static void ApplyAnim(cgltf_animation *anim, float t, float blend) static void DrawModel(GameState *gs) { - Model *model = &gs->testModel; + Model *model = &gs->player.model; ShapeInstance *instance = &model->instance; cgltf_data *data = model->data; cgltf_skin *skin = model->skin; @@ -424,7 +424,7 @@ static void DrawModel(GameState *gs) // apply local transformations for each bone for the current animation frame ApplyAnim(model->idle, t, 1.0f); - ApplyAnim(model->run, t, gs->animBlend); + ApplyAnim(model->run, t, gs->player.animBlend); if (!gs->input.freeLook) {