Add asteroid collision handling
This commit is contained in:
parent
42ba86f05a
commit
be1c009dfb
158
src/Asteroid.c
158
src/Asteroid.c
@ -286,7 +286,7 @@ b32 checkEdgeProjectionOverlap(v2 *vertexList, i32 listSize,
|
||||
return result;
|
||||
}
|
||||
|
||||
INTERNAL b32 moveEntity(World *world, MemoryArena_ *transientArena,
|
||||
INTERNAL u32 moveEntity(World *world, MemoryArena_ *transientArena,
|
||||
Entity *entity, i32 entityIndex, v2 ddP, f32 dt,
|
||||
f32 ddPSpeed)
|
||||
{
|
||||
@ -312,12 +312,12 @@ INTERNAL b32 moveEntity(World *world, MemoryArena_ *transientArena,
|
||||
|
||||
v2 newPos = v2_add(v2_add(ddPHalfDtSquared, oldDpDt), oldPos);
|
||||
|
||||
b32 willCollide = FALSE;
|
||||
|
||||
i32 collisionIndex = -1;
|
||||
// TODO(doyle): Collision for rects, (need to create vertex list for it)
|
||||
#if 1
|
||||
for (i32 i = entityIndex + 1; i < world->entityIndex; i++)
|
||||
for (i32 i = 1; i < world->entityIndex; i++)
|
||||
{
|
||||
if (i == entityIndex) continue;
|
||||
|
||||
Entity *checkEntity = &world->entityList[i];
|
||||
ASSERT(checkEntity->id != entity->id);
|
||||
|
||||
@ -362,38 +362,23 @@ INTERNAL b32 moveEntity(World *world, MemoryArena_ *transientArena,
|
||||
checkEntityVertexListOffsetToP,
|
||||
checkEntity->numVertexPoints, edgeList, totalNumEdges))
|
||||
{
|
||||
willCollide = TRUE;
|
||||
collisionIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (willCollide)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (!willCollide)
|
||||
{
|
||||
entity->dP = newDp;
|
||||
entity->pos = newPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
entity->dP = v2_scale(newDp, -1.0f);
|
||||
if (collisionIndex != -1) break;
|
||||
}
|
||||
|
||||
#else
|
||||
entity->dP = newDp;
|
||||
entity->pos = newPos;
|
||||
#endif
|
||||
|
||||
return willCollide;
|
||||
return collisionIndex;
|
||||
}
|
||||
|
||||
INTERNAL void addAsteroid(World *world, v2 windowSize)
|
||||
{
|
||||
world->asteroidCounter++;
|
||||
|
||||
Entity *asteroid = &world->entityList[world->entityIndex++];
|
||||
asteroid->id = world->entityIdCounter++;
|
||||
|
||||
@ -410,10 +395,16 @@ INTERNAL void addAsteroid(World *world, v2 windowSize)
|
||||
asteroid->renderMode = rendermode_polygon;
|
||||
|
||||
asteroid->numVertexPoints = 10;
|
||||
asteroid->vertexPoints = createAsteroidVertexList(
|
||||
&world->entityArena, asteroid->numVertexPoints,
|
||||
(i32)(asteroid->size.w * 0.5f));
|
||||
|
||||
i32 cacheIndex = randValue % ARRAY_COUNT(world->asteroidVertexCache);
|
||||
if (!world->asteroidVertexCache[cacheIndex])
|
||||
{
|
||||
world->asteroidVertexCache[cacheIndex] = createAsteroidVertexList(
|
||||
&world->entityArena, asteroid->numVertexPoints,
|
||||
(i32)(asteroid->size.w * 0.5f));
|
||||
}
|
||||
|
||||
asteroid->vertexPoints = world->asteroidVertexCache[cacheIndex];
|
||||
asteroid->color = V4(0.0f, 0.5f, 0.5f, 1.0f);
|
||||
}
|
||||
|
||||
@ -429,14 +420,17 @@ INTERNAL void addBullet(World *world, Entity *shooter)
|
||||
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;
|
||||
if (!world->bulletVertexCache)
|
||||
{
|
||||
world->bulletVertexCache =
|
||||
memory_pushBytes(&world->entityArena, sizeof(v2) * 4);
|
||||
world->bulletVertexCache[0] = V2(0, bullet->size.h);
|
||||
world->bulletVertexCache[1] = V2(0, 0);
|
||||
world->bulletVertexCache[2] = V2(bullet->size.w, 0);
|
||||
world->bulletVertexCache[3] = bullet->size;
|
||||
}
|
||||
|
||||
bullet->vertexPoints = world->bulletVertexCache;
|
||||
bullet->numVertexPoints = 4;
|
||||
|
||||
bullet->type = entitytype_bullet;
|
||||
@ -475,10 +469,12 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
||||
u8 *arenaBase = state->transientArena.base + state->transientArena.size;
|
||||
memory_arenaInit(&world->entityArena, arenaBase, entityArenaSize);
|
||||
|
||||
{ // Init null entity
|
||||
Entity *nullEntity = &world->entityList[world->entityIndex++];
|
||||
nullEntity->id = world->entityIdCounter++;
|
||||
}
|
||||
{ // Init asteroid entities
|
||||
i32 numAsteroids = 15;
|
||||
for (i32 i = 0; i < numAsteroids; i++)
|
||||
addAsteroid(world, windowSize);
|
||||
world->numAsteroids = 15;
|
||||
}
|
||||
|
||||
{ // Init ship entity
|
||||
@ -524,6 +520,9 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
||||
state->assetManager.font);
|
||||
}
|
||||
|
||||
for (u32 i = world->asteroidCounter; i < world->numAsteroids; i++)
|
||||
addAsteroid(world, windowSize);
|
||||
|
||||
{
|
||||
KeyState *keys = state->input.keys;
|
||||
for (enum KeyCode code = 0; code < keycode_count; code++)
|
||||
@ -555,24 +554,13 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
||||
addAsteroid(world, windowSize);
|
||||
}
|
||||
|
||||
for (i32 i = 0; i < world->entityIndex; i++)
|
||||
ASSERT(world->entityList[0].id == NULL_ENTITY_ID);
|
||||
for (i32 i = 1; i < world->entityIndex; i++)
|
||||
{
|
||||
Entity *entity = &world->entityList[i];
|
||||
ASSERT(entity->type != entitytype_invalid);
|
||||
|
||||
v2 pivotPoint = {0};
|
||||
|
||||
// Loop entity around world
|
||||
if (entity->pos.y >= world->worldSize.h)
|
||||
entity->pos.y = 0;
|
||||
else if (entity->pos.y < 0)
|
||||
entity->pos.y = world->worldSize.h;
|
||||
|
||||
if (entity->pos.x >= world->worldSize.w)
|
||||
entity->pos.x = 0;
|
||||
else if (entity->pos.x < 0)
|
||||
entity->pos.x = world->worldSize.w;
|
||||
|
||||
f32 ddPSpeedInMs = 0;
|
||||
v2 ddP = {0};
|
||||
if (entity->type == entitytype_ship)
|
||||
@ -604,7 +592,7 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
||||
}
|
||||
|
||||
if (getKeyStatus(&state->input.keys[keycode_space],
|
||||
readkeytype_delayedRepeat, 0.0f, dt))
|
||||
readkeytype_delayedRepeat, 0.05f, dt))
|
||||
{
|
||||
addBullet(world, entity);
|
||||
}
|
||||
@ -637,7 +625,6 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
||||
}
|
||||
|
||||
v2 ddP = {0};
|
||||
#if 1
|
||||
switch (entity->direction)
|
||||
{
|
||||
case direction_north:
|
||||
@ -707,30 +694,71 @@ void asteroid_gameUpdateAndRender(GameState *state, Memory *memory,
|
||||
ddPSpeedInMs = 1;
|
||||
entity->dP = v2_scale(ddP, world->pixelsPerMeter * ddPSpeedInMs);
|
||||
entity->rotation += (60 * dt);
|
||||
#endif
|
||||
}
|
||||
else if (entity->type == entitytype_bullet)
|
||||
{
|
||||
ddPSpeedInMs = 5;
|
||||
if (!math_pointInRect(world->camera, entity->pos))
|
||||
{
|
||||
world->entityList[i--] =
|
||||
world->entityList[--world->entityIndex];
|
||||
continue;
|
||||
}
|
||||
|
||||
ddPSpeedInMs = 25;
|
||||
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(world, &state->transientArena, entity, i,
|
||||
ddP, dt, ddPSpeedInMs);
|
||||
// Loop entity around world
|
||||
if (entity->pos.y >= world->worldSize.h)
|
||||
entity->pos.y = 0;
|
||||
else if (entity->pos.y < 0)
|
||||
entity->pos.y = world->worldSize.h;
|
||||
|
||||
if (entity->pos.x >= world->worldSize.w)
|
||||
entity->pos.x = 0;
|
||||
else if (entity->pos.x < 0)
|
||||
entity->pos.x = world->worldSize.w;
|
||||
|
||||
i32 collisionIndex = moveEntity(world, &state->transientArena, entity,
|
||||
i, ddP, dt, ddPSpeedInMs);
|
||||
|
||||
v4 collideColor = {0};
|
||||
if (willCollide)
|
||||
if (collisionIndex != -1)
|
||||
{
|
||||
collideColor = V4(1.0f, 0, 0, 0.5f);
|
||||
}
|
||||
ASSERT(collisionIndex < world->entityIndex);
|
||||
|
||||
if (entity->type == entitytype_bullet)
|
||||
{
|
||||
if (!math_pointInRect(world->camera, entity->pos))
|
||||
Entity *collideEntity = &world->entityList[collisionIndex];
|
||||
|
||||
Entity *colliderA;
|
||||
Entity *colliderB;
|
||||
|
||||
if (collideEntity->type < entity->type)
|
||||
{
|
||||
world->entityList[i] = world->entityList[--world->entityIndex];
|
||||
i--;
|
||||
colliderA = collideEntity;
|
||||
colliderB = entity;
|
||||
}
|
||||
else
|
||||
{
|
||||
colliderA = entity;
|
||||
colliderB = collideEntity;
|
||||
}
|
||||
|
||||
if (colliderA->type == entitytype_asteroid)
|
||||
{
|
||||
ASSERT(colliderB->type == entitytype_bullet);
|
||||
|
||||
world->entityList[collisionIndex] =
|
||||
world->entityList[--world->entityIndex];
|
||||
|
||||
world->entityList[i--] =
|
||||
world->entityList[--world->entityIndex];
|
||||
|
||||
world->asteroidCounter--;
|
||||
|
||||
ASSERT(world->asteroidCounter >= 0);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -15,9 +15,14 @@ typedef struct World
|
||||
v2 *entityVertexListCache[entitytype_count];
|
||||
Entity entityList[1024];
|
||||
i32 entityIndex;
|
||||
|
||||
u32 entityIdCounter;
|
||||
|
||||
u32 asteroidCounter;
|
||||
u32 numAsteroids;
|
||||
|
||||
v2 *asteroidVertexCache[10];
|
||||
v2 *bulletVertexCache;
|
||||
|
||||
f32 pixelsPerMeter;
|
||||
v2 worldSize;
|
||||
Rect camera;
|
||||
@ -36,7 +41,6 @@ typedef struct GameState {
|
||||
MemoryArena_ transientArena;
|
||||
MemoryArena_ persistentArena;
|
||||
|
||||
|
||||
Renderer renderer;
|
||||
} GameState;
|
||||
|
||||
|
@ -23,9 +23,11 @@ enum Direction
|
||||
direction_num,
|
||||
};
|
||||
|
||||
#define NULL_ENTITY_ID 0
|
||||
enum EntityType
|
||||
{
|
||||
entitytype_invalid,
|
||||
entitytype_null,
|
||||
entitytype_ship,
|
||||
entitytype_asteroid,
|
||||
entitytype_bullet,
|
||||
|
Loading…
Reference in New Issue
Block a user