Add ability to shoot and delete entities
This commit is contained in:
parent
6069ed8415
commit
42ba86f05a
Binary file not shown.
259
src/Asteroid.c
259
src/Asteroid.c
@ -183,6 +183,8 @@ v2 *createAsteroidVertexList(MemoryArena_ *arena, i32 iterations,
|
||||
result[i] = V2(((math_cosf(iterationAngle * i) + 1) * asteroidRadius),
|
||||
((math_sinf(iterationAngle * i) + 1) * asteroidRadius));
|
||||
|
||||
ASSERT(result[i].x >= 0 && result[i].y >= 0);
|
||||
|
||||
#if 1
|
||||
f32 displacementDist = 0.50f * asteroidRadius;
|
||||
i32 vertexDisplacement =
|
||||
@ -284,8 +286,9 @@ b32 checkEdgeProjectionOverlap(v2 *vertexList, i32 listSize,
|
||||
return result;
|
||||
}
|
||||
|
||||
b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP,
|
||||
f32 dt, f32 ddPSpeed)
|
||||
INTERNAL b32 moveEntity(World *world, MemoryArena_ *transientArena,
|
||||
Entity *entity, i32 entityIndex, v2 ddP, f32 dt,
|
||||
f32 ddPSpeed)
|
||||
{
|
||||
ASSERT(ABS(ddP.x) <= 1.0f && ABS(ddP.y) <= 1.0f);
|
||||
/*
|
||||
@ -295,7 +298,7 @@ b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP,
|
||||
newPos = (a*t^2)/2 + oldVelocity*t + oldPos
|
||||
*/
|
||||
|
||||
ddP = v2_scale(ddP, state->pixelsPerMeter * ddPSpeed);
|
||||
ddP = v2_scale(ddP, world->pixelsPerMeter * ddPSpeed);
|
||||
v2 oldDp = entity->dP;
|
||||
v2 resistance = v2_scale(oldDp, 2.0f);
|
||||
ddP = v2_sub(ddP, resistance);
|
||||
@ -313,59 +316,59 @@ b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP,
|
||||
|
||||
// TODO(doyle): Collision for rects, (need to create vertex list for it)
|
||||
#if 1
|
||||
if (entity->renderMode == rendermode_polygon && entity->collides)
|
||||
for (i32 i = entityIndex + 1; i < world->entityIndex; i++)
|
||||
{
|
||||
for (i32 i = entityIndex + 1; i < state->entityIndex; i++)
|
||||
Entity *checkEntity = &world->entityList[i];
|
||||
ASSERT(checkEntity->id != entity->id);
|
||||
|
||||
if (world->collisionTable[entity->type][checkEntity->type])
|
||||
{
|
||||
Entity *checkEntity = &state->entityList[i];
|
||||
ASSERT(checkEntity->id != entity->id);
|
||||
ASSERT(entity->vertexPoints);
|
||||
ASSERT(checkEntity->vertexPoints);
|
||||
|
||||
if (checkEntity->renderMode == rendermode_polygon &&
|
||||
checkEntity->collides)
|
||||
/* Create entity edge lists */
|
||||
v2 *entityVertexListOffsetToP = entity_generateUpdatedVertexList(
|
||||
transientArena, entity);
|
||||
|
||||
v2 *checkEntityVertexListOffsetToP =
|
||||
entity_generateUpdatedVertexList(transientArena,
|
||||
checkEntity);
|
||||
|
||||
v2 *entityEdgeList = createNormalEdgeList(transientArena,
|
||||
entityVertexListOffsetToP,
|
||||
entity->numVertexPoints);
|
||||
|
||||
v2 *checkEntityEdgeList = createNormalEdgeList(
|
||||
transientArena, checkEntityVertexListOffsetToP,
|
||||
checkEntity->numVertexPoints);
|
||||
|
||||
/* Combine both edge lists into one */
|
||||
i32 totalNumEdges =
|
||||
checkEntity->numVertexPoints + entity->numVertexPoints;
|
||||
v2 *edgeList =
|
||||
memory_pushBytes(transientArena, totalNumEdges * sizeof(v2));
|
||||
for (i32 i = 0; i < entity->numVertexPoints; i++)
|
||||
{
|
||||
/* Create entity edge lists */
|
||||
v2 *entityVertexListOffsetToP =
|
||||
entity_createVertexList(&state->transientArena, entity);
|
||||
|
||||
v2 *checkEntityVertexListOffsetToP = entity_createVertexList(
|
||||
&state->transientArena, checkEntity);
|
||||
|
||||
v2 *entityEdgeList = createNormalEdgeList(
|
||||
&state->transientArena, entityVertexListOffsetToP,
|
||||
entity->numVertexPoints);
|
||||
|
||||
v2 *checkEntityEdgeList = createNormalEdgeList(
|
||||
&state->transientArena, checkEntityVertexListOffsetToP,
|
||||
checkEntity->numVertexPoints);
|
||||
|
||||
/* Combine both edge lists into one */
|
||||
i32 totalNumEdges =
|
||||
checkEntity->numVertexPoints + entity->numVertexPoints;
|
||||
v2 *edgeList = memory_pushBytes(&state->transientArena,
|
||||
totalNumEdges * sizeof(v2));
|
||||
for (i32 i = 0; i < entity->numVertexPoints; i++)
|
||||
{
|
||||
edgeList[i] = entityEdgeList[i];
|
||||
}
|
||||
|
||||
for (i32 i = 0; i < checkEntity->numVertexPoints; i++)
|
||||
{
|
||||
edgeList[i + entity->numVertexPoints] =
|
||||
checkEntityEdgeList[i];
|
||||
}
|
||||
|
||||
if (checkEdgeProjectionOverlap(
|
||||
entityVertexListOffsetToP, entity->numVertexPoints,
|
||||
checkEntityVertexListOffsetToP,
|
||||
checkEntity->numVertexPoints, edgeList, totalNumEdges))
|
||||
{
|
||||
willCollide = TRUE;
|
||||
}
|
||||
edgeList[i] = entityEdgeList[i];
|
||||
}
|
||||
|
||||
if (willCollide) {
|
||||
break;
|
||||
for (i32 i = 0; i < checkEntity->numVertexPoints; i++)
|
||||
{
|
||||
edgeList[i + entity->numVertexPoints] = checkEntityEdgeList[i];
|
||||
}
|
||||
|
||||
if (checkEdgeProjectionOverlap(
|
||||
entityVertexListOffsetToP, entity->numVertexPoints,
|
||||
checkEntityVertexListOffsetToP,
|
||||
checkEntity->numVertexPoints, edgeList, totalNumEdges))
|
||||
{
|
||||
willCollide = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (willCollide)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -389,68 +392,106 @@ b32 moveEntity(GameState *state, Entity *entity, i32 entityIndex, v2 ddP,
|
||||
return willCollide;
|
||||
}
|
||||
|
||||
INTERNAL void addAsteroid(GameState *state, v2 windowSize)
|
||||
INTERNAL void addAsteroid(World *world, v2 windowSize)
|
||||
{
|
||||
Entity *asteroid = &state->entityList[state->entityIndex];
|
||||
asteroid->id = state->entityIndex++;
|
||||
Entity *asteroid = &world->entityList[world->entityIndex++];
|
||||
asteroid->id = world->entityIdCounter++;
|
||||
|
||||
i32 randValue = rand();
|
||||
i32 randX = (randValue % (i32)windowSize.w);
|
||||
i32 randY = (randValue % (i32)windowSize.h);
|
||||
asteroid->pos = V2i(randX, randY);
|
||||
|
||||
asteroid->size = V2(75.0f, 75.0f);
|
||||
asteroid->size = V2(100.0f, 100.0f);
|
||||
asteroid->hitbox = asteroid->size;
|
||||
asteroid->offset = V2(asteroid->size.w * -0.5f, 0);
|
||||
asteroid->scale = 1;
|
||||
asteroid->rotation = 45;
|
||||
asteroid->offset = v2_scale(asteroid->size, -0.5f);
|
||||
asteroid->type = entitytype_asteroid;
|
||||
asteroid->direction = direction_null;
|
||||
asteroid->renderMode = rendermode_polygon;
|
||||
|
||||
asteroid->numVertexPoints = 10;
|
||||
asteroid->vertexPoints = createAsteroidVertexList(
|
||||
&state->persistentArena, asteroid->numVertexPoints,
|
||||
(i32)(asteroid->size.x * 0.5f));
|
||||
&world->entityArena, asteroid->numVertexPoints,
|
||||
(i32)(asteroid->size.w * 0.5f));
|
||||
|
||||
asteroid->tex = NULL;
|
||||
asteroid->collides = TRUE;
|
||||
asteroid->color = V4(0.0f, 0.5f, 0.5f, 1.0f);
|
||||
}
|
||||
|
||||
INTERNAL void addBullet(World *world, Entity *shooter)
|
||||
{
|
||||
Entity *bullet = &world->entityList[world->entityIndex++];
|
||||
bullet->id = world->entityIdCounter++;
|
||||
|
||||
bullet->offset = v2_scale(bullet->size, -0.5f);
|
||||
bullet->pos = v2_add(shooter->pos, bullet->offset);
|
||||
bullet->hitbox = bullet->size;
|
||||
bullet->size = V2(2.0f, 20.0f);
|
||||
bullet->rotation = shooter->rotation;
|
||||
bullet->renderMode = rendermode_quad;
|
||||
|
||||
// TODO(doyle): Figure out how to free this memory on entity delete. A free list?
|
||||
bullet->vertexPoints =
|
||||
memory_pushBytes(&world->entityArena, sizeof(v2) * 4);
|
||||
bullet->vertexPoints[0] = V2(0, bullet->size.h);
|
||||
bullet->vertexPoints[1] = V2(0, 0);
|
||||
bullet->vertexPoints[2] = V2(bullet->size.w, 0);
|
||||
bullet->vertexPoints[3] = bullet->size;
|
||||
|
||||
bullet->numVertexPoints = 4;
|
||||
|
||||
bullet->type = entitytype_bullet;
|
||||
bullet->color = V4(1.0f, 1.0f, 0, 1.0f);
|
||||
}
|
||||
|
||||
INTERNAL void setCollisionRule(World *world, enum EntityType a,
|
||||
enum EntityType b, b32 rule)
|
||||
{
|
||||
ASSERT(a <= entitytype_count);
|
||||
ASSERT(b <= entitytype_count);
|
||||
world->collisionTable[a][b] = rule;
|
||||
world->collisionTable[b][a] = rule;
|
||||
}
|
||||
|
||||
void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
||||
v2 windowSize, f32 dt)
|
||||
{
|
||||
MemoryIndex globalTransientArenaSize =
|
||||
(MemoryIndex)((f32)memory->transientSize * 0.5f);
|
||||
memory_arenaInit(&state->transientArena, memory->transient,
|
||||
memory->transientSize);
|
||||
globalTransientArenaSize);
|
||||
|
||||
World *world = &state->world;
|
||||
if (!state->init)
|
||||
{
|
||||
srand((u32)time(NULL));
|
||||
memory_arenaInit(&state->persistentArena, memory->persistent,
|
||||
memory->persistentSize);
|
||||
initAssetManager(state);
|
||||
initRenderer(state, windowSize);
|
||||
|
||||
state->pixelsPerMeter = 70.0f;
|
||||
world->pixelsPerMeter = 70.0f;
|
||||
|
||||
MemoryIndex entityArenaSize =
|
||||
(MemoryIndex)((f32)memory->transientSize * 0.5f);
|
||||
|
||||
u8 *arenaBase = state->transientArena.base + state->transientArena.size;
|
||||
memory_arenaInit(&world->entityArena, arenaBase, entityArenaSize);
|
||||
|
||||
{ // Init asteroid entities
|
||||
i32 numAsteroids = 15;
|
||||
for (i32 i = 0; i < numAsteroids; i++)
|
||||
addAsteroid(state, windowSize);
|
||||
addAsteroid(world, windowSize);
|
||||
}
|
||||
|
||||
#if 1
|
||||
{ // Init ship entity
|
||||
Entity *ship = &state->entityList[state->entityIndex];
|
||||
ship->id = state->entityIndex++;
|
||||
Entity *ship = &world->entityList[world->entityIndex++];
|
||||
ship->id = world->entityIdCounter++;
|
||||
ship->pos = V2(100, 100);
|
||||
ship->size = V2(25.0f, 50.0f);
|
||||
ship->hitbox = ship->size;
|
||||
ship->offset = v2_scale(ship->size, 0.5f);
|
||||
ship->offset = v2_scale(ship->size, -0.5f);
|
||||
|
||||
ship->numVertexPoints = 3;
|
||||
ship->vertexPoints = memory_pushBytes(
|
||||
&state->persistentArena, sizeof(v2) * ship->numVertexPoints);
|
||||
&world->entityArena, sizeof(v2) * ship->numVertexPoints);
|
||||
|
||||
v2 triangleBaseP = V2(0, 0);
|
||||
v2 triangleTopP = V2(ship->size.w * 0.5f, ship->size.h);
|
||||
@ -464,19 +505,21 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
||||
ship->type = entitytype_ship;
|
||||
ship->direction = direction_null;
|
||||
ship->renderMode = rendermode_polygon;
|
||||
ship->tex = NULL;
|
||||
ship->collides = TRUE;
|
||||
|
||||
ship->color = V4(1.0f, 0.5f, 0.5f, 1.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
{ // Global Collision Rules
|
||||
setCollisionRule(world, entitytype_ship, entitytype_asteroid, TRUE);
|
||||
setCollisionRule(world, entitytype_bullet, entitytype_asteroid,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
world->camera.min = V2(0, 0);
|
||||
world->camera.max = state->renderer.size;
|
||||
world->worldSize = windowSize;
|
||||
|
||||
state->camera.min = V2(0, 0);
|
||||
state->camera.max = state->renderer.size;
|
||||
state->init = TRUE;
|
||||
|
||||
state->worldSize = windowSize;
|
||||
|
||||
debug_init(&state->persistentArena, windowSize,
|
||||
state->assetManager.font);
|
||||
}
|
||||
@ -509,26 +552,26 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
||||
if (getKeyStatus(&state->input.keys[keycode_left_square_bracket],
|
||||
readkeytype_repeat, 0.2f, dt))
|
||||
{
|
||||
addAsteroid(state, windowSize);
|
||||
addAsteroid(world, windowSize);
|
||||
}
|
||||
|
||||
for (i32 i = 0; i < state->entityIndex; i++)
|
||||
for (i32 i = 0; i < world->entityIndex; i++)
|
||||
{
|
||||
Entity *entity = &state->entityList[i];
|
||||
Entity *entity = &world->entityList[i];
|
||||
ASSERT(entity->type != entitytype_invalid);
|
||||
|
||||
v2 pivotPoint = {0};
|
||||
|
||||
// Loop entity around world
|
||||
if (entity->pos.y >= state->worldSize.h)
|
||||
if (entity->pos.y >= world->worldSize.h)
|
||||
entity->pos.y = 0;
|
||||
else if (entity->pos.y < 0)
|
||||
entity->pos.y = state->worldSize.h;
|
||||
entity->pos.y = world->worldSize.h;
|
||||
|
||||
if (entity->pos.x >= state->worldSize.w)
|
||||
if (entity->pos.x >= world->worldSize.w)
|
||||
entity->pos.x = 0;
|
||||
else if (entity->pos.x < 0)
|
||||
entity->pos.x = state->worldSize.w;
|
||||
entity->pos.x = world->worldSize.w;
|
||||
|
||||
f32 ddPSpeedInMs = 0;
|
||||
v2 ddP = {0};
|
||||
@ -560,6 +603,12 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
||||
entity->rotation -= (rotationsPerSecond) * dt;
|
||||
}
|
||||
|
||||
if (getKeyStatus(&state->input.keys[keycode_space],
|
||||
readkeytype_delayedRepeat, 0.0f, dt))
|
||||
{
|
||||
addBullet(world, entity);
|
||||
}
|
||||
|
||||
if (ddP.x > 0.0f && ddP.y > 0.0f)
|
||||
{
|
||||
// NOTE(doyle): Cheese it and pre-compute the vector for
|
||||
@ -572,6 +621,11 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
||||
DEBUG_PUSH_VAR("Pos: %5.2f, %5.2f", entity->pos, "v2");
|
||||
DEBUG_PUSH_VAR("Velocity: %5.2f, %5.2f", entity->dP, "v2");
|
||||
DEBUG_PUSH_VAR("Rotation: %5.2f", entity->rotation, "f32");
|
||||
|
||||
renderer_rect(&state->renderer, world->camera, entity->pos,
|
||||
V2(5, 5), V2(0, 0),
|
||||
DEGREES_TO_RADIANS(entity->rotation), NULL,
|
||||
V4(1.0f, 1.0f, 1.0f, 1.0f), renderflag_no_texture);
|
||||
}
|
||||
else if (entity->type == entitytype_asteroid)
|
||||
{
|
||||
@ -648,26 +702,43 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
||||
f32 dirOffset = ((randValue % 10) + 1) / 100.0f;
|
||||
v2_scale(ddP, dirOffset);
|
||||
|
||||
// NOTE(doyle): Make asteroids start and move at constant speed
|
||||
// NOTE(doyle): Make asteroids start and move at constant speed by
|
||||
// ensuring that dP is "refreshed" with non-decaying acceleration
|
||||
ddPSpeedInMs = 1;
|
||||
entity->dP = v2_scale(ddP, state->pixelsPerMeter * ddPSpeedInMs);
|
||||
entity->dP = v2_scale(ddP, world->pixelsPerMeter * ddPSpeedInMs);
|
||||
entity->rotation += (60 * dt);
|
||||
#endif
|
||||
}
|
||||
else if (entity->type == entitytype_bullet)
|
||||
{
|
||||
ddPSpeedInMs = 5;
|
||||
Radians rotation = DEGREES_TO_RADIANS((entity->rotation + 90.0f));
|
||||
ddP = V2(math_cosf(rotation), math_sinf(rotation));
|
||||
entity->dP = v2_scale(ddP, world->pixelsPerMeter * ddPSpeedInMs);
|
||||
}
|
||||
|
||||
b32 willCollide = moveEntity(state, entity, i, ddP, dt, ddPSpeedInMs);
|
||||
v4 entityColor = V4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
#if 1
|
||||
b32 willCollide = moveEntity(world, &state->transientArena, entity, i,
|
||||
ddP, dt, ddPSpeedInMs);
|
||||
v4 collideColor = {0};
|
||||
if (willCollide)
|
||||
{
|
||||
entityColor = V4(1.0f, 1.0f, 0, 1.0f);
|
||||
collideColor = V4(1.0f, 0, 0, 0.5f);
|
||||
}
|
||||
|
||||
if (entity->type == entitytype_bullet)
|
||||
{
|
||||
if (!math_pointInRect(world->camera, entity->pos))
|
||||
{
|
||||
world->entityList[i] = world->entityList[--world->entityIndex];
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
RenderFlags flags = renderflag_wireframe | renderflag_no_texture;
|
||||
renderer_entity(&state->renderer, &state->transientArena, state->camera,
|
||||
renderer_entity(&state->renderer, &state->transientArena, world->camera,
|
||||
entity, V2(0, 0), 0,
|
||||
entityColor, flags);
|
||||
collideColor, flags);
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
32
src/Debug.c
32
src/Debug.c
@ -273,19 +273,27 @@ void debug_drawUi(GameState *state, f32 dt)
|
||||
updateAndRenderDebugStack(&state->renderer, &state->transientArena, dt);
|
||||
renderConsole(&state->renderer, &state->transientArena);
|
||||
|
||||
MemoryArena_ *transient = &state->transientArena;
|
||||
i32 transientSizeInKbs = transient->size / 1024;
|
||||
i32 transientUsedInKbs = transient->used / 1024;
|
||||
v2 transientUsage = V2i(transientUsedInKbs, transientSizeInKbs);
|
||||
DEBUG_PUSH_VAR("Transient Size: %.0f", transient->size, "f32");
|
||||
DEBUG_PUSH_VAR("Transient Usage: %.0f/%.0f", transientUsage, "v2");
|
||||
{ // Print Memory Arena Info
|
||||
DEBUG_PUSH_STRING("== MEMORY ARENAS ==");
|
||||
MemoryArena_ *transient = &state->transientArena;
|
||||
i32 transientSizeInKbs = transient->size / 1024;
|
||||
i32 transientUsedInKbs = transient->used / 1024;
|
||||
v2 transientUsage = V2i(transientUsedInKbs, transientSizeInKbs);
|
||||
DEBUG_PUSH_VAR("Transient Usage: %.0f/%.0f", transientUsage, "v2");
|
||||
|
||||
MemoryArena_ *persistent = &state->persistentArena;
|
||||
i32 persistentSizeInKbs = persistent->size / 1024;
|
||||
i32 persistentUsedInKbs = persistent->used / 1024;
|
||||
v2 persistentUsage = V2i(persistentUsedInKbs, persistentSizeInKbs);
|
||||
DEBUG_PUSH_VAR("Permanent Size: %.0f", persistent->size, "f32");
|
||||
DEBUG_PUSH_VAR("Permanent Usage: %.0f/%.0f", persistentUsage, "v2");
|
||||
MemoryArena_ *persistent = &state->persistentArena;
|
||||
i32 persistentSizeInKbs = persistent->size / 1024;
|
||||
i32 persistentUsedInKbs = persistent->used / 1024;
|
||||
v2 persistentUsage = V2i(persistentUsedInKbs, persistentSizeInKbs);
|
||||
DEBUG_PUSH_VAR("Permanent Usage: %.0f/%.0f", persistentUsage, "v2");
|
||||
|
||||
MemoryArena_ *entityArena = &state->world.entityArena;
|
||||
i32 entitySizeInKbs = entityArena->size / 1024;
|
||||
i32 entityUsedInKbs = entityArena->used / 1024;
|
||||
v2 entityUsage = V2i(entityUsedInKbs, entitySizeInKbs);
|
||||
DEBUG_PUSH_VAR("Entity Usage: %.0f/%.0f", entityUsage, "v2");
|
||||
DEBUG_PUSH_STRING("== ==");
|
||||
}
|
||||
|
||||
DEBUG_PUSH_VAR("Num Vertex: %d",
|
||||
GLOBAL_debug.callCount[debugcount_numVertex], "i32");
|
||||
|
@ -89,8 +89,12 @@ void entity_addAnim(AssetManager *const assetManager, Entity *const entity,
|
||||
DEBUG_LOG("No more free entity animation slots");
|
||||
}
|
||||
|
||||
v2 *entity_createVertexList(MemoryArena_ *transientArena, Entity *entity)
|
||||
v2 *entity_generateUpdatedVertexList(MemoryArena_ *transientArena,
|
||||
Entity *entity)
|
||||
{
|
||||
ASSERT(entity->vertexPoints);
|
||||
ASSERT(entity->numVertexPoints >= 3);
|
||||
|
||||
v2 *result =
|
||||
memory_pushBytes(transientArena, entity->numVertexPoints * sizeof(v2));
|
||||
|
||||
@ -98,9 +102,10 @@ v2 *entity_createVertexList(MemoryArena_ *transientArena, Entity *entity)
|
||||
{
|
||||
result[i] = v2_add(entity->vertexPoints[i], entity->offset);
|
||||
result[i] = v2_add(result[i], entity->pos);
|
||||
|
||||
}
|
||||
|
||||
math_applyRotationToVertexes(result[0], entity->offset,
|
||||
math_applyRotationToVertexes(entity->pos, V2(0 ,0),
|
||||
DEGREES_TO_RADIANS(entity->rotation), result,
|
||||
entity->numVertexPoints);
|
||||
|
||||
|
@ -574,11 +574,15 @@ void renderer_entity(Renderer *renderer, MemoryArena_ *transientArena,
|
||||
renderTex.texRect = texRect;
|
||||
}
|
||||
|
||||
// TODO(doyle): Proper blending
|
||||
v4 renderColor = color;
|
||||
if (v4_equals(color, V4(0, 0, 0, 0))) renderColor = entity->color;
|
||||
|
||||
if (entity->renderMode == rendermode_quad)
|
||||
{
|
||||
renderer_rect(renderer, camera, entity->pos, entity->size,
|
||||
v2_add(entity->offset, pivotPoint), totalRotation,
|
||||
&renderTex, color, flags);
|
||||
&renderTex, entity->color, flags);
|
||||
}
|
||||
else if (entity->renderMode == rendermode_polygon)
|
||||
{
|
||||
@ -586,12 +590,12 @@ void renderer_entity(Renderer *renderer, MemoryArena_ *transientArena,
|
||||
ASSERT(entity->vertexPoints);
|
||||
|
||||
v2 *offsetVertexPoints =
|
||||
entity_createVertexList(transientArena, entity);
|
||||
entity_generateUpdatedVertexList(transientArena, entity);
|
||||
|
||||
renderer_polygon(renderer, camera, offsetVertexPoints,
|
||||
entity->numVertexPoints,
|
||||
v2_add(entity->offset, pivotPoint), totalRotation,
|
||||
&renderTex, color, flags);
|
||||
&renderTex, renderColor, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -172,8 +172,13 @@ i32 main(void)
|
||||
memory.transientSize = transientSize;
|
||||
memory.transient = PLATFORM_MEM_ALLOC_(NULL, transientSize, u8);
|
||||
|
||||
GameState gameState = {0};
|
||||
glfwSetWindowUserPointer(window, CAST(void *)(&gameState));
|
||||
MemoryArena_ gameArena = {0};
|
||||
memory_arenaInit(&gameArena, memory.persistent, memory.persistentSize);
|
||||
|
||||
GameState *gameState = MEMORY_PUSH_STRUCT(&gameArena, GameState);
|
||||
gameState->persistentArena = gameArena;
|
||||
|
||||
glfwSetWindowUserPointer(window, CAST(void *)(gameState));
|
||||
|
||||
/*
|
||||
*******************
|
||||
@ -203,7 +208,7 @@ i32 main(void)
|
||||
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
asteroid_gameUpdateAndRender(&gameState, &memory, windowSize,
|
||||
asteroid_gameUpdateAndRender(gameState, &memory, windowSize,
|
||||
secondsElapsed);
|
||||
GL_CHECK_ERROR();
|
||||
|
||||
@ -233,7 +238,7 @@ i32 main(void)
|
||||
char textBuffer[256];
|
||||
snprintf(textBuffer, ARRAY_COUNT(textBuffer),
|
||||
"Dengine | %f ms/f | %f fps | Entity Count: %d",
|
||||
msPerFrame, framesPerSecond, gameState.entityIndex);
|
||||
msPerFrame, framesPerSecond, gameState->world.entityIndex);
|
||||
|
||||
glfwSetWindowTitle(window, textBuffer);
|
||||
titleUpdateFrequencyInSeconds = 0.5f;
|
||||
|
@ -8,23 +8,35 @@
|
||||
#include "Dengine/Platform.h"
|
||||
#include "Dengine/Renderer.h"
|
||||
|
||||
typedef struct World
|
||||
{
|
||||
MemoryArena_ entityArena;
|
||||
|
||||
v2 *entityVertexListCache[entitytype_count];
|
||||
Entity entityList[1024];
|
||||
i32 entityIndex;
|
||||
|
||||
u32 entityIdCounter;
|
||||
|
||||
f32 pixelsPerMeter;
|
||||
v2 worldSize;
|
||||
Rect camera;
|
||||
|
||||
// TODO(doyle): Ensure we change this if it gets too big
|
||||
b32 collisionTable[entitytype_count][entitytype_count];
|
||||
} World;
|
||||
|
||||
typedef struct GameState {
|
||||
b32 init;
|
||||
|
||||
Entity entityList[1024];
|
||||
i32 entityIndex;
|
||||
f32 pixelsPerMeter;
|
||||
|
||||
v2 worldSize;
|
||||
|
||||
Rect camera;
|
||||
|
||||
World world;
|
||||
AssetManager assetManager;
|
||||
KeyInput input;
|
||||
|
||||
MemoryArena_ transientArena;
|
||||
MemoryArena_ persistentArena;
|
||||
|
||||
|
||||
Renderer renderer;
|
||||
} GameState;
|
||||
|
||||
|
@ -28,6 +28,7 @@ enum EntityType
|
||||
entitytype_invalid,
|
||||
entitytype_ship,
|
||||
entitytype_asteroid,
|
||||
entitytype_bullet,
|
||||
entitytype_count,
|
||||
};
|
||||
|
||||
@ -42,10 +43,7 @@ typedef struct EntityAnim
|
||||
|
||||
typedef struct Entity
|
||||
{
|
||||
i32 id;
|
||||
|
||||
i32 childIds[8];
|
||||
i32 numChilds;
|
||||
u32 id;
|
||||
|
||||
v2 pos;
|
||||
v2 dP;
|
||||
@ -53,11 +51,11 @@ typedef struct Entity
|
||||
v2 hitbox;
|
||||
v2 size;
|
||||
|
||||
// NOTE(doyle): Offset from origin point to the entity's considered "center"
|
||||
// point, all operations work from this point, i.e. rotation, movement,
|
||||
// collision detection
|
||||
// If this is a polygon, the offset should be from the 1st vertex point
|
||||
// specified
|
||||
/*
|
||||
NOTE(doyle): Offset is the vector to shift the polygons "origin" to the
|
||||
world origin. In our case this should strictly be negative as we have
|
||||
a requirement that all vertex points must be strictly positive.
|
||||
*/
|
||||
v2 offset;
|
||||
|
||||
enum RenderMode renderMode;
|
||||
@ -70,17 +68,11 @@ typedef struct Entity
|
||||
enum EntityType type;
|
||||
enum Direction direction;
|
||||
|
||||
v4 color;
|
||||
Texture *tex;
|
||||
b32 flipX;
|
||||
b32 flipY;
|
||||
|
||||
// TODO(doyle): Two collision flags, we want certain entities to collide
|
||||
// with certain types of entities only (i.e. projectile from hero to enemy,
|
||||
// only collides with enemy). Having two flags is redundant, but! it does
|
||||
// allow for early-exit in collision check if the entity doesn't collide at
|
||||
// all
|
||||
b32 collides;
|
||||
|
||||
EntityAnim animList[16];
|
||||
i32 animListIndex;
|
||||
|
||||
@ -95,5 +87,6 @@ void entity_updateAnim(Entity *const entity, const f32 dt);
|
||||
void entity_addAnim(AssetManager *const assetManager, Entity *const entity,
|
||||
const char *const animName);
|
||||
|
||||
v2 *entity_createVertexList(MemoryArena_ *transientArena, Entity *entity);
|
||||
v2 *entity_generateUpdatedVertexList(MemoryArena_ *transientArena,
|
||||
Entity *entity);
|
||||
#endif
|
||||
|
@ -410,5 +410,23 @@ INTERNAL inline void math_applyRotationToVertexes(v2 pos, v2 pivotPoint,
|
||||
vertexList[i] = newP;
|
||||
}
|
||||
}
|
||||
INTERNAL inline f32 math_lerp(f32 a, f32 t, f32 b)
|
||||
{
|
||||
/*
|
||||
Linear blend between two values. We having a starting point "a", and
|
||||
the distance to "b" is defined as (b - a). Then we can say
|
||||
|
||||
a + t(b - a)
|
||||
|
||||
As our linear blend fn. We start from "a" and choosing a t from 0->1
|
||||
will vary the value of (b - a) towards b. If we expand this, this
|
||||
becomes
|
||||
|
||||
a + (t * b) - (a * t) == (1 - t)a + t*b
|
||||
*/
|
||||
f32 result = ((1 - t) * a) + (t * b);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user