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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user