refactor: engine
This commit is contained in:
parent
0685243b7b
commit
6a7aa68002
7
app/ecs-components/helpers/vector-2d.js
Normal file
7
app/ecs-components/helpers/vector-2d.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
export default (type) => ({
|
||||
type: 'object',
|
||||
properties: {
|
||||
x: {type},
|
||||
y: {type},
|
||||
},
|
||||
});
|
|
@ -1,15 +1,20 @@
|
|||
import vector2d from './helpers/vector-2d';
|
||||
|
||||
export default {
|
||||
layers: {
|
||||
type: 'array',
|
||||
subtype: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
area: vector2d('float32'),
|
||||
data: {
|
||||
type: 'array',
|
||||
subtype: {
|
||||
type: 'uint16',
|
||||
},
|
||||
},
|
||||
source: {type: 'string'},
|
||||
tileSize: vector2d('float32'),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import {
|
||||
MOVE_MAP,
|
||||
RESOLUTION,
|
||||
TPS,
|
||||
} from '@/constants.js';
|
||||
import ControlMovement from '@/ecs-systems/control-movement.js';
|
||||
|
@ -36,8 +35,6 @@ const players = {
|
|||
|
||||
export default class Engine {
|
||||
|
||||
static Ecs = Ecs;
|
||||
|
||||
incomingActions = [];
|
||||
|
||||
connections = [];
|
||||
|
@ -53,34 +50,8 @@ export default class Engine {
|
|||
server;
|
||||
|
||||
constructor(Server) {
|
||||
const ecs = new this.constructor.Ecs();
|
||||
const layerSize = {x: Math.ceil(RESOLUTION.x / 4), y: Math.ceil(RESOLUTION.y / 4)};
|
||||
ecs.create({
|
||||
AreaSize: {x: RESOLUTION.x * 4, y: RESOLUTION.y * 4},
|
||||
TileLayers: {
|
||||
layers: [
|
||||
{
|
||||
data: (
|
||||
Array(layerSize.x * layerSize.y)
|
||||
.fill(0)
|
||||
.map(() => 1 + Math.floor(Math.random() * 4))
|
||||
),
|
||||
size: layerSize,
|
||||
}
|
||||
],
|
||||
},
|
||||
});
|
||||
ecs.addSystem(ControlMovement);
|
||||
ecs.addSystem(ApplyMomentum);
|
||||
ecs.addSystem(ClampPositions);
|
||||
ecs.addSystem(FollowCamera);
|
||||
ecs.addSystem(CalculateAabbs);
|
||||
ecs.addSystem(UpdateSpatialHash);
|
||||
ecs.addSystem(ControlDirection);
|
||||
ecs.addSystem(SpriteDirection);
|
||||
ecs.addSystem(RunAnimations);
|
||||
this.ecses = {
|
||||
1: ecs,
|
||||
1: this.createHomestead(),
|
||||
};
|
||||
class SilphiusServer extends Server {
|
||||
accept(connection, packed) {
|
||||
|
@ -110,6 +81,38 @@ export default class Engine {
|
|||
);
|
||||
}
|
||||
|
||||
createEcs(master) {
|
||||
const ecs = new Ecs();
|
||||
ecs.create(master);
|
||||
ecs.addSystem(ControlMovement);
|
||||
ecs.addSystem(ApplyMomentum);
|
||||
ecs.addSystem(ClampPositions);
|
||||
ecs.addSystem(FollowCamera);
|
||||
ecs.addSystem(CalculateAabbs);
|
||||
ecs.addSystem(UpdateSpatialHash);
|
||||
ecs.addSystem(ControlDirection);
|
||||
ecs.addSystem(SpriteDirection);
|
||||
ecs.addSystem(RunAnimations);
|
||||
return ecs;
|
||||
}
|
||||
|
||||
createHomestead() {
|
||||
const area = {x: 100, y: 60};
|
||||
return this.createEcs({
|
||||
AreaSize: {x: area.x * 16, y: area.y * 16},
|
||||
TileLayers: {
|
||||
layers: [
|
||||
{
|
||||
area,
|
||||
data: Array(area.x * area.y).fill(0).map(() => 1 + Math.floor(Math.random() * 4)),
|
||||
source: '/assets/tileset.json',
|
||||
tileSize: {x: 16, y: 16},
|
||||
}
|
||||
],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
disconnectPlayer(connection) {
|
||||
const {entity} = this.connectedPlayers.get(connection);
|
||||
const ecs = this.ecses[entity.World.world];
|
||||
|
|
15
app/hooks/use-asset.js
Normal file
15
app/hooks/use-asset.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
import {Assets} from '@pixi/assets';
|
||||
import {useEffect, useState} from 'react';
|
||||
|
||||
export default function useAsset(source) {
|
||||
const [asset, setAsset] = useState();
|
||||
useEffect(() => {
|
||||
if (Assets.cache.has(source)) {
|
||||
setAsset(Assets.get(source));
|
||||
}
|
||||
else {
|
||||
Assets.load(source).then(setAsset);
|
||||
}
|
||||
}, [setAsset, source]);
|
||||
return asset;
|
||||
}
|
|
@ -43,10 +43,7 @@ export default function EcsComponent() {
|
|||
return (
|
||||
<Container>
|
||||
<TileLayer
|
||||
size={TileLayers.layers[0].size}
|
||||
tiles={TileLayers.layers[0].data}
|
||||
tileset="/assets/tileset.json"
|
||||
tileSize={{x: 16, y: 16}}
|
||||
tileLayer={TileLayers.layers[0]}
|
||||
x={-cx}
|
||||
y={-cy}
|
||||
/>
|
||||
|
|
|
@ -1,18 +1,9 @@
|
|||
import {Assets} from '@pixi/assets';
|
||||
import {Sprite as PixiSprite} from '@pixi/react';
|
||||
import {useEffect, useState} from 'react';
|
||||
|
||||
import useAsset from '@/hooks/use-asset.js';
|
||||
|
||||
export default function Sprite({entity}) {
|
||||
const [asset, setAsset] = useState();
|
||||
useEffect(() => {
|
||||
const asset = Assets.get(entity.Sprite.source);
|
||||
if (asset) {
|
||||
setAsset(asset);
|
||||
}
|
||||
else {
|
||||
Assets.load(entity.Sprite.source).then(setAsset);
|
||||
}
|
||||
}, [setAsset, entity.Sprite.source]);
|
||||
const asset = useAsset(entity.Sprite.source);
|
||||
if (!asset) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,42 +1,33 @@
|
|||
import {useEffect, useState} from 'react';
|
||||
import {Assets} from '@pixi/assets';
|
||||
import {PixiComponent} from '@pixi/react';
|
||||
import '@pixi/spritesheet'; // NECESSARY!
|
||||
import {CompositeTilemap} from '@pixi/tilemap';
|
||||
|
||||
import useAsset from '@/hooks/use-asset.js';
|
||||
|
||||
const TileLayerInternal = PixiComponent('TileLayer', {
|
||||
create: () => new CompositeTilemap(),
|
||||
applyProps: (tilemap, {tiles: oldTiles}, props) => {
|
||||
const {asset, tiles, tileset, tileSize, size, x, y} = props;
|
||||
const extless = tileset.slice('/assets/'.length, -'.json'.length);
|
||||
applyProps: (tilemap, {tileLayer: oldTileLayer}, props) => {
|
||||
const {asset, tileLayer, x, y} = props;
|
||||
const extless = tileLayer.source.slice('/assets/'.length, -'.json'.length);
|
||||
const {textures} = asset;
|
||||
tilemap.position.x = x;
|
||||
tilemap.position.y = y;
|
||||
if (tiles === oldTiles) {
|
||||
if (tileLayer === oldTileLayer) {
|
||||
return;
|
||||
}
|
||||
tilemap.clear();
|
||||
let i = 0;
|
||||
for (let y = 0; y < size.y; ++y) {
|
||||
for (let x = 0; x < size.x; ++x) {
|
||||
tilemap.tile(textures[`${extless}/${tiles[i++]}`], tileSize.x * x, tileSize.y * y);
|
||||
for (let y = 0; y < tileLayer.area.y; ++y) {
|
||||
for (let x = 0; x < tileLayer.area.x; ++x) {
|
||||
tilemap.tile(textures[`${extless}/${tileLayer.data[i++]}`], tileLayer.tileSize.x * x, tileLayer.tileSize.y * y);
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
export default function TileLayer(props) {
|
||||
const {tileset} = props;
|
||||
const [asset, setAsset] = useState();
|
||||
useEffect(() => {
|
||||
const asset = Assets.get(tileset);
|
||||
if (asset) {
|
||||
setAsset(asset);
|
||||
}
|
||||
else {
|
||||
Assets.load(tileset).then(setAsset);
|
||||
}
|
||||
}, [setAsset, tileset]);
|
||||
const {tileLayer} = props;
|
||||
const asset = useAsset(tileLayer.source);
|
||||
if (!asset) {
|
||||
return false;
|
||||
}
|
||||
|
@ -44,7 +35,6 @@ export default function TileLayer(props) {
|
|||
<TileLayerInternal
|
||||
{...props}
|
||||
asset={asset}
|
||||
tileset={tileset}
|
||||
/>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user