Add feedback UI for selecting and placing units

This commit is contained in:
2023-11-23 12:21:25 +01:00
parent 0dc8046d8f
commit 5ff0fbb26f
4 changed files with 86 additions and 121 deletions

View File

@@ -5,6 +5,7 @@
#include <rlImGui.h>
#include <raymath.h>
bool getEntityBounds(ecs_entity_t entity, Position *outPos, Size *outSize, Rectangle *outBounds);
void pickEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t **outEntities);
void pickEntities(BzSpatialGrid *entityGrid, Rectangle area, ecs_entity_t **outEntities);
@@ -116,14 +117,14 @@ void updatePlayerInput(ecs_iter_t *it) {
// TODO: For click it should just move them
i32 numUnits = bzArraySize(input->entities);
f32 unitSpacing = 3.5f;
Vector2 *unitPositions = bzArrayCreate(Position, numUnits);
bzArrayClear(input->unitPositions);
placeUnits(numUnits, unitSpacing, input->mouseDownWorld, worldPos,
map, &unitPositions);
map, &input->unitPositions);
BZ_ASSERT(bzArraySize(unitPositions) == numUnits);
BZ_ASSERT(bzArraySize(input->unitPositions) == numUnits);
bzArrayFor(unitPositions, i) {
Position target = bzArrayGet(unitPositions, i);
bzArrayFor(input->unitPositions, i) {
Position target = bzArrayGet(input->unitPositions, i);
ecs_entity_t entity = bzArrayGet(input->entities, i);
const Position *start = ecs_get(ECS, entity, Position);
@@ -139,9 +140,6 @@ void updatePlayerInput(ecs_iter_t *it) {
ecs_set_ptr(ECS, entity, Path, &path);
input->state = INPUT_NONE;
}
bzArrayDestroy(unitPositions);
} else if (wasInputClicked(input)) {
bzArrayFor(input->entities, i) {
ecs_entity_t entity = bzArrayGet(input->entities, i);
@@ -170,8 +168,70 @@ void updatePlayerInput(ecs_iter_t *it) {
}
}
static bool getEntityBounds(ecs_entity_t entity, Position *outPos, Size *outSize,
Rectangle *outBounds) {
void drawPlayerInputUI(ecs_iter_t *it) {
Game *game = ecs_singleton_get_mut(ECS, Game);
InputState *input = ecs_singleton_get_mut(ECS, InputState);
Vector2 worldPos = GetScreenToWorld2D(GetMousePosition(), game->camera);
switch (input->state) {
case INPUT_NONE:
if (IsMouseButtonDown(input->LMB) && input->mouseDownElapsed > input->CLICK_LIMIT) {
Vector2 start = input->mouseDownWorld;
Vector2 end = worldPos;
if (start.x > end.x) {
f32 tmp = start.x;
start.x = end.x;
end.x = tmp;
}
if (start.y > end.y) {
f32 tmp = start.y;
start.y = end.y;
end.y = tmp;
}
Rectangle area = {start.x, start.y, end.x - start.x, end.y - start.y};
DrawRectangleLines(area.x, area.y, area.width, area.height, RED);
}
break;
case INPUT_BUILDING: {
Color placeColor = input->buildingCanPlace ?
(Color) {0, 255, 0, 200} :
(Color) {255, 0, 0, 200};
BzTile width = game->map.tileWidth;
BzTile height = game->map.tileHeight;
DrawRectangleLines(input->buildingPos.x * width,
input->buildingPos.y * height,
input->buildingSize.sizeX * width,
input->buildingSize.sizeY * height, placeColor);
break;
}
case INPUT_SELECTED_UNITS: {
bzArrayFor(input->entities, i) {
ecs_entity_t entity = bzArrayGet(input->entities, i);
Position pos = {0};
if (!getEntityBounds(entity, &pos, NULL, NULL))
continue;
DrawCircleLines(pos.x, pos.y, 4.5f, GREEN);
}
break;
}
case INPUT_SELECTED_OBJECT:
break;
case INPUT_SELECTED_BUILDING:
break;
}
bzArrayFor(input->unitPositions, i) {
Position pos = bzArrayGet(input->unitPositions, i);
DrawCircle(pos.x, pos.y, 2.0f, ORANGE);
}
}
bool getEntityBounds(ecs_entity_t entity, Position *outPos, Size *outSize, Rectangle *outBounds) {
if (!ecs_is_alive(ECS, entity))
return false;
const Position *pos = ecs_get(ECS, entity, Position);