Re-enable collision and implement game lose screen

This commit is contained in:
Doyle Thai 2016-12-18 19:48:14 +11:00
parent 386e94db91
commit b3760aa3fc
6 changed files with 140 additions and 39 deletions

View File

@ -722,6 +722,8 @@ INTERNAL void gameUpdate(GameState *state, Memory *memory, f32 dt)
multiplierToStringP, V2(0, 0), 0, V4(1.0f, 1.0f, 1.0f, 1.0f), 3, 0);
/* Process multiplier bar updates */
if (!common_isSet(world->flags, gameworldstateflags_player_lost))
{
f32 barTimerPenalty = 1.0f;
if (world->timeSinceLastShot < 1.5f)
{
@ -737,7 +739,50 @@ INTERNAL void gameUpdate(GameState *state, Memory *memory, f32 dt)
world->scoreMultiplierBarTimer = 0;
world->scoreMultiplier++;
if (world->scoreMultiplier > 9999) world->scoreMultiplier = 9999;
if (world->scoreMultiplier > 9999)
world->scoreMultiplier = 9999;
}
}
}
if (common_isSet(world->flags, gameworldstateflags_player_lost))
{
Font *arial40 = asset_fontGet(&state->assetManager, "Arial", 40);
char *gameOver = "Game Over";
v2 gameOverP = v2_scale(state->renderer.size, 0.5f);
renderer_stringFixedCentered(
&state->renderer, &state->transientArena, arial40, "Game Over",
gameOverP, V2(0, 0), 0, V4(1, 1, 1, 1), 0, 0);
v2 gameOverSize = asset_fontStringDimInPixels(arial40, gameOver);
v2 replayP = V2(gameOverP.x, gameOverP.y - (gameOverSize.h * 1.2f));
renderer_stringFixedCentered(
&state->renderer, &state->transientArena, arial40,
"Press enter to play again or backspace to return to menu", replayP,
V2(0, 0), 0, V4(1, 1, 1, 1), 0, 0);
if (platform_queryKey(&state->input.keys[keycode_enter],
readkeytype_one_shot, 0.0f))
{
// TODO(doyle): Extract score init default values to some game
// definitions file
world->score = 0;
world->scoreMultiplier = 5;
world->scoreMultiplierBarTimer = 0.0f;
world->scoreMultiplierBarThresholdInS = 2.0f;
addPlayer(world);
world->flags ^= gameworldstateflags_player_lost;
}
else if (platform_queryKey(&state->input.keys[keycode_backspace],
readkeytype_one_shot, 0.0f))
{
common_memset((u8 *)world, 0, sizeof(*world));
state->currState = appstate_StartMenuState;
return;
}
}
@ -780,11 +825,13 @@ INTERNAL void gameUpdate(GameState *state, Memory *memory, f32 dt)
renderflag_no_texture | renderflag_wireframe);
}
#ifdef DENGINE_DEBUG
if (platform_queryKey(&state->input.keys[keycode_left_square_bracket],
readkeytype_repeat, 0.2f))
{
addAsteroid(world, (rand() % asteroidsize_count));
}
#endif
ASSERT(world->entityList[0].id == NULL_ENTITY_ID);
for (i32 i = 1; i < world->entityIndex; i++)
@ -807,6 +854,17 @@ INTERNAL void gameUpdate(GameState *state, Memory *memory, f32 dt)
DEGREES_TO_RADIANS((entity->rotation + 90.0f));
v2 direction = V2(math_cosf(rotation), math_sinf(rotation));
ddP = direction;
AudioVorbis *thrust =
asset_vorbisGet(&state->assetManager, "thrust");
AudioRenderer *audioRenderer =
getFreeAudioRenderer(world, thrust, 3);
if (audioRenderer)
{
audio_vorbisPlay(&state->transientArena,
&state->audioManager, audioRenderer,
thrust, 1);
}
}
if (platform_queryKey(&state->input.keys[keycode_space],
@ -1003,6 +1061,14 @@ INTERNAL void gameUpdate(GameState *state, Memory *memory, f32 dt)
colliderB = collideEntity;
}
// Assumptions made that the collision detect system relies on
ASSERT(entitytype_ship < entitytype_asteroid_small);
ASSERT(entitytype_asteroid_small < entitytype_asteroid_medium);
ASSERT(entitytype_asteroid_medium < entitytype_asteroid_large);
ASSERT(entitytype_asteroid_large < entitytype_bullet);
ASSERT(entitytype_asteroid_small + 1 == entitytype_asteroid_medium);
ASSERT(entitytype_asteroid_medium + 1 == entitytype_asteroid_large);
if (colliderA->type >= entitytype_asteroid_small &&
colliderA->type <= entitytype_asteroid_large)
{
@ -1092,7 +1158,6 @@ INTERNAL void gameUpdate(GameState *state, Memory *memory, f32 dt)
ASSERT(colliderB->type == entitytype_bullet);
deleteEntity(world, collisionIndex);
deleteEntity(world, i--);
world->asteroidCounter--;
@ -1126,6 +1191,36 @@ INTERNAL void gameUpdate(GameState *state, Memory *memory, f32 dt)
continue;
}
else if (colliderA->type == entitytype_ship)
{
if (colliderB->type >= entitytype_asteroid_small &&
colliderB->type <= entitytype_asteroid_large)
{
world->flags |= gameworldstateflags_player_lost;
if (collideEntity->type == entitytype_ship)
{
deleteEntity(world, collisionIndex);
}
else
{
deleteEntity(world, i--);
}
AudioVorbis *explode =
asset_vorbisGet(&state->assetManager, "bang_large");
AudioRenderer *audioRenderer =
getFreeAudioRenderer(world, explode, 3);
if (audioRenderer)
{
audio_vorbisPlay(&state->transientArena,
&state->audioManager, audioRenderer,
explode, 1);
}
continue;
}
}
}
RenderFlags flags = renderflag_wireframe | renderflag_no_texture;
@ -1219,13 +1314,11 @@ INTERNAL void startMenuUpdate(GameState *state, Memory *memory, f32 dt)
menuState->newResolutionRequest = TRUE;
v2 newSize =
resolutionArray->ptr[menuState->resStringDisplayIndex];
GameWorldState *world = GET_STATE_DATA(
state, &state->persistentArena, GameWorldState);
renderer_updateSize(renderer, &state->assetManager, newSize);
// TODO(doyle): reset world arena instead of zeroing out struct
GameWorldState *world = GET_STATE_DATA(
state, &state->persistentArena, GameWorldState);
common_memset((u8 *)world, 0, sizeof(GameWorldState));
debug_init(newSize, *arial15);
}
@ -1327,10 +1420,9 @@ INTERNAL void startMenuUpdate(GameState *state, Memory *memory, f32 dt)
GameWorldState *world =
GET_STATE_DATA(state, &state->persistentArena, GameWorldState);
addPlayer(world);
state->currState = appstate_GameWorldState;
world->flags |= gameworldstateflags_level_started;
addPlayer(world);
}
else if (platform_queryKey(&inputBuffer->keys[keycode_o],
readkeytype_one_shot, KEY_DELAY_NONE))

View File

@ -35,6 +35,10 @@ INTERNAL void shaderUse(u32 shaderId) { glUseProgram(shaderId); }
void renderer_updateSize(Renderer *renderer, AssetManager *assetManager, v2 windowSize)
{
renderer->size = windowSize;
// renderer->displayScale =
// V2(windowSize.x * 1.0f / renderer->referenceScale.x,
// windowSize.y * 1.0f / renderer->referenceScale.y);
// NOTE(doyle): Value to map a screen coordinate to NDC coordinate
renderer->vertexNdcFactor =
V2(1.0f / renderer->size.w, 1.0f / renderer->size.h);
@ -59,6 +63,7 @@ void renderer_updateSize(Renderer *renderer, AssetManager *assetManager, v2 wind
void renderer_init(Renderer *renderer, AssetManager *assetManager,
MemoryArena_ *persistentArena, v2 windowSize)
{
renderer->referenceScale = V2(1280, 720);
renderer_updateSize(renderer, assetManager, windowSize);
/* Create buffers */

View File

@ -19,10 +19,12 @@ INTERNAL void keyCallback(GLFWwindow *window, int key, int scancode, int action,
{
GameState *game = CAST(GameState *)(glfwGetWindowUserPointer(window));
#if 1
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, GL_TRUE);
}
#endif
switch (key)
{

View File

@ -26,11 +26,9 @@ typedef struct AssetManager
void asset_init(AssetManager *assetManager, MemoryArena_ *arena);
/*
*********************************
* Texture Operations
*********************************
*/
////////////////////////////////////////////////////////////////////////////////
// Texture Managing
////////////////////////////////////////////////////////////////////////////////
const SubTexture asset_atlasGetSubTex(TexAtlas *const atlas,
const char *const key);
Texture *asset_texGet(AssetManager *const assetManager, const char *const key);
@ -49,11 +47,9 @@ u8 *asset_imageLoad(i32 *width, i32 *height, i32 *bpp, const char *const path,
void asset_imageFree(u8 *image);
/*
*********************************
* Animation Asset Managing
*********************************
*/
////////////////////////////////////////////////////////////////////////////////
// Animation Asset Managing
////////////////////////////////////////////////////////////////////////////////
void asset_animAdd(AssetManager *const assetManager, MemoryArena_ *const arena,
const char *const animName, TexAtlas *const atlas,
char **const subTextureNames, const i32 numSubTextures,
@ -61,21 +57,17 @@ void asset_animAdd(AssetManager *const assetManager, MemoryArena_ *const arena,
Animation *asset_animGet(AssetManager *const assetManager,
const char *const key);
/*
*********************************
* Audio
*********************************
*/
////////////////////////////////////////////////////////////////////////////////
// Audio
////////////////////////////////////////////////////////////////////////////////
AudioVorbis *const asset_vorbisGet(AssetManager *const assetManager,
const char *const key);
const i32 asset_vorbisLoad(AssetManager *assetManager, MemoryArena_ *arena,
const char *const path, const char *const key);
/*
*********************************
* Everything else
*********************************
*/
////////////////////////////////////////////////////////////////////////////////
// Everything else
////////////////////////////////////////////////////////////////////////////////
const i32 asset_xmlLoad(AssetManager *const assetManager,
MemoryArena_ *const arena,
const PlatformFileRead *const fileRead);

View File

@ -21,6 +21,8 @@ enum GameWorldStateFlags
{
gameworldstateflags_init = (1 << 0),
gameworldstateflags_level_started = (1 << 1),
gameworldstateflags_player_lost = (1 << 2),
gameworldstateflags_create_player = (1 << 3),
};
typedef struct GameWorldState

View File

@ -68,6 +68,7 @@ enum VertexBatchState {
typedef struct Renderer
{
// rendererf
u32 shaderList[shaderlist_count];
u32 activeShaderId;
@ -81,6 +82,13 @@ typedef struct Renderer
v2 vertexNdcFactor;
v2 size;
// NOTE(doyle): Reference scale is the size chosen to have the best
// playability based on the sizes of the entity given to the system. Any
// other resoluions will be scaled through the renderer so that objects
// remain the same size in different resolutions.
f32 displayScale;
v2 referenceScale;
RenderGroup groups[128];
i32 groupsInUse;
i32 groupCapacity;