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