The snake must grow.
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 643 B After Width: | Height: | Size: 643 B |
@@ -80,6 +80,10 @@ static void state_tick(Presentation_State *state) {
|
||||
game_session_update(session, delta_time);
|
||||
|
||||
{ // TEMP: SS
|
||||
if(IsKeyPressed(KEY_TAB)) {
|
||||
ctx->debug_render_match_state = !ctx->debug_render_match_state;
|
||||
}
|
||||
|
||||
if(IsKeyPressed(KEY_ESCAPE)) {
|
||||
presentation_state_machine_go_to(&presentation_state_main_menu);
|
||||
}
|
||||
@@ -196,7 +200,7 @@ static void state_render(Presentation_State *state) {
|
||||
},
|
||||
(Rectangle) { // Destination.
|
||||
pres_x + origin.x,
|
||||
pres_y + origin.y + ENTITY_PRESENTATION_Y_OFFSET - (sin(GetTime() * sin_frequency)) * sin_amplitude,
|
||||
pres_y + origin.y + ENTITY_PRESENTATION_Y_OFFSET - (sin((GetTime() + (float)(entity->child_index) / 4.0) * sin_frequency)) * sin_amplitude,
|
||||
GRID_CELL_SIZE,
|
||||
GRID_CELL_SIZE
|
||||
},
|
||||
@@ -245,11 +249,11 @@ static void state_render(Presentation_State *state) {
|
||||
|
||||
// TODO: SS - Switch on 'sim_world->match_state'.
|
||||
|
||||
{ // TEMP: SS - Render match state.
|
||||
if(ctx->debug_render_match_state) {
|
||||
char buf[512];
|
||||
snprintf(&buf[0], sizeof(buf), "Match-state: %i. Tick: %lu.", sim_world->match_state, sim_world->tick);
|
||||
|
||||
DrawText(buf, 32, 32, 12, RED);
|
||||
DrawText(buf, 16, 16, 8, RED);
|
||||
}
|
||||
}
|
||||
EndMode2D();
|
||||
|
||||
@@ -15,6 +15,10 @@ typedef struct {
|
||||
Texture2D texture_apple;
|
||||
Texture2D texture_snake_head;
|
||||
Texture2D texture_snake_body;
|
||||
|
||||
// Debug.
|
||||
bool debug_render_match_state;
|
||||
|
||||
} Presentation_State_Ingame_Context;
|
||||
|
||||
void presentation_state_ingame_init(Presentation_State_Ingame_Context *ctx);
|
||||
|
||||
@@ -32,10 +32,14 @@ typedef struct {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
|
||||
uint16_t prev_x;
|
||||
uint16_t prev_y;
|
||||
|
||||
Entity_Movement_Direction move_direction;
|
||||
Entity_Movement_Direction prev_move_direction;
|
||||
|
||||
Entity_ID child;
|
||||
uint16_t child_index; // Primarily used when presenting the body-parts.
|
||||
|
||||
// TODO: SS - Color/tint?
|
||||
} Entity;
|
||||
|
||||
@@ -14,6 +14,7 @@ Game_World *game_world_create(uint32_t seed, uint16_t level_width, uint16_t leve
|
||||
Game_World *w = (Game_World *)calloc(1, sizeof(Game_World));
|
||||
assert(w != NULL);
|
||||
w->seed = seed;
|
||||
random_init(&w->random_generator, w->seed);
|
||||
|
||||
w->max_entities = level_width * level_height;
|
||||
w->entities = (Entity *)calloc(w->max_entities, sizeof(Entity));
|
||||
@@ -28,13 +29,16 @@ Game_World *game_world_create(uint32_t seed, uint16_t level_width, uint16_t leve
|
||||
grid_initialize(&w->grid, level_width, level_height);
|
||||
|
||||
{ // TEMP: SS - Testing ..
|
||||
Entity_ID entity_food;
|
||||
assert(game_world_create_entity(
|
||||
w,
|
||||
Entity_Type_Food,
|
||||
4, 8,
|
||||
&entity_food
|
||||
));
|
||||
for(uint16_t i = 0; i < 8; i++) {
|
||||
Entity_ID entity_food;
|
||||
assert(game_world_create_entity(
|
||||
w,
|
||||
Entity_Type_Food,
|
||||
(uint16_t)random_u32_range(&w->random_generator, 0, level_width),
|
||||
(uint16_t)random_u32_range(&w->random_generator, 0, level_height),
|
||||
&entity_food
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return w;
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
#include "entity.h"
|
||||
#include "grid.h"
|
||||
#include "shared/squeue.h"
|
||||
#include "shared/random.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t seed;
|
||||
Random_Generator random_generator;
|
||||
|
||||
SQueue entity_id_queue;
|
||||
Entity *entities;
|
||||
|
||||
@@ -115,6 +115,12 @@ void grid_move_entity_from_cell_to_cell(Grid_Cell *cell_a, Grid_Cell *cell_b) {
|
||||
|
||||
Entity *entity_to_be_moved = cell_a->entity;
|
||||
|
||||
uint16_t start_x = cell_a->x;
|
||||
uint16_t start_y = cell_a->y;
|
||||
|
||||
assert(grid_try_remove_entity_from_cell(cell_a));
|
||||
assert(grid_try_add_entity_to_cell(cell_b, entity_to_be_moved));
|
||||
|
||||
entity_to_be_moved->prev_x = start_x;
|
||||
entity_to_be_moved->prev_y = start_y;
|
||||
}
|
||||
25
src/shared/random.c
Normal file
25
src/shared/random.c
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "random.h"
|
||||
|
||||
void random_init(Random_Generator *random_generator, uint32_t seed) {
|
||||
if(seed == 0) {
|
||||
seed = 1;
|
||||
}
|
||||
random_generator->seed = seed;
|
||||
random_generator->state = random_generator->seed;
|
||||
}
|
||||
|
||||
uint32_t random_u32(Random_Generator *random_generator) {
|
||||
uint32_t x = random_generator->state;
|
||||
|
||||
x ^= x << 13;
|
||||
x ^= x >> 17;
|
||||
x ^= x << 5;
|
||||
|
||||
random_generator->state = x;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
uint32_t random_u32_range(Random_Generator *random_generator, uint32_t min, uint32_t max) {
|
||||
return min + (random_u32(random_generator) % (max - min + 1));
|
||||
}
|
||||
@@ -1,34 +1,17 @@
|
||||
#ifndef RANDOM_H
|
||||
#define RANDOM_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint32_t seed;
|
||||
uint32_t state;
|
||||
} Random_Generator;
|
||||
|
||||
static inline void random_init(Random_Generator *random_generator, uint32_t seed) {
|
||||
if(seed == 0) {
|
||||
seed = 1;
|
||||
}
|
||||
random_generator->seed = seed;
|
||||
random_generator->state = random_generator->seed;
|
||||
}
|
||||
void random_init(Random_Generator *random_generator, uint32_t seed);
|
||||
|
||||
static inline uint32_t random_next_u32(Random_Generator *random_generator) {
|
||||
uint32_t x = random_generator->state;
|
||||
|
||||
x ^= x << 13;
|
||||
x ^= x >> 17;
|
||||
x ^= x << 5;
|
||||
|
||||
random_generator->state = x;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline uint32_t random_u64_range(Random_Generator *random_generator, uint32_t min, uint32_t max) {
|
||||
return min + (random_next_u32(rng) % (max - min + 1));
|
||||
}
|
||||
uint32_t random_u32(Random_Generator *random_generator);
|
||||
uint32_t random_u32_range(Random_Generator *random_generator, uint32_t min, uint32_t max);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -111,7 +111,7 @@ void simulation_world_tick(Simulation_World *simulation_world) {
|
||||
break;
|
||||
}
|
||||
case Simulation_Match_State_Counting_Down: {
|
||||
if(simulation_world->tick > 50) { // TEMP: SS - Hardcoded number and condition to break out of this state.
|
||||
if(simulation_world->tick > 20) { // TEMP: SS - Hardcoded number and condition to break out of this state.
|
||||
simulation_world->match_state = Simulation_Match_State_Active;
|
||||
}
|
||||
|
||||
@@ -308,19 +308,31 @@ void simulation_world_tick(Simulation_World *simulation_world) {
|
||||
t = a;
|
||||
}
|
||||
}
|
||||
// // TODO: SS - Recurse through this entity's children and move them too.
|
||||
// if(entity->child != INVALID_ENTITY_ID) {
|
||||
// printf("TODO: SS - MOVE CHILDREN TOO!\n");
|
||||
// }
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// TODO: SS - Spawn the entity and make it a child of the snake's last child.
|
||||
Entity_ID child_entity = INVALID_ENTITY_ID;
|
||||
assert(game_world_create_entity(gw, Entity_Type_Snake_Body, start_cell->x, start_cell->y, &child_entity));
|
||||
assert(game_world_create_entity(
|
||||
gw,
|
||||
Entity_Type_Snake_Body,
|
||||
e->prev_x,
|
||||
e->prev_y,
|
||||
&child_entity
|
||||
));
|
||||
|
||||
assert(entity->child == INVALID_ENTITY_ID);
|
||||
entity->child = child_entity;
|
||||
assert(e->child == INVALID_ENTITY_ID);
|
||||
e->child = child_entity;
|
||||
|
||||
Entity *child = game_world_try_get_entity_by_id(gw, child_entity);
|
||||
assert(child != NULL);
|
||||
child->child_index = child_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user