Moved game-logic to game_world_tick(..)
This commit is contained in:
@@ -123,6 +123,163 @@ void game_world_destroy_entity(Game_World *world, Entity_ID entity_id, bool dest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void game_world_tick(Game_World *world) {
|
||||||
|
// Game-logic! :)
|
||||||
|
|
||||||
|
for(uint16_t i = 0; i < world->max_entities; i++) {
|
||||||
|
Entity *entity = &world->entities[i];
|
||||||
|
if(!entity->active) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(entity->type) {
|
||||||
|
case Entity_Type_Snake_Head: {
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Entity_Type_Snake_Body: {
|
||||||
|
// Skip.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Entity_Type_Food: {
|
||||||
|
// Skip (for now).
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
printf("Unhandled entity-type %i.\n", entity->type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{ // Move entity
|
||||||
|
int16_t dx = 0;
|
||||||
|
int16_t dy = 0;
|
||||||
|
|
||||||
|
switch(entity->move_direction) {
|
||||||
|
case Entity_Movement_Direction_None: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Entity_Movement_Direction_Up: {
|
||||||
|
dy = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Entity_Movement_Direction_Down: {
|
||||||
|
dy = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Entity_Movement_Direction_Right: {
|
||||||
|
dx = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Entity_Movement_Direction_Left: {
|
||||||
|
dx = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dx != 0 || dy != 0) {
|
||||||
|
// Try moving.
|
||||||
|
|
||||||
|
// Figure out what cell we're on and what cell we want to go to.
|
||||||
|
Grid_Cell *current_cell = grid_get_cell(&world->grid, entity->x, entity->y);
|
||||||
|
assert(current_cell != NULL);
|
||||||
|
Grid_Cell *target_cell = grid_get_cell(&world->grid, entity->x + dx, entity->y + dy);
|
||||||
|
|
||||||
|
// { // Debug-logging.
|
||||||
|
// printf("Current cell = (x: %u, y: %u, entity: %p).\n", current_cell->x, current_cell->y, current_cell->entity);
|
||||||
|
// if(target_cell != NULL) {
|
||||||
|
// printf("Target cell = (x: %u, y: %u, entity: %p).\n", target_cell->x, target_cell->y, target_cell->entity);
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// printf("Target cell = NULL!\n");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
if(target_cell == NULL) {
|
||||||
|
// Target cell does not exist.
|
||||||
|
// TODO: SS - Check the session's settings.
|
||||||
|
// Maybe each session could decide whether the snake should "loop-around" or not.
|
||||||
|
// If the snake shouldn't loop around, die.
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bool should_move_to_target_cell = false;
|
||||||
|
bool snake_ate = false;
|
||||||
|
|
||||||
|
if(target_cell->entity != NULL) {
|
||||||
|
// Target cell is occupied.
|
||||||
|
|
||||||
|
// Check what type of entity it is and determine what should happen.
|
||||||
|
switch(target_cell->entity->type) {
|
||||||
|
case Entity_Type_Snake_Head: {
|
||||||
|
// TODO: SS - Die.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Entity_Type_Snake_Body: {
|
||||||
|
// TODO: SS - Die.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Entity_Type_Food: {
|
||||||
|
// Eat!
|
||||||
|
assert(grid_try_remove_entity_from_cell(target_cell));
|
||||||
|
|
||||||
|
snake_ate = true;
|
||||||
|
should_move_to_target_cell = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Target cell is unoccupied and free to enter.
|
||||||
|
should_move_to_target_cell = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(should_move_to_target_cell) {
|
||||||
|
{ // Move snake recursively.
|
||||||
|
Entity *e = entity;
|
||||||
|
Grid_Cell *t = target_cell;
|
||||||
|
while(e != NULL) {
|
||||||
|
Grid_Cell *a = grid_get_cell(&world->grid, e->x, e->y);
|
||||||
|
assert(a != NULL);
|
||||||
|
|
||||||
|
grid_move_entity_from_cell_to_cell(a, t);
|
||||||
|
|
||||||
|
e = game_world_try_get_entity_by_id(world, e->child);
|
||||||
|
t = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(snake_ate) {
|
||||||
|
Entity *e = entity;
|
||||||
|
uint16_t child_index = 0;
|
||||||
|
while(e->child != INVALID_ENTITY_ID) {
|
||||||
|
e = game_world_try_get_entity_by_id(world, e->child);
|
||||||
|
child_index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity_ID child_entity = INVALID_ENTITY_ID;
|
||||||
|
assert(game_world_create_entity(
|
||||||
|
world,
|
||||||
|
Entity_Type_Snake_Body,
|
||||||
|
e->prev_x,
|
||||||
|
e->prev_y,
|
||||||
|
&child_entity
|
||||||
|
));
|
||||||
|
|
||||||
|
assert(e->child == INVALID_ENTITY_ID);
|
||||||
|
e->child = child_entity;
|
||||||
|
|
||||||
|
{ // Spawn food.
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Entity *game_world_try_get_entity_by_id(Game_World *world, Entity_ID id) {
|
Entity *game_world_try_get_entity_by_id(Game_World *world, Entity_ID id) {
|
||||||
assert(world != NULL);
|
assert(world != NULL);
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ void game_world_destroy(Game_World *world);
|
|||||||
bool game_world_create_entity(Game_World *world, Entity_Type type, uint16_t x, uint16_t y, Entity_ID *out_entity_id);
|
bool game_world_create_entity(Game_World *world, Entity_Type type, uint16_t x, uint16_t y, Entity_ID *out_entity_id);
|
||||||
void game_world_destroy_entity(Game_World *world, Entity_ID entity_id, bool destroy_children);
|
void game_world_destroy_entity(Game_World *world, Entity_ID entity_id, bool destroy_children);
|
||||||
|
|
||||||
|
void game_world_tick(Game_World *world);
|
||||||
|
|
||||||
// TODO: SS - "void game_world_spawn_player(Game_World *world, ..)"
|
// TODO: SS - "void game_world_spawn_player(Game_World *world, ..)"
|
||||||
|
|
||||||
Entity *game_world_try_get_entity_by_id(Game_World *world, Entity_ID id);
|
Entity *game_world_try_get_entity_by_id(Game_World *world, Entity_ID id);
|
||||||
|
|||||||
@@ -181,156 +181,7 @@ void simulation_world_tick(Simulation_World *simulation_world) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Game-logic! :)
|
game_world_tick(gw);
|
||||||
|
|
||||||
for(uint16_t i = 0; i < gw->max_entities; i++) {
|
|
||||||
Entity *entity = &gw->entities[i];
|
|
||||||
if(!entity->active) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(entity->type) {
|
|
||||||
case Entity_Type_Snake_Head: {
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Entity_Type_Snake_Body: {
|
|
||||||
// Skip.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Entity_Type_Food: {
|
|
||||||
// Skip (for now).
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
printf("Unhandled entity-type %i.\n", entity->type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{ // Move entity
|
|
||||||
int16_t dx = 0;
|
|
||||||
int16_t dy = 0;
|
|
||||||
|
|
||||||
switch(entity->move_direction) {
|
|
||||||
case Entity_Movement_Direction_None: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Entity_Movement_Direction_Up: {
|
|
||||||
dy = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Entity_Movement_Direction_Down: {
|
|
||||||
dy = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Entity_Movement_Direction_Right: {
|
|
||||||
dx = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Entity_Movement_Direction_Left: {
|
|
||||||
dx = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dx != 0 || dy != 0) {
|
|
||||||
// Try moving.
|
|
||||||
|
|
||||||
// Figure out what cell we're on and what cell we want to go to.
|
|
||||||
Grid_Cell *current_cell = grid_get_cell(&gw->grid, entity->x, entity->y);
|
|
||||||
assert(current_cell != NULL);
|
|
||||||
Grid_Cell *target_cell = grid_get_cell(&gw->grid, entity->x + dx, entity->y + dy);
|
|
||||||
|
|
||||||
// { // Debug-logging.
|
|
||||||
// printf("Current cell = (x: %u, y: %u, entity: %p).\n", current_cell->x, current_cell->y, current_cell->entity);
|
|
||||||
// if(target_cell != NULL) {
|
|
||||||
// printf("Target cell = (x: %u, y: %u, entity: %p).\n", target_cell->x, target_cell->y, target_cell->entity);
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// printf("Target cell = NULL!\n");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
if(target_cell == NULL) {
|
|
||||||
// Target cell does not exist.
|
|
||||||
// TODO: SS - Check the session's settings.
|
|
||||||
// Maybe each session could decide whether the snake should "loop-around" or not.
|
|
||||||
// If the snake shouldn't loop around, die.
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
bool should_move_to_target_cell = false;
|
|
||||||
bool snake_should_grow = false;
|
|
||||||
|
|
||||||
if(target_cell->entity != NULL) {
|
|
||||||
// Target cell is occupied.
|
|
||||||
|
|
||||||
// Check what type of entity it is and determine what should happen.
|
|
||||||
switch(target_cell->entity->type) {
|
|
||||||
case Entity_Type_Snake_Head: {
|
|
||||||
// TODO: SS - Die.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Entity_Type_Snake_Body: {
|
|
||||||
// TODO: SS - Die.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Entity_Type_Food: {
|
|
||||||
// Eat!
|
|
||||||
assert(grid_try_remove_entity_from_cell(target_cell));
|
|
||||||
|
|
||||||
snake_should_grow = true;
|
|
||||||
should_move_to_target_cell = true;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Target cell is unoccupied and free to enter.
|
|
||||||
should_move_to_target_cell = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(should_move_to_target_cell) {
|
|
||||||
{ // Move snake recursively.
|
|
||||||
Entity *e = entity;
|
|
||||||
Grid_Cell *t = target_cell;
|
|
||||||
while(e != NULL) {
|
|
||||||
Grid_Cell *a = grid_get_cell(&gw->grid, e->x, e->y);
|
|
||||||
assert(a != NULL);
|
|
||||||
|
|
||||||
grid_move_entity_from_cell_to_cell(a, t);
|
|
||||||
|
|
||||||
e = game_world_try_get_entity_by_id(gw, e->child);
|
|
||||||
t = a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(snake_should_grow) {
|
|
||||||
Entity *e = entity;
|
|
||||||
uint16_t child_index = 0;
|
|
||||||
while(e->child != INVALID_ENTITY_ID) {
|
|
||||||
e = game_world_try_get_entity_by_id(gw, e->child);
|
|
||||||
child_index += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Entity_ID child_entity = INVALID_ENTITY_ID;
|
|
||||||
assert(game_world_create_entity(
|
|
||||||
gw,
|
|
||||||
Entity_Type_Snake_Body,
|
|
||||||
e->prev_x,
|
|
||||||
e->prev_y,
|
|
||||||
&child_entity
|
|
||||||
));
|
|
||||||
|
|
||||||
assert(e->child == INVALID_ENTITY_ID);
|
|
||||||
e->child = child_entity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user