Rework input
This commit is contained in:
@@ -8,8 +8,8 @@
|
||||
|
||||
Rectangle calculateEntityBounds(Position pos, Size size);
|
||||
bool getEntityBounds(ecs_entity_t entity, Position *outPos, Size *outSize, Rectangle *outBounds);
|
||||
void pickEntity(BzSpatialGrid *entityGrid, Vector2 point);
|
||||
void pickEntities(BzSpatialGrid *entityGrid, Rectangle area);
|
||||
bool pickEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t tag);
|
||||
void pickUnits(BzSpatialGrid *entityGrid, Rectangle area);
|
||||
|
||||
static void iterateSelectedUnits(ecs_query_t *query, void (*fn)(ecs_entity_t entity, Position *pos, Size *size));
|
||||
static void iterRemovePaths(ecs_entity_t entity, Position *pos, Size *size);
|
||||
@@ -23,7 +23,7 @@ static bool wasInputDragged(InputState *input) {
|
||||
return IsMouseButtonReleased(input->LMB) && input->mouseDownElapsed > input->CLICK_LIMIT;
|
||||
}
|
||||
static bool wasInputClicked(InputState *input) {
|
||||
return IsMouseButtonReleased(input->LMB);
|
||||
return IsMouseButtonReleased(input->LMB) && input->mouseDownElapsed <= input->CLICK_LIMIT;
|
||||
}
|
||||
|
||||
void updatePlayerInput() {
|
||||
@@ -34,10 +34,10 @@ void updatePlayerInput() {
|
||||
|
||||
Game *game = ecs_singleton_get_mut(ECS, Game);
|
||||
InputState *input = ecs_singleton_get_mut(ECS, InputState);
|
||||
if (IsKeyDown(KEY_W)) game->camera.target.y -= 20;
|
||||
if (IsKeyDown(KEY_S)) game->camera.target.y += 20;
|
||||
if (IsKeyDown(KEY_A)) game->camera.target.x -= 20;
|
||||
if (IsKeyDown(KEY_D)) game->camera.target.x += 20;
|
||||
if (IsKeyDown(KEY_W)) game->camera.target.y -= 5;
|
||||
if (IsKeyDown(KEY_S)) game->camera.target.y += 5;
|
||||
if (IsKeyDown(KEY_A)) game->camera.target.x -= 5;
|
||||
if (IsKeyDown(KEY_D)) game->camera.target.x += 5;
|
||||
|
||||
if (IsKeyDown(KEY_Q)) game->camera.rotation--;
|
||||
if (IsKeyDown(KEY_E)) game->camera.rotation++;
|
||||
@@ -57,30 +57,39 @@ void updatePlayerInput() {
|
||||
Vector2 worldPos = GetScreenToWorld2D(GetMousePosition(), game->camera);
|
||||
BzTile tileX = 0, tileY = 0;
|
||||
bzTileMapPosToTile(map, worldPos, &tileX, &tileY);
|
||||
i32 selectedUnitCount = ecs_query_entity_count(input->unitSelectedQuery);
|
||||
switch (input->state) {
|
||||
case INPUT_NONE:
|
||||
if (wasInputDragged(input)) {
|
||||
if (selectedUnitCount > 0) {
|
||||
input->state = INPUT_SELECTED_UNITS;
|
||||
break;
|
||||
case INPUT_NONE: {
|
||||
if (isInputDragged(input)) {
|
||||
Vector2 start = input->mouseDownWorld;
|
||||
Vector2 end = worldPos;
|
||||
if (start.x > end.x) {
|
||||
f32 tmp = start.x;
|
||||
start.x = end.x;
|
||||
end.x = tmp;
|
||||
}
|
||||
|
||||
} else if (wasInputClicked(input)) {
|
||||
// Click
|
||||
|
||||
// 1. Entity
|
||||
if (selectedUnitCount > 0) {
|
||||
input->state = INPUT_SELECTED_UNITS;
|
||||
break;
|
||||
if (start.y > end.y) {
|
||||
f32 tmp = start.y;
|
||||
start.y = end.y;
|
||||
end.y = tmp;
|
||||
}
|
||||
|
||||
// 2. Object
|
||||
|
||||
// 3. Building
|
||||
input->pickArea = (Rectangle) {start.x, start.y, end.x - start.x, end.y - start.y};
|
||||
pickUnits(game->entityGrid, input->pickArea);
|
||||
}
|
||||
i32 selectedCount = ecs_query_entity_count(input->queries.selected);
|
||||
if (wasInputClicked(input)) {
|
||||
if (pickEntity(game->entityGrid, input->mouseDownWorld, Unit)) {
|
||||
input->state = INPUT_SELECTED_UNITS;
|
||||
} else if (pickEntity(game->entityGrid, input->mouseDownWorld, Harvestable)) {
|
||||
input->state = INPUT_SELECTED_OBJECT;
|
||||
} else if (pickEntity(game->entityGrid, input->mouseDownWorld, Buildable)) {
|
||||
input->state = INPUT_SELECTED_BUILDING;
|
||||
}
|
||||
} else if (wasInputDragged(input) && selectedCount > 0) {
|
||||
input->state = INPUT_SELECTED_UNITS;
|
||||
}
|
||||
break;
|
||||
case INPUT_BUILDING:
|
||||
}
|
||||
case INPUT_BUILDING: {
|
||||
if (IsKeyPressed(input->ESC) ||
|
||||
IsMouseButtonPressed(input->RMB) ||
|
||||
input->building == 0) {
|
||||
@@ -99,15 +108,17 @@ void updatePlayerInput() {
|
||||
input->buildingPos = (TilePosition) {tileX, tileY};
|
||||
input->buildingSize = (TileSize) {sizeX, sizeY};
|
||||
break;
|
||||
case INPUT_SELECTED_UNITS:
|
||||
}
|
||||
case INPUT_SELECTED_UNITS: {
|
||||
if (IsKeyPressed(input->ESC) || IsMouseButtonPressed(input->RMB)) {
|
||||
ecs_remove_all(ECS, UnitSelected);
|
||||
ecs_remove_all(ECS, Selected);
|
||||
input->state = INPUT_NONE;
|
||||
break;
|
||||
}
|
||||
if (selectedUnitCount > 1 && wasInputDragged(input)) {
|
||||
i32 selectedCount = ecs_query_entity_count(input->queries.selected);
|
||||
if (selectedCount > 1 && wasInputDragged(input)) {
|
||||
// TODO: For click it should just move them
|
||||
i32 numUnits = selectedUnitCount;
|
||||
i32 numUnits = selectedCount;
|
||||
f32 unitSpacing = 3.5f;
|
||||
bzArrayClear(input->unitPositions);
|
||||
placeUnits(numUnits, unitSpacing, input->mouseDownWorld, worldPos,
|
||||
@@ -117,10 +128,10 @@ void updatePlayerInput() {
|
||||
i32 unitPosIdx = 0;
|
||||
|
||||
ecs_defer_begin(ECS);
|
||||
iterateSelectedUnits(input->unitSelectedQuery, iterRemovePaths);
|
||||
iterateSelectedUnits(input->queries.selected, iterRemovePaths);
|
||||
ecs_defer_end(ECS);
|
||||
|
||||
ecs_iter_t it = ecs_query_iter(ECS, input->unitSelectedQuery);
|
||||
ecs_iter_t it = ecs_query_iter(ECS, input->queries.selected);
|
||||
ecs_defer_begin(ECS);
|
||||
while (ecs_iter_next(&it)) {
|
||||
Position *pos = ecs_field(&it, Position, 1);
|
||||
@@ -149,10 +160,10 @@ void updatePlayerInput() {
|
||||
ecs_defer_end(ECS);
|
||||
} else if (wasInputClicked(input)) {
|
||||
ecs_defer_begin(ECS);
|
||||
iterateSelectedUnits(input->unitSelectedQuery, iterRemovePaths);
|
||||
iterateSelectedUnits(input->queries.selected, iterRemovePaths);
|
||||
ecs_defer_end(ECS);
|
||||
|
||||
ecs_iter_t it = ecs_query_iter(ECS, input->unitSelectedQuery);
|
||||
ecs_iter_t it = ecs_query_iter(ECS, input->queries.selected);
|
||||
|
||||
ecs_defer_begin(ECS);
|
||||
while (ecs_iter_next(&it)) {
|
||||
@@ -163,12 +174,12 @@ void updatePlayerInput() {
|
||||
|
||||
Path path = {NULL, 0};
|
||||
pathfindAStar(&(PathfindingDesc) {
|
||||
.start=pos[i],
|
||||
.target=worldPos,
|
||||
.map=map,
|
||||
.outPath=&path,
|
||||
.pool=game->pools.pathData,
|
||||
.alloc=&game->stackAlloc
|
||||
.start=pos[i],
|
||||
.target=worldPos,
|
||||
.map=map,
|
||||
.outPath=&path,
|
||||
.pool=game->pools.pathData,
|
||||
.alloc=&game->stackAlloc
|
||||
});
|
||||
if (!path.paths) continue;
|
||||
ecs_set_ptr(ECS, entity, Path, &path);
|
||||
@@ -178,10 +189,16 @@ void updatePlayerInput() {
|
||||
ecs_defer_end(ECS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case INPUT_SELECTED_OBJECT:
|
||||
break;
|
||||
case INPUT_SELECTED_BUILDING:
|
||||
if (IsKeyPressed(input->ESC) || IsMouseButtonPressed(input->RMB)) {
|
||||
ecs_remove_all(ECS, Selected);
|
||||
input->state = INPUT_NONE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,26 +208,12 @@ void drawPlayerInputUI() {
|
||||
BzTileMap *map = &game->map;
|
||||
Vector2 worldPos = GetScreenToWorld2D(GetMousePosition(), game->camera);
|
||||
|
||||
i32 selectedUnitCount = ecs_count_id(ECS, UnitSelected);
|
||||
i32 selectedUnitCount = ecs_count_id(ECS, Selected);
|
||||
switch (input->state) {
|
||||
case INPUT_NONE:
|
||||
if (isInputDragged(input)) {
|
||||
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};
|
||||
Rectangle area = input->pickArea;
|
||||
DrawRectangleLines(area.x, area.y, area.width, area.height, RED);
|
||||
|
||||
pickEntities(game->entityGrid, area);
|
||||
}
|
||||
break;
|
||||
case INPUT_BUILDING: {
|
||||
@@ -243,12 +246,8 @@ void drawPlayerInputUI() {
|
||||
|
||||
break;
|
||||
}
|
||||
case INPUT_SELECTED_OBJECT:
|
||||
break;
|
||||
case INPUT_SELECTED_BUILDING:
|
||||
break;
|
||||
}
|
||||
ecs_iter_t it = ecs_query_iter(ECS, input->unitSelectedQuery);
|
||||
ecs_iter_t it = ecs_query_iter(ECS, input->queries.selected);
|
||||
rlSetLineWidth(2.0f);
|
||||
while (ecs_query_next(&it)) {
|
||||
Position *pos = ecs_field(&it, Position, 1);
|
||||
@@ -298,13 +297,15 @@ bool getEntityBounds(ecs_entity_t entity, Position *outPos, Size *outSize, Recta
|
||||
return true;
|
||||
}
|
||||
|
||||
void pickEntity(BzSpatialGrid *entityGrid, Vector2 point) {
|
||||
ecs_remove_all(ECS, UnitSelected);
|
||||
bool pickEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t tag) {
|
||||
ecs_remove_all(ECS, Selected);
|
||||
BzSpatialGridIter it = bzSpatialGridIter(entityGrid, point.x, point.y, 0.0f, 0.0f);
|
||||
f32 closestDst = INFINITY;
|
||||
ecs_entity_t closest = 0;
|
||||
while (bzSpatialGridQueryNext(&it)) {
|
||||
ecs_entity_t entity = *(ecs_entity_t *) it.data;
|
||||
if (!ecs_has_id(ECS, entity, Selectable)) continue;
|
||||
if (!ecs_has_id(ECS, entity, tag)) continue;
|
||||
Vector2 pos;
|
||||
Rectangle bounds;
|
||||
if (!getEntityBounds(entity, &pos, NULL, &bounds)) continue;
|
||||
@@ -318,20 +319,23 @@ void pickEntity(BzSpatialGrid *entityGrid, Vector2 point) {
|
||||
}
|
||||
}
|
||||
if (closest) {
|
||||
ecs_add(ECS, closest, UnitSelected);
|
||||
ecs_add(ECS, closest, Selected);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void pickEntities(BzSpatialGrid *entityGrid, Rectangle area) {
|
||||
ecs_remove_all(ECS, UnitSelected);
|
||||
void pickUnits(BzSpatialGrid *entityGrid, Rectangle area) {
|
||||
ecs_remove_all(ECS, Selected);
|
||||
BzSpatialGridIter it = bzSpatialGridIter(entityGrid, area.x, area.y, area.width, area.height);
|
||||
while (bzSpatialGridQueryNext(&it)) {
|
||||
ecs_entity_t entity = *(ecs_entity_t *) it.data;
|
||||
if (!ecs_has_id(ECS, entity, Unit)) continue;
|
||||
Rectangle bounds;
|
||||
if (!getEntityBounds(entity, NULL, NULL, &bounds)) continue;
|
||||
|
||||
if (!CheckCollisionRecs(area, bounds)) continue;
|
||||
ecs_add(ECS, entity, UnitSelected);
|
||||
ecs_add(ECS, entity, Selected);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user