feat: tile hulls
This commit is contained in:
parent
64ece0cb86
commit
cd875f8025
|
@ -1,7 +1,7 @@
|
||||||
import gather from '@/util/gather.js';
|
import gather from '@/util/gather.js';
|
||||||
|
|
||||||
const Gathered = gather(
|
const Gathered = gather(
|
||||||
import.meta.glob('./*.js', {eager: true, import: 'default'}),
|
import.meta.glob(['./*.js', '!./*.test.js'], {eager: true, import: 'default'}),
|
||||||
);
|
);
|
||||||
|
|
||||||
const Components = {};
|
const Components = {};
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import Component from '@/ecs/component.js';
|
import Component from '@/ecs/component.js';
|
||||||
|
import {floodwalk2D, ortho, removeCollinear} from '@/util/math.js';
|
||||||
|
|
||||||
import vector2d from './helpers/vector-2d';
|
import vector2d from './helpers/vector-2d';
|
||||||
|
|
||||||
|
@ -14,6 +15,67 @@ class LayerProxy {
|
||||||
get data() {
|
get data() {
|
||||||
return this.layer.data;
|
return this.layer.data;
|
||||||
}
|
}
|
||||||
|
get hulls() {
|
||||||
|
const {data, area, tileSize} = this;
|
||||||
|
const hulls = [];
|
||||||
|
const seen = {};
|
||||||
|
const n = data.length;
|
||||||
|
const {x: w, y: h} = area;
|
||||||
|
let x = 0;
|
||||||
|
let y = 0;
|
||||||
|
for (let i = 0; i < n; ++i) {
|
||||||
|
if (data[i]) {
|
||||||
|
if (!seen[i]) {
|
||||||
|
const indices = floodwalk2D(new Set([data[i]]), data, {x, y, w, h});
|
||||||
|
if (indices.size > 0) {
|
||||||
|
const pointHash = Object.create(null);
|
||||||
|
const points = [];
|
||||||
|
const seePoint = ({x, y}) => {
|
||||||
|
if (pointHash[y]?.[x]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!pointHash[y]) {
|
||||||
|
pointHash[y] = Object.create({});
|
||||||
|
}
|
||||||
|
return pointHash[y][x] = true;
|
||||||
|
};
|
||||||
|
for (const index of indices) {
|
||||||
|
seen[index] = true;
|
||||||
|
const op = {
|
||||||
|
x: tileSize.x * (index % area.x),
|
||||||
|
y: tileSize.y * (Math.floor(index / area.x)),
|
||||||
|
};
|
||||||
|
let p;
|
||||||
|
const tsq = {x: tileSize.x / 4, y: tileSize.y / 4};
|
||||||
|
p = {x: op.x + tsq.x, y: op.y + tsq.y};
|
||||||
|
if (seePoint(p)) {
|
||||||
|
points.push(p);
|
||||||
|
}
|
||||||
|
p = {x: op.x + tileSize.x - tsq.x, y: op.y + tsq.y};
|
||||||
|
if (seePoint(p)) {
|
||||||
|
points.push(p);
|
||||||
|
}
|
||||||
|
p = {x: op.x + tileSize.x - tsq.x, y: op.y + tileSize.y - tsq.y};
|
||||||
|
if (seePoint(p)) {
|
||||||
|
points.push(p);
|
||||||
|
}
|
||||||
|
p = {x: op.x + tsq.x, y: op.y + tileSize.y - tsq.y};
|
||||||
|
if (seePoint(p)) {
|
||||||
|
points.push(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hulls.push(removeCollinear(ortho(points, {x: tileSize.x / 2, y: tileSize.y / 2})));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x += 1;
|
||||||
|
if (x === w) {
|
||||||
|
x -= w;
|
||||||
|
y += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hulls;
|
||||||
|
}
|
||||||
get layer() {
|
get layer() {
|
||||||
return this.instance.layers[this.index];
|
return this.instance.layers[this.index];
|
||||||
}
|
}
|
||||||
|
|
45
app/ecs-components/tile-layers.test.js
Normal file
45
app/ecs-components/tile-layers.test.js
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import {expect, test} from 'vitest';
|
||||||
|
|
||||||
|
import Ecs from '@/ecs/ecs.js';
|
||||||
|
|
||||||
|
import TileLayers from './tile-layers.js';
|
||||||
|
|
||||||
|
test('creates hulls', async () => {
|
||||||
|
const Component = new TileLayers(new Ecs());
|
||||||
|
const data = Array(64).fill(0);
|
||||||
|
data[9] = 1;
|
||||||
|
data[10] = 1;
|
||||||
|
data[17] = 1;
|
||||||
|
data[18] = 1;
|
||||||
|
const layers = await Component.create(1, {
|
||||||
|
layers: [
|
||||||
|
{
|
||||||
|
area: {x: 8, y: 8},
|
||||||
|
data,
|
||||||
|
source: '',
|
||||||
|
tileSize: {x: 16, y: 16},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
});
|
||||||
|
expect(layers.layer(0).hulls)
|
||||||
|
.to.deep.equal([
|
||||||
|
[
|
||||||
|
{x: 20, y: 20},
|
||||||
|
{x: 44, y: 20},
|
||||||
|
{x: 44, y: 44},
|
||||||
|
{x: 20, y: 44},
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
data[11] = 1;
|
||||||
|
expect(layers.layer(0).hulls)
|
||||||
|
.to.deep.equal([
|
||||||
|
[
|
||||||
|
{x: 20, y: 20},
|
||||||
|
{x: 60, y: 20},
|
||||||
|
{x: 60, y: 28},
|
||||||
|
{x: 44, y: 28},
|
||||||
|
{x: 44, y: 44},
|
||||||
|
{x: 20, y: 44},
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user