Use component for unit selection
This commit is contained in:
@@ -4,6 +4,8 @@ ECS_TAG_DECLARE(TextureTerrain);
|
|||||||
ECS_TAG_DECLARE(TextureBuildings);
|
ECS_TAG_DECLARE(TextureBuildings);
|
||||||
ECS_TAG_DECLARE(TextureEntities);
|
ECS_TAG_DECLARE(TextureEntities);
|
||||||
|
|
||||||
|
ECS_TAG_DECLARE(UnitSelected);
|
||||||
|
|
||||||
ECS_COMPONENT_DECLARE(Resource);
|
ECS_COMPONENT_DECLARE(Resource);
|
||||||
|
|
||||||
ECS_COMPONENT_DECLARE(TilePosition);
|
ECS_COMPONENT_DECLARE(TilePosition);
|
||||||
@@ -29,6 +31,8 @@ void initComponentIDs(ecs_world_t *ecs) {
|
|||||||
ECS_TAG_DEFINE(ecs, TextureBuildings);
|
ECS_TAG_DEFINE(ecs, TextureBuildings);
|
||||||
ECS_TAG_DEFINE(ecs, TextureEntities);
|
ECS_TAG_DEFINE(ecs, TextureEntities);
|
||||||
|
|
||||||
|
ECS_TAG_DEFINE(ecs, UnitSelected);
|
||||||
|
|
||||||
ECS_COMPONENT_DEFINE(ecs, Resource);
|
ECS_COMPONENT_DEFINE(ecs, Resource);
|
||||||
|
|
||||||
ECS_COMPONENT_DEFINE(ecs, TilePosition);
|
ECS_COMPONENT_DEFINE(ecs, TilePosition);
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ extern ECS_TAG_DECLARE(TextureTerrain);
|
|||||||
extern ECS_TAG_DECLARE(TextureBuildings);
|
extern ECS_TAG_DECLARE(TextureBuildings);
|
||||||
extern ECS_TAG_DECLARE(TextureEntities);
|
extern ECS_TAG_DECLARE(TextureEntities);
|
||||||
|
|
||||||
|
extern ECS_TAG_DECLARE(UnitSelected);
|
||||||
|
|
||||||
typedef enum ResourceType {
|
typedef enum ResourceType {
|
||||||
RES_IRON,
|
RES_IRON,
|
||||||
RES_WOOD,
|
RES_WOOD,
|
||||||
|
|||||||
@@ -30,7 +30,12 @@ typedef struct InputState {
|
|||||||
TilePosition buildingPos;
|
TilePosition buildingPos;
|
||||||
TileSize buildingSize;
|
TileSize buildingSize;
|
||||||
// SELECTED_UNITS
|
// SELECTED_UNITS
|
||||||
ecs_entity_t *entities;
|
/*
|
||||||
|
* 1: Position
|
||||||
|
* 2: Size
|
||||||
|
* 3: UnitSelected
|
||||||
|
*/
|
||||||
|
ecs_query_t *unitSelectedQuery;
|
||||||
Position *unitPositions;
|
Position *unitPositions;
|
||||||
// SELECTED_OBJECT
|
// SELECTED_OBJECT
|
||||||
// SELECTED_BUILDING
|
// SELECTED_BUILDING
|
||||||
|
|||||||
14
game/main.c
14
game/main.c
@@ -71,7 +71,11 @@ bool init(void *userData) {
|
|||||||
input->ESC = KEY_ESCAPE;
|
input->ESC = KEY_ESCAPE;
|
||||||
input->CLICK_LIMIT = 0.2f;
|
input->CLICK_LIMIT = 0.2f;
|
||||||
|
|
||||||
input->entities = bzArrayCreate(ecs_entity_t, 16);
|
input->unitSelectedQuery = ecs_query(ECS, {
|
||||||
|
.filter.terms = {
|
||||||
|
{ ecs_id(Position) }, { ecs_id(Size) }, { ecs_id(UnitSelected) }
|
||||||
|
}
|
||||||
|
});
|
||||||
input->unitPositions = bzArrayCreate(Position, 16);
|
input->unitPositions = bzArrayCreate(Position, 16);
|
||||||
|
|
||||||
|
|
||||||
@@ -178,7 +182,6 @@ void deinit(void *userData) {
|
|||||||
ecs_fini(ECS);
|
ecs_fini(ECS);
|
||||||
ECS = NULL;
|
ECS = NULL;
|
||||||
|
|
||||||
bzArrayDestroy(inputCopy.entities);
|
|
||||||
bzArrayDestroy(inputCopy.unitPositions);
|
bzArrayDestroy(inputCopy.unitPositions);
|
||||||
bzObjectPoolDestroy(gameCopy.pools.pathData);
|
bzObjectPoolDestroy(gameCopy.pools.pathData);
|
||||||
bzSpatialGridDestroy(gameCopy.entityGrid);
|
bzSpatialGridDestroy(gameCopy.entityGrid);
|
||||||
@@ -249,8 +252,11 @@ void imguiRender(float dt, void *userData) {
|
|||||||
switch (input->state) {
|
switch (input->state) {
|
||||||
case INPUT_SELECTED_UNITS:
|
case INPUT_SELECTED_UNITS:
|
||||||
igText("Selected units:");
|
igText("Selected units:");
|
||||||
for (i32 i = 0; i < bzArraySize(input->entities); i++) {
|
ecs_iter_t it = ecs_query_iter(ECS, input->unitSelectedQuery);
|
||||||
igText("\t%llu", bzArrayGet(input->entities, i));
|
while (ecs_iter_next(&it)) {
|
||||||
|
for (i32 i = 0; i < it.count; i++) {
|
||||||
|
igText("\t%llu", it.entities[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INPUT_SELECTED_OBJECT:
|
case INPUT_SELECTED_OBJECT:
|
||||||
|
|||||||
@@ -82,14 +82,14 @@ void renderDebugPath(ecs_iter_t *it);
|
|||||||
* 0: Game (singleton)
|
* 0: Game (singleton)
|
||||||
* 0: InputState (singleton)
|
* 0: InputState (singleton)
|
||||||
*/
|
*/
|
||||||
void updatePlayerInput(ecs_iter_t *it);
|
void updatePlayerInput();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Task:
|
* Task:
|
||||||
* 0: Game (singleton)
|
* 0: Game (singleton)
|
||||||
* 0: InputState (singleton)
|
* 0: InputState (singleton)
|
||||||
*/
|
*/
|
||||||
void drawPlayerInputUI(ecs_iter_t *it);
|
void drawPlayerInputUI();
|
||||||
|
|
||||||
/**********************************
|
/**********************************
|
||||||
* UI systems
|
* UI systems
|
||||||
|
|||||||
@@ -5,14 +5,13 @@
|
|||||||
#include <rlImGui.h>
|
#include <rlImGui.h>
|
||||||
#include <raymath.h>
|
#include <raymath.h>
|
||||||
|
|
||||||
|
Rectangle calculateEntityBounds(Position pos, Size size);
|
||||||
bool getEntityBounds(ecs_entity_t entity, Position *outPos, Size *outSize, Rectangle *outBounds);
|
bool getEntityBounds(ecs_entity_t entity, Position *outPos, Size *outSize, Rectangle *outBounds);
|
||||||
void pickEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t **outEntities);
|
void pickEntity(BzSpatialGrid *entityGrid, Vector2 point);
|
||||||
void pickEntities(BzSpatialGrid *entityGrid, Rectangle area, ecs_entity_t **outEntities);
|
void pickEntities(BzSpatialGrid *entityGrid, Rectangle area);
|
||||||
|
|
||||||
void placeUnits(i32 numUnits, f32 unitSpacing, Vector2 start, Vector2 end, BzTileMap *map, Vector2 **outPlaces);
|
void placeUnits(i32 numUnits, f32 unitSpacing, Vector2 start, Vector2 end, BzTileMap *map, Vector2 **outPlaces);
|
||||||
|
|
||||||
void drawSelectionCircles(ecs_entity_t **selected);
|
|
||||||
|
|
||||||
static bool isInputDragged(InputState *input) {
|
static bool isInputDragged(InputState *input) {
|
||||||
return IsMouseButtonDown(input->LMB && input->mouseDownElapsed > input->CLICK_LIMIT);
|
return IsMouseButtonDown(input->LMB && input->mouseDownElapsed > input->CLICK_LIMIT);
|
||||||
}
|
}
|
||||||
@@ -23,7 +22,7 @@ static bool wasInputClicked(InputState *input) {
|
|||||||
return IsMouseButtonReleased(input->LMB);
|
return IsMouseButtonReleased(input->LMB);
|
||||||
}
|
}
|
||||||
|
|
||||||
void updatePlayerInput(ecs_iter_t *it) {
|
void updatePlayerInput() {
|
||||||
f32 dt = GetFrameTime();
|
f32 dt = GetFrameTime();
|
||||||
ImGuiIO *io = igGetIO();
|
ImGuiIO *io = igGetIO();
|
||||||
if (io->WantCaptureMouse || io->WantCaptureKeyboard)
|
if (io->WantCaptureMouse || io->WantCaptureKeyboard)
|
||||||
@@ -54,10 +53,11 @@ void updatePlayerInput(ecs_iter_t *it) {
|
|||||||
Vector2 worldPos = GetScreenToWorld2D(GetMousePosition(), game->camera);
|
Vector2 worldPos = GetScreenToWorld2D(GetMousePosition(), game->camera);
|
||||||
BzTile tileX = 0, tileY = 0;
|
BzTile tileX = 0, tileY = 0;
|
||||||
bzTileMapPosToTile(map, worldPos, &tileX, &tileY);
|
bzTileMapPosToTile(map, worldPos, &tileX, &tileY);
|
||||||
|
i32 selectedUnitCount = ecs_count_id(ECS, UnitSelected);
|
||||||
switch (input->state) {
|
switch (input->state) {
|
||||||
case INPUT_NONE:
|
case INPUT_NONE:
|
||||||
if (wasInputDragged(input)) {
|
if (wasInputDragged(input)) {
|
||||||
if (bzArraySize(input->entities) > 0) {
|
if (selectedUnitCount > 0) {
|
||||||
input->state = INPUT_SELECTED_UNITS;
|
input->state = INPUT_SELECTED_UNITS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -66,7 +66,7 @@ void updatePlayerInput(ecs_iter_t *it) {
|
|||||||
// Click
|
// Click
|
||||||
|
|
||||||
// 1. Entity
|
// 1. Entity
|
||||||
if (bzArraySize(input->entities) > 0) {
|
if (selectedUnitCount > 0) {
|
||||||
input->state = INPUT_SELECTED_UNITS;
|
input->state = INPUT_SELECTED_UNITS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -97,54 +97,67 @@ void updatePlayerInput(ecs_iter_t *it) {
|
|||||||
break;
|
break;
|
||||||
case INPUT_SELECTED_UNITS:
|
case INPUT_SELECTED_UNITS:
|
||||||
if (IsKeyPressed(input->ESC) || IsMouseButtonPressed(input->RMB)) {
|
if (IsKeyPressed(input->ESC) || IsMouseButtonPressed(input->RMB)) {
|
||||||
bzArrayClear(input->entities);
|
ecs_remove_all(ECS, UnitSelected);
|
||||||
input->state = INPUT_NONE;
|
input->state = INPUT_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (bzArraySize(input->entities) > 1 && wasInputDragged(input)) {
|
if (selectedUnitCount > 1 && wasInputDragged(input)) {
|
||||||
// TODO: For click it should just move them
|
// TODO: For click it should just move them
|
||||||
i32 numUnits = bzArraySize(input->entities);
|
i32 numUnits = selectedUnitCount;
|
||||||
f32 unitSpacing = 3.5f;
|
f32 unitSpacing = 3.5f;
|
||||||
bzArrayClear(input->unitPositions);
|
bzArrayClear(input->unitPositions);
|
||||||
placeUnits(numUnits, unitSpacing, input->mouseDownWorld, worldPos,
|
placeUnits(numUnits, unitSpacing, input->mouseDownWorld, worldPos,
|
||||||
map, &input->unitPositions);
|
map, &input->unitPositions);
|
||||||
|
|
||||||
BZ_ASSERT(bzArraySize(input->unitPositions) == numUnits);
|
BZ_ASSERT(bzArraySize(input->unitPositions) == numUnits);
|
||||||
|
i32 unitPosIdx = 0;
|
||||||
|
|
||||||
bzArrayFor(input->unitPositions, i) {
|
ecs_iter_t it = ecs_query_iter(ECS, input->unitSelectedQuery);
|
||||||
Position target = bzArrayGet(input->unitPositions, i);
|
|
||||||
ecs_entity_t entity = bzArrayGet(input->entities, i);
|
|
||||||
|
|
||||||
const Position *start = ecs_get(ECS, entity, Position);
|
while (ecs_iter_next(&it)) {
|
||||||
Path path = {NULL, 0};
|
Position *pos = ecs_field(&it, Position, 1);
|
||||||
pathfindAStar(&(PathfindingDesc) {
|
for (i32 i = 0; i < it.count; i++) {
|
||||||
.start=*start,
|
ecs_entity_t entity = it.entities[i];
|
||||||
.target=target,
|
ecs_remove(ECS, entity, Path);
|
||||||
.map=map,
|
|
||||||
.outPath=&path,
|
Position target = bzArrayGet(input->unitPositions, unitPosIdx);
|
||||||
.pool=game->pools.pathData
|
unitPosIdx++;
|
||||||
});
|
|
||||||
if (!path.paths) continue;
|
Path path = {NULL, 0};
|
||||||
ecs_set_ptr(ECS, entity, Path, &path);
|
pathfindAStar(&(PathfindingDesc) {
|
||||||
|
.start=pos[i],
|
||||||
|
.target=target,
|
||||||
|
.map=map,
|
||||||
|
.outPath=&path,
|
||||||
|
.pool=game->pools.pathData
|
||||||
|
});
|
||||||
|
if (!path.paths) continue;
|
||||||
|
ecs_set_ptr(ECS, entity, Path, &path);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (wasInputClicked(input)) {
|
} else if (wasInputClicked(input)) {
|
||||||
bzArrayFor(input->entities, i) {
|
ecs_iter_t it = ecs_query_iter(ECS, input->unitSelectedQuery);
|
||||||
ecs_entity_t entity = bzArrayGet(input->entities, i);
|
|
||||||
ecs_remove(ECS, entity, Path);
|
|
||||||
|
|
||||||
const Position *start = ecs_get(ECS, entity, Position);
|
while (ecs_iter_next(&it)) {
|
||||||
Path path = {NULL, 0};
|
Position *pos = ecs_field(&it, Position, 1);
|
||||||
pathfindAStar(&(PathfindingDesc) {
|
for (i32 i = 0; i < it.count; i++) {
|
||||||
.start=*start,
|
ecs_entity_t entity = it.entities[i];
|
||||||
.target=worldPos,
|
ecs_remove(ECS, entity, Path);
|
||||||
.map=map,
|
|
||||||
.outPath=&path,
|
Path path = {NULL, 0};
|
||||||
.pool=game->pools.pathData
|
pathfindAStar(&(PathfindingDesc) {
|
||||||
});
|
.start=pos[i],
|
||||||
if (!path.paths) continue;
|
.target=worldPos,
|
||||||
ecs_set_ptr(ECS, entity, Path, &path);
|
.map=map,
|
||||||
|
.outPath=&path,
|
||||||
|
.pool=game->pools.pathData
|
||||||
|
});
|
||||||
|
if (!path.paths) continue;
|
||||||
|
ecs_set_ptr(ECS, entity, Path, &path);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INPUT_SELECTED_OBJECT:
|
case INPUT_SELECTED_OBJECT:
|
||||||
@@ -154,12 +167,13 @@ void updatePlayerInput(ecs_iter_t *it) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawPlayerInputUI(ecs_iter_t *it) {
|
void drawPlayerInputUI() {
|
||||||
Game *game = ecs_singleton_get_mut(ECS, Game);
|
Game *game = ecs_singleton_get_mut(ECS, Game);
|
||||||
InputState *input = ecs_singleton_get_mut(ECS, InputState);
|
InputState *input = ecs_singleton_get_mut(ECS, InputState);
|
||||||
BzTileMap *map = &game->map;
|
BzTileMap *map = &game->map;
|
||||||
Vector2 worldPos = GetScreenToWorld2D(GetMousePosition(), game->camera);
|
Vector2 worldPos = GetScreenToWorld2D(GetMousePosition(), game->camera);
|
||||||
|
|
||||||
|
i32 selectedUnitCount = ecs_count_id(ECS, UnitSelected);
|
||||||
switch (input->state) {
|
switch (input->state) {
|
||||||
case INPUT_NONE:
|
case INPUT_NONE:
|
||||||
if (isInputDragged(input)) {
|
if (isInputDragged(input)) {
|
||||||
@@ -178,7 +192,7 @@ void drawPlayerInputUI(ecs_iter_t *it) {
|
|||||||
Rectangle area = {start.x, start.y, end.x - start.x, end.y - start.y};
|
Rectangle area = {start.x, start.y, end.x - start.x, end.y - start.y};
|
||||||
DrawRectangleLines(area.x, area.y, area.width, area.height, RED);
|
DrawRectangleLines(area.x, area.y, area.width, area.height, RED);
|
||||||
|
|
||||||
pickEntities(game->entityGrid, area, &input->entities);
|
pickEntities(game->entityGrid, area);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INPUT_BUILDING: {
|
case INPUT_BUILDING: {
|
||||||
@@ -195,8 +209,8 @@ void drawPlayerInputUI(ecs_iter_t *it) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case INPUT_SELECTED_UNITS: {
|
case INPUT_SELECTED_UNITS: {
|
||||||
if (bzArraySize(input->entities) > 1 && isInputDragged(input)) {
|
if (selectedUnitCount > 1 && isInputDragged(input)) {
|
||||||
i32 numUnits = bzArraySize(input->entities);
|
i32 numUnits = selectedUnitCount;
|
||||||
f32 unitSpacing = 3.5f;
|
f32 unitSpacing = 3.5f;
|
||||||
bzArrayClear(input->unitPositions);
|
bzArrayClear(input->unitPositions);
|
||||||
placeUnits(numUnits, unitSpacing, input->mouseDownWorld, worldPos,
|
placeUnits(numUnits, unitSpacing, input->mouseDownWorld, worldPos,
|
||||||
@@ -216,10 +230,27 @@ void drawPlayerInputUI(ecs_iter_t *it) {
|
|||||||
case INPUT_SELECTED_BUILDING:
|
case INPUT_SELECTED_BUILDING:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
drawSelectionCircles(&input->entities);
|
ecs_iter_t it = ecs_query_iter(ECS, input->unitSelectedQuery);
|
||||||
|
while (ecs_query_next(&it)) {
|
||||||
|
Position *pos = ecs_field(&it, Position, 1);
|
||||||
|
Size *size = ecs_field(&it, Size, 2);
|
||||||
|
for (i32 i = 0; i < it.count; i++) {
|
||||||
|
f32 radius = size[i].x;
|
||||||
|
if (size[i].y > radius)
|
||||||
|
radius = size[i].y;
|
||||||
|
radius *= 0.5f;
|
||||||
|
DrawCircleLines(pos[i].x, pos[i].y, radius, GREEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle calculateEntityBounds(Position pos, Size size) {
|
||||||
|
return (Rectangle) {
|
||||||
|
pos.x - size.x * 0.5f,
|
||||||
|
pos.y - size.x * 0.5f,
|
||||||
|
size.x, size.y
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getEntityBounds(ecs_entity_t entity, Position *outPos, Size *outSize, Rectangle *outBounds) {
|
bool getEntityBounds(ecs_entity_t entity, Position *outPos, Size *outSize, Rectangle *outBounds) {
|
||||||
@@ -248,9 +279,8 @@ bool getEntityBounds(ecs_entity_t entity, Position *outPos, Size *outSize, Recta
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pickEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t **outEntities) {
|
void pickEntity(BzSpatialGrid *entityGrid, Vector2 point) {
|
||||||
BZ_ASSERT(*outEntities);
|
ecs_remove_all(ECS, UnitSelected);
|
||||||
bzArrayClear(*outEntities);
|
|
||||||
BzSpatialGridIter it = bzSpatialGridIter(entityGrid, point.x, point.y, 0.0f, 0.0f);
|
BzSpatialGridIter it = bzSpatialGridIter(entityGrid, point.x, point.y, 0.0f, 0.0f);
|
||||||
f32 closestDst = INFINITY;
|
f32 closestDst = INFINITY;
|
||||||
ecs_entity_t closest = 0;
|
ecs_entity_t closest = 0;
|
||||||
@@ -269,14 +299,12 @@ void pickEntity(BzSpatialGrid *entityGrid, Vector2 point, ecs_entity_t **outEnti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (closest) {
|
if (closest) {
|
||||||
bzArrayPush(*outEntities, closest);
|
ecs_add(ECS, closest, UnitSelected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pickEntities(BzSpatialGrid *entityGrid, Rectangle area, ecs_entity_t **outEntities) {
|
void pickEntities(BzSpatialGrid *entityGrid, Rectangle area) {
|
||||||
BZ_ASSERT(*outEntities);
|
ecs_remove_all(ECS, UnitSelected);
|
||||||
bzArrayClear(*outEntities);
|
|
||||||
|
|
||||||
BzSpatialGridIter it = bzSpatialGridIter(entityGrid, area.x, area.y, area.width, area.height);
|
BzSpatialGridIter it = bzSpatialGridIter(entityGrid, area.x, area.y, area.width, area.height);
|
||||||
while (bzSpatialGridQueryNext(&it)) {
|
while (bzSpatialGridQueryNext(&it)) {
|
||||||
ecs_entity_t entity = *(ecs_entity_t *) it.data;
|
ecs_entity_t entity = *(ecs_entity_t *) it.data;
|
||||||
@@ -284,7 +312,7 @@ void pickEntities(BzSpatialGrid *entityGrid, Rectangle area, ecs_entity_t **outE
|
|||||||
if (!getEntityBounds(entity, NULL, NULL, &bounds)) continue;
|
if (!getEntityBounds(entity, NULL, NULL, &bounds)) continue;
|
||||||
|
|
||||||
if (!CheckCollisionRecs(area, bounds)) continue;
|
if (!CheckCollisionRecs(area, bounds)) continue;
|
||||||
bzArrayPush(*outEntities, entity);
|
ecs_add(ECS, entity, UnitSelected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,15 +355,3 @@ void placeUnits(i32 numUnits, f32 unitSpacing, Vector2 start, Vector2 end, BzTil
|
|||||||
pos.x += unitSpacing * 2.0f;
|
pos.x += unitSpacing * 2.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawSelectionCircles(ecs_entity_t **selected) {
|
|
||||||
bzArrayFor(*selected, i) {
|
|
||||||
ecs_entity_t entity = bzArrayGet(*selected, i);
|
|
||||||
Position pos = {0};
|
|
||||||
if (!getEntityBounds(entity, &pos, NULL, NULL))
|
|
||||||
continue;
|
|
||||||
DrawCircleLines(pos.x, pos.y, 4.5f, GREEN);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user