mirror of
https://github.com/Kapendev/parin.git
synced 2025-04-25 20:49:57 +03:00
Maps are blazingly fast now.
This commit is contained in:
parent
7846b4adb8
commit
557622f64f
4 changed files with 107 additions and 192 deletions
|
@ -9,39 +9,31 @@ auto tile = Tile(16, 16, 145);
|
|||
auto tileFlip = Flip.none;
|
||||
|
||||
void ready() {
|
||||
lockResolution(320, 180);
|
||||
lockResolution(160, 90);
|
||||
atlas = loadTexture("parin_atlas.png");
|
||||
// Parse a CSV string representing a tile map, where each tile is 16x16 pixels in size.
|
||||
// Parse a CSV representing a tile map, where each tile is 16x16 pixels in size.
|
||||
map.parse("-1,-1,-1\n21,22,23\n37,38,39\n53,54,55", 16, 16);
|
||||
}
|
||||
|
||||
bool update(float dt) {
|
||||
// Create the drawing options for the map and tile.
|
||||
auto mapOptions = DrawOptions(Vec2(2));
|
||||
auto tileOptions = mapOptions;
|
||||
tileOptions.flip = tileFlip;
|
||||
if (wasd.x > 0) tileFlip = Flip.x;
|
||||
else if (wasd.x < 0) tileFlip = Flip.none;
|
||||
|
||||
// Move the tile and the camera.
|
||||
// Move and update the game objects.
|
||||
tileFlip = wasd.x ? (wasd.x > 0 ? Flip.x : Flip.none) : tileFlip;
|
||||
tile.position += wasd * Vec2(120 * dt);
|
||||
camera.position = tile.position + tile.size * Vec2(0.5f);
|
||||
// Check for collisions between the tile and the map and resolve the collision.
|
||||
foreach (position; map.gridPositions(camera.area, mapOptions)) {
|
||||
if (map[position] < 0) continue;
|
||||
auto area = Rect(map.worldPosition(position, mapOptions), map.tileSize * mapOptions.scale);
|
||||
while (area.hasIntersection(Rect(tile.position, tile.size * mapOptions.scale))) {
|
||||
// Check for collisions with the map and resolve them.
|
||||
foreach (point; map.gridPoints(camera.area)) {
|
||||
if (map[point] < 0) continue;
|
||||
auto area = Rect(map.toWorldPoint(point), map.tileSize);
|
||||
while (area.hasIntersection(tile.area)) {
|
||||
tile.position -= wasd * Vec2(dt);
|
||||
camera.position = tile.position + tile.size * Vec2(0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the tile and the map.
|
||||
// Draw the world.
|
||||
camera.attach();
|
||||
drawTile(atlas, tile, tileOptions);
|
||||
drawTileMap(atlas, map, camera, mapOptions);
|
||||
drawTile(atlas, tile, DrawOptions(tileFlip));
|
||||
drawTileMap(atlas, map, camera);
|
||||
camera.detach();
|
||||
drawDebugText("Move with arrow keys.", Vec2(8));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -311,11 +311,8 @@ struct TextureId {
|
|||
/// Retrieves the texture associated with the resource identifier.
|
||||
ref Texture get() {
|
||||
if (!isValid) {
|
||||
if (data.value) {
|
||||
assert(0, "ID `{}` with generation `{}` does not exist.".format(data.value, data.generation));
|
||||
} else {
|
||||
assert(0, "ID `0` is always invalid and represents a resource that was never created.");
|
||||
}
|
||||
if (data.value) assert(0, "ID `{}` with generation `{}` does not exist.".format(data.value, data.generation));
|
||||
else assert(0, "ID `0` is always invalid and represents a resource that was never created.");
|
||||
}
|
||||
return engineState.textures[GenerationalIndex(data.value - 1, data.generation)];
|
||||
}
|
||||
|
@ -414,11 +411,8 @@ struct FontId {
|
|||
/// Retrieves the font associated with the resource identifier.
|
||||
ref Font get() {
|
||||
if (!isValid) {
|
||||
if (data.value) {
|
||||
assert(0, "ID `{}` with generation `{}` does not exist.".format(data.value, data.generation));
|
||||
} else {
|
||||
assert(0, "ID `0` is always invalid and represents a resource that was never created.");
|
||||
}
|
||||
if (data.value) assert(0, "ID `{}` with generation `{}` does not exist.".format(data.value, data.generation));
|
||||
else assert(0, "ID `0` is always invalid and represents a resource that was never created.");
|
||||
}
|
||||
return engineState.fonts[GenerationalIndex(data.value - 1, data.generation)];
|
||||
}
|
||||
|
@ -585,11 +579,8 @@ struct SoundId {
|
|||
/// Retrieves the sound associated with the resource identifier.
|
||||
ref Sound get() {
|
||||
if (!isValid) {
|
||||
if (data.value) {
|
||||
assert(0, "ID `{}` with generation `{}` does not exist.".format(data.value, data.generation));
|
||||
} else {
|
||||
assert(0, "ID `0` is always invalid and represents a resource that was never created.");
|
||||
}
|
||||
if (data.value) assert(0, "ID `{}` with generation `{}` does not exist.".format(data.value, data.generation));
|
||||
else assert(0, "ID `0` is always invalid and represents a resource that was never created.");
|
||||
}
|
||||
return engineState.sounds[GenerationalIndex(data.value - 1, data.generation)];
|
||||
}
|
||||
|
@ -2099,6 +2090,7 @@ void drawLine(Line area, float size, Color color = white) {
|
|||
void drawTextureArea(Texture texture, Rect area, Vec2 position, DrawOptions options = DrawOptions()) {
|
||||
if (texture.isEmpty || area.size.x <= 0.0f || area.size.y <= 0.0f) return;
|
||||
auto target = Rect(position, area.size * options.scale.abs());
|
||||
auto origin = options.origin == Vec2() ? target.origin(options.hook) : options.origin;
|
||||
auto flip = options.flip;
|
||||
if (options.scale.x < 0.0f && options.scale.y < 0.0f) {
|
||||
flip = oppositeFlip(flip, Flip.xy);
|
||||
|
@ -2113,8 +2105,6 @@ void drawTextureArea(Texture texture, Rect area, Vec2 position, DrawOptions opti
|
|||
case Flip.y: area.size.y *= -1.0f; break;
|
||||
case Flip.xy: area.size *= Vec2(-1.0f); break;
|
||||
}
|
||||
|
||||
auto origin = options.origin == Vec2() ? target.origin(options.hook) : options.origin;
|
||||
if (isPixelSnapped || isPixelPerfect) {
|
||||
rl.DrawTexturePro(
|
||||
texture.data,
|
||||
|
@ -2419,12 +2409,9 @@ mixin template runGame(alias readyFunc, alias updateFunc, alias finishFunc, int
|
|||
extern(C)
|
||||
void main(int argc, immutable(char)** argv) {
|
||||
openWindow(width, height, [], title);
|
||||
// Yeah... I love writing code again and again and again.
|
||||
foreach (i; 0 .. argc) {
|
||||
Sz length = 0;
|
||||
while (argv[i][length] != '\0') {
|
||||
length += 1;
|
||||
}
|
||||
while (argv[i][length] != '\0') length += 1;
|
||||
engineState.envArgsBuffer.append(argv[i][0 .. length]);
|
||||
}
|
||||
readyFunc();
|
||||
|
|
|
@ -36,6 +36,10 @@ struct Tile {
|
|||
return Vec2(width, height);
|
||||
}
|
||||
|
||||
Rect area() {
|
||||
return Rect(position, size);
|
||||
}
|
||||
|
||||
Sz row(Sz colCount) {
|
||||
return id / colCount;
|
||||
}
|
||||
|
@ -179,32 +183,6 @@ struct TileMap {
|
|||
return Vec2(tileWidth, tileHeight);
|
||||
}
|
||||
|
||||
Fault parse(IStr csv, int newTileWidth, int newTileHeight) {
|
||||
if (csv.length == 0) return Fault.invalid;
|
||||
if (data.isEmpty) {
|
||||
data.resizeBlank(defaultGridRowCount, defaultGridColCount);
|
||||
}
|
||||
tileWidth = newTileWidth;
|
||||
tileHeight = newTileHeight;
|
||||
softRowCount = 0;
|
||||
softColCount = 0;
|
||||
auto view = csv;
|
||||
while (view.length != 0) {
|
||||
softRowCount += 1;
|
||||
softColCount = 0;
|
||||
if (softRowCount > data.rowCount) return Fault.invalid;
|
||||
auto line = view.skipLine();
|
||||
while (line.length != 0) {
|
||||
softColCount += 1;
|
||||
if (softColCount > data.colCount) return Fault.invalid;
|
||||
auto tile = line.skipValue(',').toSigned();
|
||||
if (tile.isNone) return Fault.invalid;
|
||||
data[softRowCount - 1, softColCount - 1] = cast(short) tile.get();
|
||||
}
|
||||
}
|
||||
return Fault.none;
|
||||
}
|
||||
|
||||
/// Moves the tile map to follow the target position at the specified speed.
|
||||
void followPosition(Vec2 target, float speed) {
|
||||
position = position.moveTo(target, Vec2(speed));
|
||||
|
@ -216,7 +194,7 @@ struct TileMap {
|
|||
}
|
||||
|
||||
/// Returns the top left world position of a grid position.
|
||||
Vec2 worldPosition(Sz row, Sz col, DrawOptions options = DrawOptions()) {
|
||||
Vec2 toWorldPoint(Sz row, Sz col, DrawOptions options = DrawOptions()) {
|
||||
auto targetTileWidth = cast(int) (tileWidth * options.scale.x);
|
||||
auto targetTileHeight = cast(int) (tileHeight * options.scale.y);
|
||||
auto temp = Rect(
|
||||
|
@ -229,32 +207,11 @@ struct TileMap {
|
|||
}
|
||||
|
||||
/// Returns the top left world position of a grid position.
|
||||
Vec2 worldPosition(IVec2 gridPosition, DrawOptions options = DrawOptions()) {
|
||||
return worldPosition(gridPosition.y, gridPosition.x, options);
|
||||
Vec2 toWorldPoint(IVec2 gridPosition, DrawOptions options = DrawOptions()) {
|
||||
return toWorldPoint(gridPosition.y, gridPosition.x, options);
|
||||
}
|
||||
|
||||
IVec2 firstGridPosition(Vec2 topLeftWorldPosition, DrawOptions options = DrawOptions()) {
|
||||
if (softRowCount == 0 || softColCount == 0) return IVec2();
|
||||
auto result = IVec2();
|
||||
auto targetTileWidth = cast(int) (tileWidth * options.scale.x);
|
||||
auto targetTileHeight = cast(int) (tileHeight * options.scale.y);
|
||||
result.y = cast(int) floor(clamp((topLeftWorldPosition.y - position.y) / targetTileHeight, 0, softRowCount - 1));
|
||||
result.x = cast(int) floor(clamp((topLeftWorldPosition.x - position.x) / targetTileWidth, 0, softColCount - 1));
|
||||
return result;
|
||||
}
|
||||
|
||||
IVec2 lastGridPosition(Vec2 bottomRightWorldPosition, DrawOptions options = DrawOptions()) {
|
||||
if (softRowCount == 0 || softColCount == 0) return IVec2();
|
||||
auto result = IVec2();
|
||||
auto targetTileWidth = cast(int) (tileWidth * options.scale.x);
|
||||
auto targetTileHeight = cast(int) (tileHeight * options.scale.y);
|
||||
auto extraTileCount = options.hook == Hook.topLeft ? 1 : 2;
|
||||
result.y = cast(int) floor(clamp((bottomRightWorldPosition.y - position.y) / targetTileHeight + extraTileCount, 0, softRowCount - 1));
|
||||
result.x = cast(int) floor(clamp((bottomRightWorldPosition.x - position.x) / targetTileWidth + extraTileCount, 0, softColCount - 1));
|
||||
return result;
|
||||
}
|
||||
|
||||
auto gridPositions(Vec2 topLeftWorldPosition, Vec2 bottomRightWorldPosition, DrawOptions options = DrawOptions()) {
|
||||
auto gridPoints(Vec2 topLeftWorldPoint, Vec2 bottomRightWorldPoint, DrawOptions options = DrawOptions()) {
|
||||
static struct Range {
|
||||
Sz colCount;
|
||||
IVec2 first;
|
||||
|
@ -278,17 +235,52 @@ struct TileMap {
|
|||
}
|
||||
}
|
||||
|
||||
auto result = Range(
|
||||
softColCount,
|
||||
firstGridPosition(topLeftWorldPosition, options),
|
||||
lastGridPosition(bottomRightWorldPosition, options),
|
||||
if (softRowCount == 0 || softColCount == 0) return Range();
|
||||
auto targetTileWidth = cast(int) (tileWidth * options.scale.x);
|
||||
auto targetTileHeight = cast(int) (tileHeight * options.scale.y);
|
||||
auto extraTileCount = options.hook == Hook.topLeft ? 1 : 2;
|
||||
auto firstGridPoint = IVec2(
|
||||
cast(int) clamp((topLeftWorldPoint.x - position.x) / targetTileWidth, 0, softColCount - 1),
|
||||
cast(int) clamp((topLeftWorldPoint.y - position.y) / targetTileHeight, 0, softRowCount - 1),
|
||||
);
|
||||
auto lastGridPoint = IVec2(
|
||||
cast(int) clamp((bottomRightWorldPoint.x - position.x) / targetTileWidth + extraTileCount, 0, softColCount - 1),
|
||||
cast(int) clamp((bottomRightWorldPoint.y - position.y) / targetTileHeight + extraTileCount, 0, softRowCount - 1),
|
||||
);
|
||||
return Range(
|
||||
softColCount,
|
||||
firstGridPoint,
|
||||
lastGridPoint,
|
||||
firstGridPoint,
|
||||
);
|
||||
result.position = result.first;
|
||||
return result;
|
||||
}
|
||||
|
||||
auto gridPositions(Rect worldArea, DrawOptions options = DrawOptions()) {
|
||||
return gridPositions(worldArea.topLeftPoint, worldArea.bottomRightPoint, options);
|
||||
auto gridPoints(Rect worldArea, DrawOptions options = DrawOptions()) {
|
||||
return gridPoints(worldArea.topLeftPoint, worldArea.bottomRightPoint, options);
|
||||
}
|
||||
|
||||
Fault parse(IStr csv, int newTileWidth, int newTileHeight) {
|
||||
if (csv.length == 0) return Fault.invalid;
|
||||
if (data.isEmpty) data.resizeBlank(defaultGridRowCount, defaultGridColCount);
|
||||
tileWidth = newTileWidth;
|
||||
tileHeight = newTileHeight;
|
||||
softRowCount = 0;
|
||||
softColCount = 0;
|
||||
auto view = csv;
|
||||
while (view.length != 0) {
|
||||
softRowCount += 1;
|
||||
softColCount = 0;
|
||||
if (softRowCount > data.rowCount) return Fault.invalid;
|
||||
auto line = view.skipLine();
|
||||
while (line.length != 0) {
|
||||
softColCount += 1;
|
||||
if (softColCount > data.colCount) return Fault.invalid;
|
||||
auto tile = line.skipValue(',').toSigned();
|
||||
if (tile.isNone) return Fault.invalid;
|
||||
data[softRowCount - 1, softColCount - 1] = cast(short) tile.get();
|
||||
}
|
||||
}
|
||||
return Fault.none;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -314,15 +306,21 @@ void drawTile(TextureId texture, Tile tile, DrawOptions options = DrawOptions())
|
|||
}
|
||||
|
||||
void drawTileMap(Texture texture, TileMap map, Camera camera, DrawOptions options = DrawOptions()) {
|
||||
if (texture.isEmpty || map.tileWidth <= 0 || map.tileHeight <= 0) return;
|
||||
|
||||
if (texture.isEmpty || map.softRowCount == 0 || map.softColCount == 0 || map.tileWidth <= 0 || map.tileHeight <= 0) return;
|
||||
auto topLeftWorldPoint = camera.topLeftPoint;
|
||||
auto bottomRightWorldPoint = camera.bottomRightPoint;
|
||||
auto textureColCount = texture.width / map.tileWidth;
|
||||
auto targetTileWidth = cast(int) (map.tileWidth * options.scale.x);
|
||||
auto targetTileHeight = cast(int) (map.tileHeight * options.scale.y);
|
||||
auto colRow1 = map.firstGridPosition(camera.topLeftPoint, options);
|
||||
auto colRow2 = map.lastGridPosition(camera.bottomRightPoint, options);
|
||||
if (colRow1.x == colRow2.x || colRow1.y == colRow2.y) return;
|
||||
|
||||
auto extraTileCount = options.hook == Hook.topLeft ? 1 : 2;
|
||||
auto colRow1 = IVec2(
|
||||
cast(int) clamp((topLeftWorldPoint.x - map.position.x) / targetTileWidth, 0, map.softColCount - 1),
|
||||
cast(int) clamp((topLeftWorldPoint.y - map.position.y) / targetTileHeight, 0, map.softRowCount - 1),
|
||||
);
|
||||
auto colRow2 = IVec2(
|
||||
cast(int) clamp((bottomRightWorldPoint.x - map.position.x) / targetTileWidth + extraTileCount, 0, map.softColCount - 1),
|
||||
cast(int) clamp((bottomRightWorldPoint.y - map.position.y) / targetTileHeight + extraTileCount, 0, map.softRowCount - 1),
|
||||
);
|
||||
auto textureArea = Rect(map.tileWidth, map.tileHeight);
|
||||
foreach (row; colRow1.y .. colRow2.y + 1) {
|
||||
foreach (col; colRow1.x .. colRow2.x + 1) {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
// TODO: Update all the doc comments here.
|
||||
// TODO: Add one-way collision support for moving walls.
|
||||
// TODO: Add spatial partitioning.
|
||||
// TODO: Add spatial partitioning. Just check the cell a box is in and the cells that are near it.
|
||||
// NOTE: Was working on spatial partitioning. The grid is done, just need to add values in it.
|
||||
|
||||
/// The `platformer` module provides a pixel-perfect physics engine.
|
||||
|
@ -146,127 +146,65 @@ struct BoxWorld {
|
|||
|
||||
@safe @nogc nothrow:
|
||||
|
||||
@trusted
|
||||
void appendWallIdToSpatialGrid(WallBoxId id) {
|
||||
FixedList!(IVec2, 4) vecSet = void;
|
||||
// vecSet.clear();
|
||||
// auto taggedId = id & ~(1 << 31);
|
||||
// foreach (position; getWallSpatialGridPositions) {
|
||||
// auto canAppend = true;
|
||||
// foreach (vec; vecSet) {
|
||||
// if (vec == position) {
|
||||
// canAppend = false;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (canAppend) {
|
||||
// grid[vec.y, vec.x].append(taggedId);
|
||||
// vecSet.append(vec);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void removeWallIdFromSpatialGrid(WallBoxId id) {
|
||||
|
||||
}
|
||||
|
||||
void enableSpatialGrid(Sz rowCount, Sz colCount, int tileWidth, int tileHeight) {
|
||||
void enableGrid(Sz rowCount, Sz colCount, int tileWidth, int tileHeight) {
|
||||
gridTileWidth = tileWidth;
|
||||
gridTileHeight = tileHeight;
|
||||
grid.resizeBlank(rowCount, colCount);
|
||||
foreach (ref group; grid) {
|
||||
group.length = 0;
|
||||
}
|
||||
foreach (ref group; grid) group.clear();
|
||||
foreach (i, ref properties; wallsProperties) {
|
||||
auto id = cast(BaseBoxId) (i + 1);
|
||||
auto tagged = id & ~(1 << 31);
|
||||
auto positions = getWallSpatialGridPositions(id);
|
||||
// grid[positions[0].y, positions[0].x].append(tagged);
|
||||
// if (positions[0] != positions[1]) {
|
||||
// grid[positions[1].y, positions[1].x].append(tagged);
|
||||
// }
|
||||
auto point = getWallGridPoint(id);
|
||||
grid[point.y, point.x].append(id & ~(1 << 31));
|
||||
}
|
||||
foreach (i, ref properties; actorsProperties) {
|
||||
auto id = cast(BaseBoxId) (i + 1);
|
||||
auto tagged = id | (1 << 31);
|
||||
auto positions = getActorSpatialGridPositions(id);
|
||||
// grid[positions[0].y, positions[0].x].append(tagged);
|
||||
// if (positions[0] != positions[1]) {
|
||||
// grid[positions[1].y, positions[1].x].append(tagged);
|
||||
// }
|
||||
auto point = getActorGridPoint(id);
|
||||
grid[point.y, point.x].append(id | (1 << 31));
|
||||
}
|
||||
}
|
||||
|
||||
void disableSpatialGrid() {
|
||||
void disableGrid() {
|
||||
gridTileWidth = 0;
|
||||
gridTileHeight = 0;
|
||||
grid.clear();
|
||||
}
|
||||
|
||||
ref IRect getWall(WallBoxId id) {
|
||||
if (id == 0) {
|
||||
assert(0, "ID `0` is always invalid and represents a box that was never created.");
|
||||
} else if (id > walls.length) {
|
||||
assert(0, "ID `{}` does not exist.".format(id));
|
||||
}
|
||||
if (id == 0) assert(0, "ID `0` is always invalid and represents a box that was never created.");
|
||||
return walls[id - 1];
|
||||
}
|
||||
|
||||
ref WallBoxProperties getWallProperties(WallBoxId id) {
|
||||
if (id == 0) {
|
||||
assert(0, "ID `0` is always invalid and represents a box that was never created.");
|
||||
} else if (id > wallsProperties.length) {
|
||||
assert(0, "ID `{}` does not exist.".format(id));
|
||||
}
|
||||
if (id == 0) assert(0, "ID `0` is always invalid and represents a box that was never created.");
|
||||
return wallsProperties[id - 1];
|
||||
}
|
||||
|
||||
@trusted
|
||||
IVec2[4] getWallSpatialGridPositions(WallBoxId id) {
|
||||
IVec2[4] result = void;
|
||||
IVec2 getWallGridPoint(WallBoxId id) {
|
||||
if (id == 0) assert(0, "ID `0` is always invalid and represents a box that was never created.");
|
||||
auto i = id - 1;
|
||||
result[0].x = walls[i].position.x / gridTileWidth - (walls[i].position.x < 0);
|
||||
result[0].y = walls[i].position.y / gridTileHeight - (walls[i].position.y < 0);
|
||||
result[3].x = (walls[i].position.x + walls[i].size.x) - ((walls[i].position.x + walls[i].size.x) < 0);
|
||||
result[3].y = (walls[i].position.y + walls[i].size.y) - ((walls[i].position.y + walls[i].size.y) < 0);
|
||||
result[1].x = result[3].x;
|
||||
result[1].y = result[0].y;
|
||||
result[2].x = result[0].x;
|
||||
result[2].y = result[3].y;
|
||||
return result;
|
||||
return IVec2(
|
||||
walls[i].position.x / gridTileWidth - (walls[i].position.x < 0),
|
||||
walls[i].position.y / gridTileHeight - (walls[i].position.y < 0),
|
||||
);
|
||||
}
|
||||
|
||||
ref IRect getActor(ActorBoxId id) {
|
||||
if (id == 0) {
|
||||
assert(0, "ID `0` is always invalid and represents a box that was never created.");
|
||||
} else if (id > actors.length) {
|
||||
assert(0, "ID `{}` does not exist.".format(id));
|
||||
}
|
||||
if (id == 0) assert(0, "ID `0` is always invalid and represents a box that was never created.");
|
||||
return actors[id - 1];
|
||||
}
|
||||
|
||||
ref ActorBoxProperties getActorProperties(ActorBoxId id) {
|
||||
if (id == 0) {
|
||||
assert(0, "ID `0` is always invalid and represents a box that was never created.");
|
||||
} else if (id > actorsProperties.length) {
|
||||
assert(0, "ID `{}` does not exist.".format(id));
|
||||
}
|
||||
if (id == 0) assert(0, "ID `0` is always invalid and represents a box that was never created.");
|
||||
return actorsProperties[id - 1];
|
||||
}
|
||||
|
||||
@trusted
|
||||
IVec2[4] getActorSpatialGridPositions(WallBoxId id) {
|
||||
IVec2[4] result = void;
|
||||
IVec2 getActorGridPoint(ActorBoxId id) {
|
||||
if (id == 0) assert(0, "ID `0` is always invalid and represents a box that was never created.");
|
||||
auto i = id - 1;
|
||||
result[0].x = actors[i].position.x / gridTileWidth - (actors[i].position.x < 0);
|
||||
result[0].y = actors[i].position.y / gridTileHeight - (actors[i].position.y < 0);
|
||||
result[1].x = (actors[i].position.x + actors[i].size.x) - ((actors[i].position.x + actors[i].size.x) < 0);
|
||||
result[1].y = (actors[i].position.y + actors[i].size.y) - ((actors[i].position.y + actors[i].size.y) < 0);
|
||||
result[1].x = result[3].x;
|
||||
result[1].y = result[0].y;
|
||||
result[2].x = result[0].x;
|
||||
result[2].y = result[3].y;
|
||||
return result;
|
||||
return IVec2(
|
||||
actors[i].position.x / gridTileWidth - (actors[i].position.x < 0),
|
||||
actors[i].position.y / gridTileHeight - (actors[i].position.y < 0),
|
||||
);
|
||||
}
|
||||
|
||||
WallBoxId appendWall(IRect box, OneWaySide oneWaySide = OneWaySide.none) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue