silphius/app/ecs-components/tile-layers.js

113 lines
3.3 KiB
JavaScript
Raw Normal View History

2024-06-14 12:05:02 -05:00
import vector2d from './helpers/vector-2d';
2024-06-25 04:50:13 -05:00
import Schema from '@/ecs/schema.js';
export default function(Component) {
return class TileLayers extends Component {
insertMany(entities) {
for (const [id, {layerChange}] of entities) {
if (layerChange) {
const component = this.get(id);
const {layers} = component;
for (const layerIndex in layerChange) {
for (const calculated in layerChange[layerIndex]) {
const tile = layerChange[layerIndex][calculated];
layers[layerIndex].data[calculated] = tile;
}
layers[layerIndex] = {...layers[layerIndex]};
}
}
}
return super.insertMany(entities);
}
mergeDiff(original, update) {
if (!update.layerChange) {
return super.mergeDiff(original, update);
}
const layerChange = {
...original.layerChange,
};
for (const index in update.layerChange) {
layerChange[index] = {
...layerChange[index],
...update.layerChange[index],
};
}
return {layerChange};
}
instanceFromSchema() {
const Instance = super.instanceFromSchema();
const Component = this;
Instance.prototype.layer = function (index) {
const {layers} = this;
if (!(index in layers)) {
return undefined;
}
const instance = this;
class LayerProxy {
constructor(layer) {
this.layer = layer;
}
2024-06-26 04:16:14 -05:00
get area() {
return this.layer.area;
}
get source() {
return this.layer.source;
}
2024-06-25 04:50:13 -05:00
stamp(at, data) {
const changes = {};
for (const row in data) {
const columns = data[row];
for (const column in columns) {
const tile = columns[column];
const x = at.x + parseInt(column);
const y = at.y + parseInt(row);
if (x < 0 || y < 0 || x >= this.layer.area.x || y >= this.layer.area.y) {
continue;
}
const calculated = y * this.layer.area.x + x;
this.layer.data[calculated] = tile;
changes[calculated] = tile;
}
}
Component.markChange(instance.entity, 'layerChange', {[index]: changes});
}
2024-06-25 07:08:50 -05:00
tile({x, y}) {
if (x < 0 || y < 0 || x >= this.layer.area.x || y >= this.layer.area.y) {
return undefined;
}
return this.layer.data[y * this.layer.area.x + x];
}
2024-06-26 04:16:14 -05:00
get tileSize() {
return this.layer.tileSize;
}
2024-06-25 04:50:13 -05:00
}
return new LayerProxy(layers[index]);
};
return Instance;
}
static schema = new Schema({
2024-06-12 13:19:16 -05:00
type: 'object',
properties: {
2024-06-25 04:50:13 -05:00
layers: {
2024-06-12 13:19:16 -05:00
type: 'array',
subtype: {
2024-06-25 04:50:13 -05:00
type: 'object',
properties: {
area: vector2d('float32'),
data: {
type: 'array',
subtype: {
type: 'uint16',
},
},
source: {type: 'string'},
tileSize: vector2d('float32'),
},
2024-06-12 13:19:16 -05:00
},
},
},
2024-06-25 04:50:13 -05:00
});
}
}