Compare commits
10 Commits
917fdeba9b
...
6097ec6e0d
Author | SHA1 | Date |
---|---|---|
|
6097ec6e0d | |
|
89d962d2bc | |
|
6e2ccfa875 | |
|
7607827420 | |
|
34655d5c0a | |
|
dc20a6b992 | |
|
a080b5ee0a | |
|
7af75b8366 | |
|
a0f6cf3471 | |
|
5b3cbd1bba |
|
@ -141,9 +141,27 @@ typedef struct _BFSTileMap {
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
}BFSTileMap_t;
|
}BFSTileMap_t;
|
||||||
|
|
||||||
|
typedef enum _WaterRunnerState
|
||||||
|
{
|
||||||
|
BFS_RESET = 0,
|
||||||
|
BFS_START,
|
||||||
|
LOWEST_POINT_SEARCH,
|
||||||
|
LOWEST_POINT_MOVEMENT,
|
||||||
|
REACHABILITY_SEARCH,
|
||||||
|
SCANLINE_FILL,
|
||||||
|
FILL_COMPLETE,
|
||||||
|
}WaterRunerState_t;
|
||||||
|
|
||||||
typedef struct _CWaterRunner {
|
typedef struct _CWaterRunner {
|
||||||
int32_t current_tile;
|
|
||||||
BFSTileMap_t bfs_tilemap;
|
BFSTileMap_t bfs_tilemap;
|
||||||
|
WaterRunerState_t state;
|
||||||
|
struct sc_queue_32 bfs_queue;
|
||||||
|
bool* visited;
|
||||||
|
int32_t current_tile;
|
||||||
|
int32_t target_tile;
|
||||||
|
int32_t fill_idx;
|
||||||
|
uint8_t movement_delay;
|
||||||
|
int16_t counter;
|
||||||
}CWaterRunner_t;
|
}CWaterRunner_t;
|
||||||
|
|
||||||
// Credits to bedroomcoders.co.uk for this
|
// Credits to bedroomcoders.co.uk for this
|
||||||
|
|
|
@ -27,6 +27,7 @@ typedef struct TileGrid
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
unsigned int n_tiles;
|
unsigned int n_tiles;
|
||||||
unsigned int tile_size;
|
unsigned int tile_size;
|
||||||
|
unsigned int max_water_level;
|
||||||
Tile_t* tiles;
|
Tile_t* tiles;
|
||||||
}TileGrid_t;
|
}TileGrid_t;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "water_flow.h"
|
#include "water_flow.h"
|
||||||
|
#include "sc/queue/sc_queue.h"
|
||||||
|
#include <stdio.h>
|
||||||
Entity_t* create_water_runner(EntityManager_t* ent_manager, int32_t width, int32_t height, int32_t start_tile)
|
Entity_t* create_water_runner(EntityManager_t* ent_manager, int32_t width, int32_t height, int32_t start_tile)
|
||||||
{
|
{
|
||||||
Entity_t* p_filler = add_entity(ent_manager, DYNMEM_ENT_TAG);
|
Entity_t* p_filler = add_entity(ent_manager, DYNMEM_ENT_TAG);
|
||||||
|
@ -21,8 +21,13 @@ Entity_t* create_water_runner(EntityManager_t* ent_manager, int32_t width, int32
|
||||||
p_crunner->bfs_tilemap.width = width;
|
p_crunner->bfs_tilemap.width = width;
|
||||||
p_crunner->bfs_tilemap.height = height;
|
p_crunner->bfs_tilemap.height = height;
|
||||||
p_crunner->bfs_tilemap.len = total;
|
p_crunner->bfs_tilemap.len = total;
|
||||||
|
p_crunner->movement_delay = 5;
|
||||||
|
|
||||||
|
sc_queue_init(&p_crunner->bfs_queue);
|
||||||
|
p_crunner->visited = calloc(total, sizeof(bool));
|
||||||
|
|
||||||
p_crunner->current_tile = start_tile;
|
p_crunner->current_tile = start_tile;
|
||||||
|
p_crunner->target_tile = total;
|
||||||
|
|
||||||
CTransform_t* p_ct = add_component(p_filler, CTRANSFORM_COMP_T);
|
CTransform_t* p_ct = add_component(p_filler, CTRANSFORM_COMP_T);
|
||||||
p_ct->movement_mode = KINEMATIC_MOVEMENT;
|
p_ct->movement_mode = KINEMATIC_MOVEMENT;
|
||||||
|
@ -34,9 +39,95 @@ void free_water_runner(Entity_t* ent, EntityManager_t* ent_manager)
|
||||||
{
|
{
|
||||||
CWaterRunner_t* p_crunner = get_component(ent, CWATERRUNNER_T);
|
CWaterRunner_t* p_crunner = get_component(ent, CWATERRUNNER_T);
|
||||||
free(p_crunner->bfs_tilemap.tilemap);
|
free(p_crunner->bfs_tilemap.tilemap);
|
||||||
|
free(p_crunner->visited);
|
||||||
|
sc_queue_term(&p_crunner->bfs_queue);
|
||||||
remove_entity(ent_manager, ent->m_id);
|
remove_entity(ent_manager, ent->m_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void runner_BFS(const TileGrid_t* tilemap, CWaterRunner_t* p_crunner, int32_t* lowest_tile, int32_t start_tile)
|
||||||
|
{
|
||||||
|
memset(p_crunner->visited, 0, p_crunner->bfs_tilemap.len * sizeof(bool));
|
||||||
|
p_crunner->visited[start_tile] = true;
|
||||||
|
p_crunner->bfs_tilemap.tilemap[start_tile].reachable = true;
|
||||||
|
sc_queue_add_last(&p_crunner->bfs_queue, start_tile);
|
||||||
|
int init_height = start_tile / p_crunner->bfs_tilemap.width;
|
||||||
|
bool first_reached = false;
|
||||||
|
while (!sc_queue_empty(&p_crunner->bfs_queue))
|
||||||
|
{
|
||||||
|
const int curr_idx = sc_queue_peek_first(&p_crunner->bfs_queue);
|
||||||
|
sc_queue_del_first(&p_crunner->bfs_queue);
|
||||||
|
|
||||||
|
int curr_height = curr_idx / p_crunner->bfs_tilemap.width;
|
||||||
|
int curr_low = *lowest_tile / p_crunner->bfs_tilemap.width;
|
||||||
|
|
||||||
|
// Possible optimisation to avoid repeated BFS, dunno how possible
|
||||||
|
|
||||||
|
bool to_go[4] = {false, false, false, false};
|
||||||
|
Tile_t* curr_tile = tilemap->tiles + curr_idx;
|
||||||
|
|
||||||
|
int next = curr_idx + p_crunner->bfs_tilemap.width;
|
||||||
|
Tile_t* next_tile = tilemap->tiles + next;
|
||||||
|
|
||||||
|
if (
|
||||||
|
((curr_height <= init_height && !first_reached) || curr_height > curr_low)
|
||||||
|
&& curr_tile->water_level < tilemap->max_water_level
|
||||||
|
)
|
||||||
|
{
|
||||||
|
first_reached = true;
|
||||||
|
*lowest_tile = curr_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (next < p_crunner->bfs_tilemap.len)
|
||||||
|
{
|
||||||
|
to_go[0] = next_tile->solid != SOLID;
|
||||||
|
|
||||||
|
if (
|
||||||
|
next_tile->solid == SOLID
|
||||||
|
|| next_tile->water_level == tilemap->max_water_level
|
||||||
|
|| curr_tile->water_level == tilemap->max_water_level
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (curr_idx % p_crunner->bfs_tilemap.width != 0)
|
||||||
|
{
|
||||||
|
next = curr_idx - 1;
|
||||||
|
next_tile = tilemap->tiles + next;
|
||||||
|
to_go[1] = next_tile->solid != SOLID;
|
||||||
|
}
|
||||||
|
next = curr_idx + 1;
|
||||||
|
if (next % p_crunner->bfs_tilemap.width != 0)
|
||||||
|
{
|
||||||
|
next_tile = tilemap->tiles + next;
|
||||||
|
to_go[2] = next_tile->solid != SOLID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curr_tile->water_level == tilemap->max_water_level)
|
||||||
|
{
|
||||||
|
|
||||||
|
next = curr_idx - p_crunner->bfs_tilemap.width;
|
||||||
|
if (next >= 0)
|
||||||
|
{
|
||||||
|
next_tile = tilemap->tiles + next;
|
||||||
|
to_go[3] = next_tile->solid != SOLID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const int8_t offsets[4] = {p_crunner->bfs_tilemap.width, -1, 1, -p_crunner->bfs_tilemap.width};
|
||||||
|
for (uint8_t i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
next = curr_idx + offsets[i];
|
||||||
|
if (to_go[i] && !p_crunner->visited[next])
|
||||||
|
{
|
||||||
|
sc_queue_add_last(&p_crunner->bfs_queue, next);
|
||||||
|
p_crunner->bfs_tilemap.tilemap[next].from = curr_idx;
|
||||||
|
p_crunner->visited[next] = true;
|
||||||
|
p_crunner->bfs_tilemap.tilemap[next].reachable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void update_water_runner_system(Scene_t* scene)
|
void update_water_runner_system(Scene_t* scene)
|
||||||
{
|
{
|
||||||
|
@ -45,17 +136,169 @@ void update_water_runner_system(Scene_t* scene)
|
||||||
// - Scanline fill
|
// - Scanline fill
|
||||||
// A runner is given an amount of movement cost
|
// A runner is given an amount of movement cost
|
||||||
// Within the movement cost, do the following logic
|
// Within the movement cost, do the following logic
|
||||||
// Perform a modified DFS to find the lowest point:
|
// Perform a modified BFS to find the lowest point:
|
||||||
// - Solid tiles are not reachable
|
// - Solid tiles are not reachable
|
||||||
// - If bottom tile is non-solid, that is the only reachable tile,
|
// - If bottom tile is non-solid, that is the only reachable tile,
|
||||||
// - If bottom tile is filled with water fully, down+left+right are reachable
|
// - If bottom tile is filled with water fully, down+left+right are reachable
|
||||||
// - If bottom tile is solid, left+right are reachable
|
// - If bottom tile is solid, left+right are reachable
|
||||||
// - If bottom tile is OOB, terminate
|
// - If bottom tile is OOB, terminate
|
||||||
// Use a LIFO to deal with this.
|
// Use a FIFO to deal with this.
|
||||||
// On DFS completion, find the path to the lowest point. Keep track of this
|
// On DFS completion, find the path to the lowest point. Keep track of this
|
||||||
// The DFS should have figured out all reachable tiles, start scanline filling at the lowest point.
|
// The DFS should have figured out all reachable tiles, start scanline filling at the lowest point.
|
||||||
// On completion, move up update tile reachability by DFS on the current level. (repeat first step)
|
// On completion, move up update tile reachability by DFS on the current level. (repeat first step)
|
||||||
// - No need to recheck already reachable tiles
|
// - No need to recheck already reachable tiles
|
||||||
// - If current tile is solid, scan left and right for reachable tile and start from there
|
// - If current tile is solid, scan left and right for reachable tile and start from there
|
||||||
// Repeat scanline fill
|
// Repeat scanline fill
|
||||||
|
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
||||||
|
TileGrid_t tilemap = data->tilemap;
|
||||||
|
|
||||||
|
CWaterRunner_t* p_crunner;
|
||||||
|
unsigned int ent_idx;
|
||||||
|
sc_map_foreach(&scene->ent_manager.component_map[CWATERRUNNER_T], ent_idx, p_crunner)
|
||||||
|
{
|
||||||
|
Entity_t* ent = get_entity(&scene->ent_manager, ent_idx);
|
||||||
|
if (tilemap.tiles[p_crunner->current_tile].solid == SOLID)
|
||||||
|
{
|
||||||
|
CTileCoord_t* p_tilecoord = get_component(
|
||||||
|
ent, CTILECOORD_COMP_T
|
||||||
|
);
|
||||||
|
for (size_t i = 0;i < p_tilecoord->n_tiles; ++i)
|
||||||
|
{
|
||||||
|
// Use previously store tile position
|
||||||
|
// Clear from those positions
|
||||||
|
unsigned int tile_idx = p_tilecoord->tiles[i];
|
||||||
|
sc_map_del_64v(&(tilemap.tiles[tile_idx].entities_set), ent_idx);
|
||||||
|
}
|
||||||
|
free_water_runner(ent, &scene->ent_manager);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (p_crunner->state)
|
||||||
|
{
|
||||||
|
case BFS_RESET:
|
||||||
|
for (size_t i = 0; i < p_crunner->bfs_tilemap.len; ++i)
|
||||||
|
{
|
||||||
|
//p_crunner->bfs_tilemap.tilemap[i].to = -1;
|
||||||
|
p_crunner->bfs_tilemap.tilemap[i].from = -1;
|
||||||
|
p_crunner->bfs_tilemap.tilemap[i].reachable = false;
|
||||||
|
}
|
||||||
|
p_crunner->state = BFS_START;
|
||||||
|
// Want the fallthough
|
||||||
|
case BFS_START:
|
||||||
|
p_crunner->state = LOWEST_POINT_SEARCH;
|
||||||
|
// Want the fallthough
|
||||||
|
case LOWEST_POINT_SEARCH:
|
||||||
|
{
|
||||||
|
int32_t lowest_tile = p_crunner->current_tile - p_crunner->bfs_tilemap.width;
|
||||||
|
if (lowest_tile <= 0) lowest_tile = p_crunner->current_tile;
|
||||||
|
|
||||||
|
runner_BFS(&tilemap, p_crunner, &lowest_tile, p_crunner->current_tile);
|
||||||
|
p_crunner->target_tile = lowest_tile;
|
||||||
|
// Trace path from lowest_tile
|
||||||
|
unsigned int prev_idx = lowest_tile;
|
||||||
|
unsigned int curr_idx = p_crunner->bfs_tilemap.tilemap[prev_idx].from;
|
||||||
|
while (p_crunner->bfs_tilemap.tilemap[prev_idx].from >= 0)
|
||||||
|
{
|
||||||
|
p_crunner->bfs_tilemap.tilemap[curr_idx].to = prev_idx;
|
||||||
|
prev_idx = curr_idx;
|
||||||
|
curr_idx = p_crunner->bfs_tilemap.tilemap[prev_idx].from;
|
||||||
|
}
|
||||||
|
p_crunner->bfs_tilemap.tilemap[lowest_tile].to = -1;
|
||||||
|
if (prev_idx == lowest_tile)
|
||||||
|
{
|
||||||
|
p_crunner->state = REACHABILITY_SEARCH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p_crunner->counter = p_crunner->movement_delay;
|
||||||
|
p_crunner->state = LOWEST_POINT_MOVEMENT;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LOWEST_POINT_MOVEMENT:
|
||||||
|
p_crunner->counter--;
|
||||||
|
if (p_crunner->counter == 0)
|
||||||
|
{
|
||||||
|
p_crunner->current_tile = p_crunner->bfs_tilemap.tilemap[p_crunner->current_tile].to;
|
||||||
|
CTransform_t* p_ct = get_component(ent, CTRANSFORM_COMP_T);
|
||||||
|
p_ct->position.x = (p_crunner->current_tile % tilemap.width) * tilemap.tile_size;
|
||||||
|
p_ct->position.y = (p_crunner->current_tile / tilemap.width) * tilemap.tile_size;
|
||||||
|
if (p_crunner->current_tile == p_crunner->target_tile)
|
||||||
|
{
|
||||||
|
p_crunner->state = REACHABILITY_SEARCH;
|
||||||
|
}
|
||||||
|
p_crunner->counter = p_crunner->movement_delay;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case REACHABILITY_SEARCH:
|
||||||
|
{
|
||||||
|
if (tilemap.tiles[p_crunner->current_tile].water_level == tilemap.max_water_level)
|
||||||
|
{
|
||||||
|
p_crunner->state = FILL_COMPLETE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int start_tile =
|
||||||
|
(p_crunner->current_tile / p_crunner->bfs_tilemap.width) * p_crunner->bfs_tilemap.width;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < p_crunner->bfs_tilemap.width; ++i)
|
||||||
|
{
|
||||||
|
p_crunner->bfs_tilemap.tilemap[start_tile + i].reachable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t lowest_tile = p_crunner->current_tile;
|
||||||
|
runner_BFS(&tilemap, p_crunner, &lowest_tile, p_crunner->current_tile);
|
||||||
|
|
||||||
|
p_crunner->counter = 0;
|
||||||
|
for (int i = 0; i < p_crunner->bfs_tilemap.width; ++i)
|
||||||
|
{
|
||||||
|
Tile_t* curr_tile = tilemap.tiles + start_tile + i;
|
||||||
|
if (
|
||||||
|
p_crunner->bfs_tilemap.tilemap[start_tile + i].reachable
|
||||||
|
&& curr_tile->water_level < tilemap.max_water_level
|
||||||
|
)
|
||||||
|
{
|
||||||
|
p_crunner->counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p_crunner->fill_idx = 0;
|
||||||
|
p_crunner->state = SCANLINE_FILL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SCANLINE_FILL:
|
||||||
|
{
|
||||||
|
unsigned int start_tile =
|
||||||
|
(p_crunner->current_tile / p_crunner->bfs_tilemap.width) * p_crunner->bfs_tilemap.width;
|
||||||
|
//for (size_t i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
unsigned int curr_idx = start_tile + p_crunner->fill_idx;
|
||||||
|
Tile_t* curr_tile = tilemap.tiles + curr_idx;
|
||||||
|
if (
|
||||||
|
p_crunner->bfs_tilemap.tilemap[curr_idx].reachable
|
||||||
|
&& curr_tile->water_level < tilemap.max_water_level
|
||||||
|
)
|
||||||
|
{
|
||||||
|
curr_tile->water_level++;
|
||||||
|
if (curr_tile->water_level == tilemap.max_water_level)
|
||||||
|
{
|
||||||
|
p_crunner->counter--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_crunner->counter == 0)
|
||||||
|
{
|
||||||
|
p_crunner->state = BFS_RESET;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
p_crunner->fill_idx++;
|
||||||
|
p_crunner->fill_idx %= p_crunner->bfs_tilemap.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_water_runner_system(void)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
70
water_test.c
70
water_test.c
|
@ -24,6 +24,8 @@ static GameEngine_t engine =
|
||||||
.assets = {0}
|
.assets = {0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool water_toggle = false;
|
||||||
|
|
||||||
static void level_scene_render_func(Scene_t* scene)
|
static void level_scene_render_func(Scene_t* scene)
|
||||||
{
|
{
|
||||||
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
||||||
|
@ -85,6 +87,29 @@ static void level_scene_render_func(Scene_t* scene)
|
||||||
unsigned int x = ((p_runner->current_tile) % tilemap.width) * tilemap.tile_size;
|
unsigned int x = ((p_runner->current_tile) % tilemap.width) * tilemap.tile_size;
|
||||||
unsigned int y = ((p_runner->current_tile) / tilemap.width) * tilemap.tile_size;
|
unsigned int y = ((p_runner->current_tile) / tilemap.width) * tilemap.tile_size;
|
||||||
DrawCircle(x+16, y+16, 8, ColorAlpha(BLACK, 0.2));
|
DrawCircle(x+16, y+16, 8, ColorAlpha(BLACK, 0.2));
|
||||||
|
if (p_runner->target_tile < p_runner->bfs_tilemap.len)
|
||||||
|
{
|
||||||
|
unsigned int x = ((p_runner->target_tile) % tilemap.width) * tilemap.tile_size;
|
||||||
|
unsigned int y = ((p_runner->target_tile) / tilemap.width) * tilemap.tile_size;
|
||||||
|
DrawCircle(x+16, y+16, 8, ColorAlpha(BLUE, 0.2));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_runner->state == LOWEST_POINT_MOVEMENT)
|
||||||
|
{
|
||||||
|
int curr_idx = p_runner->current_tile;
|
||||||
|
int next_idx = p_runner->bfs_tilemap.tilemap[curr_idx].to;
|
||||||
|
while(curr_idx != p_runner->target_tile || curr_idx == next_idx)
|
||||||
|
while(next_idx >= 0)
|
||||||
|
{
|
||||||
|
unsigned int x1 = (curr_idx % tilemap.width) * tilemap.tile_size + tilemap.tile_size / 2;
|
||||||
|
unsigned int y1 = (curr_idx / tilemap.width) * tilemap.tile_size + tilemap.tile_size / 2;
|
||||||
|
unsigned int x2 = (next_idx % tilemap.width) * tilemap.tile_size + tilemap.tile_size / 2;
|
||||||
|
unsigned int y2 = (next_idx / tilemap.width) * tilemap.tile_size + tilemap.tile_size / 2;
|
||||||
|
DrawLine(x1, y1, x2, y2, BLACK);
|
||||||
|
curr_idx = next_idx;
|
||||||
|
next_idx = p_runner->bfs_tilemap.tilemap[curr_idx].to;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char buffer[64] = {0};
|
char buffer[64] = {0};
|
||||||
|
@ -124,7 +149,7 @@ static void level_scene_render_func(Scene_t* scene)
|
||||||
draw_rec.y = 0;
|
draw_rec.y = 0;
|
||||||
draw_rec.height *= -1;
|
draw_rec.height *= -1;
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
ClearBackground(LIGHTGRAY);
|
ClearBackground( water_toggle? ColorAlpha(BLUE, 0.2) : LIGHTGRAY);
|
||||||
DrawTextureRec(
|
DrawTextureRec(
|
||||||
data->game_viewport.texture,
|
data->game_viewport.texture,
|
||||||
draw_rec,
|
draw_rec,
|
||||||
|
@ -173,6 +198,10 @@ static void toggle_block_system(Scene_t* scene)
|
||||||
Vector2 raw_mouse_pos = {GetMouseX(), GetMouseY()};
|
Vector2 raw_mouse_pos = {GetMouseX(), GetMouseY()};
|
||||||
raw_mouse_pos = Vector2Subtract(raw_mouse_pos, (Vector2){data->game_rec.x, data->game_rec.y});
|
raw_mouse_pos = Vector2Subtract(raw_mouse_pos, (Vector2){data->game_rec.x, data->game_rec.y});
|
||||||
|
|
||||||
|
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
|
||||||
|
{
|
||||||
|
last_tile_idx = MAX_N_TILES;
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
raw_mouse_pos.x < data->game_rec.width
|
raw_mouse_pos.x < data->game_rec.width
|
||||||
&& raw_mouse_pos.y < data->game_rec.height
|
&& raw_mouse_pos.y < data->game_rec.height
|
||||||
|
@ -184,11 +213,34 @@ static void toggle_block_system(Scene_t* scene)
|
||||||
if (tile_idx == last_tile_idx) return;
|
if (tile_idx == last_tile_idx) return;
|
||||||
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
|
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
|
||||||
{
|
{
|
||||||
TileType_t new_type = EMPTY_TILE;
|
if (!water_toggle)
|
||||||
new_type = (tilemap.tiles[tile_idx].tile_type == SOLID_TILE)? EMPTY_TILE : SOLID_TILE;
|
{
|
||||||
if (new_type == SOLID_TILE) tilemap.tiles[tile_idx].water_level = 0;
|
TileType_t new_type = EMPTY_TILE;
|
||||||
change_a_tile(&tilemap, tile_idx, new_type);
|
new_type = (tilemap.tiles[tile_idx].tile_type == SOLID_TILE)? EMPTY_TILE : SOLID_TILE;
|
||||||
|
if (new_type == SOLID_TILE) tilemap.tiles[tile_idx].water_level = 0;
|
||||||
|
change_a_tile(&tilemap, tile_idx, new_type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (tilemap.tiles[tile_idx].tile_type != SOLID_TILE)
|
||||||
|
{
|
||||||
|
if (tilemap.tiles[tile_idx].water_level > 0)
|
||||||
|
{
|
||||||
|
tilemap.tiles[tile_idx].water_level = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tilemap.tiles[tile_idx].water_level = tilemap.max_water_level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
last_tile_idx = tile_idx;
|
last_tile_idx = tile_idx;
|
||||||
|
CWaterRunner_t* p_crunner;
|
||||||
|
sc_map_foreach_value(&scene->ent_manager.component_map[CWATERRUNNER_T], p_crunner)
|
||||||
|
{
|
||||||
|
p_crunner->state = BFS_RESET;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (IsMouseButtonReleased(MOUSE_RIGHT_BUTTON))
|
else if (IsMouseButtonReleased(MOUSE_RIGHT_BUTTON))
|
||||||
{
|
{
|
||||||
|
@ -253,6 +305,9 @@ static void level_do_action(Scene_t* scene, ActionType_t action, bool pressed)
|
||||||
case ACTION_RIGHT:
|
case ACTION_RIGHT:
|
||||||
p_playerstate->player_dir.x = (pressed)? 1 : 0;
|
p_playerstate->player_dir.x = (pressed)? 1 : 0;
|
||||||
break;
|
break;
|
||||||
|
case ACTION_METAL_TOGGLE:
|
||||||
|
if (!pressed) water_toggle = !water_toggle;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -300,6 +355,7 @@ int main(void)
|
||||||
scene.data.tilemap.width = DEFAULT_MAP_WIDTH;
|
scene.data.tilemap.width = DEFAULT_MAP_WIDTH;
|
||||||
scene.data.tilemap.height = DEFAULT_MAP_HEIGHT;
|
scene.data.tilemap.height = DEFAULT_MAP_HEIGHT;
|
||||||
scene.data.tilemap.tile_size = TILE_SIZE;
|
scene.data.tilemap.tile_size = TILE_SIZE;
|
||||||
|
scene.data.tilemap.max_water_level = 1;
|
||||||
scene.data.tilemap.n_tiles = scene.data.tilemap.width * scene.data.tilemap.height;
|
scene.data.tilemap.n_tiles = scene.data.tilemap.width * scene.data.tilemap.height;
|
||||||
assert(scene.data.tilemap.n_tiles <= MAX_N_TILES);
|
assert(scene.data.tilemap.n_tiles <= MAX_N_TILES);
|
||||||
scene.data.tilemap.tiles = all_tiles;
|
scene.data.tilemap.tiles = all_tiles;
|
||||||
|
@ -330,14 +386,18 @@ int main(void)
|
||||||
sc_array_add(&scene.scene.systems, &simple_friction_system);
|
sc_array_add(&scene.scene.systems, &simple_friction_system);
|
||||||
sc_array_add(&scene.scene.systems, &movement_update_system);
|
sc_array_add(&scene.scene.systems, &movement_update_system);
|
||||||
sc_array_add(&scene.scene.systems, &update_tilemap_system);
|
sc_array_add(&scene.scene.systems, &update_tilemap_system);
|
||||||
|
sc_array_add(&scene.scene.systems, &update_water_runner_system);
|
||||||
sc_array_add(&scene.scene.systems, &toggle_block_system);
|
sc_array_add(&scene.scene.systems, &toggle_block_system);
|
||||||
sc_array_add(&scene.scene.systems, &camera_update_system);
|
sc_array_add(&scene.scene.systems, &camera_update_system);
|
||||||
sc_array_add(&scene.scene.systems, &player_dir_reset_system);
|
sc_array_add(&scene.scene.systems, &player_dir_reset_system);
|
||||||
|
|
||||||
|
|
||||||
sc_map_put_64(&scene.scene.action_map, KEY_R, ACTION_RESTART);
|
sc_map_put_64(&scene.scene.action_map, KEY_R, ACTION_RESTART);
|
||||||
sc_map_put_64(&scene.scene.action_map, KEY_UP, ACTION_UP);
|
sc_map_put_64(&scene.scene.action_map, KEY_UP, ACTION_UP);
|
||||||
sc_map_put_64(&scene.scene.action_map, KEY_DOWN, ACTION_DOWN);
|
sc_map_put_64(&scene.scene.action_map, KEY_DOWN, ACTION_DOWN);
|
||||||
sc_map_put_64(&scene.scene.action_map, KEY_LEFT, ACTION_LEFT);
|
sc_map_put_64(&scene.scene.action_map, KEY_LEFT, ACTION_LEFT);
|
||||||
sc_map_put_64(&scene.scene.action_map, KEY_RIGHT, ACTION_RIGHT);
|
sc_map_put_64(&scene.scene.action_map, KEY_RIGHT, ACTION_RIGHT);
|
||||||
|
sc_map_put_64(&scene.scene.action_map, KEY_P, ACTION_METAL_TOGGLE);
|
||||||
|
|
||||||
|
|
||||||
while(true)
|
while(true)
|
||||||
|
|
Loading…
Reference in New Issue