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 {
|
export default {
|
||||||
layers: {
|
layers: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
subtype: {
|
subtype: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
|
area: vector2d('float32'),
|
||||||
data: {
|
data: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
subtype: {
|
subtype: {
|
||||||
type: 'uint16',
|
type: 'uint16',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
source: {type: 'string'},
|
||||||
|
tileSize: vector2d('float32'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import {
|
import {
|
||||||
MOVE_MAP,
|
MOVE_MAP,
|
||||||
RESOLUTION,
|
|
||||||
TPS,
|
TPS,
|
||||||
} from '@/constants.js';
|
} from '@/constants.js';
|
||||||
import ControlMovement from '@/ecs-systems/control-movement.js';
|
import ControlMovement from '@/ecs-systems/control-movement.js';
|
||||||
|
@ -36,8 +35,6 @@ const players = {
|
||||||
|
|
||||||
export default class Engine {
|
export default class Engine {
|
||||||
|
|
||||||
static Ecs = Ecs;
|
|
||||||
|
|
||||||
incomingActions = [];
|
incomingActions = [];
|
||||||
|
|
||||||
connections = [];
|
connections = [];
|
||||||
|
@ -53,34 +50,8 @@ export default class Engine {
|
||||||
server;
|
server;
|
||||||
|
|
||||||
constructor(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 = {
|
this.ecses = {
|
||||||
1: ecs,
|
1: this.createHomestead(),
|
||||||
};
|
};
|
||||||
class SilphiusServer extends Server {
|
class SilphiusServer extends Server {
|
||||||
accept(connection, packed) {
|
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) {
|
disconnectPlayer(connection) {
|
||||||
const {entity} = this.connectedPlayers.get(connection);
|
const {entity} = this.connectedPlayers.get(connection);
|
||||||
const ecs = this.ecses[entity.World.world];
|
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 (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<TileLayer
|
<TileLayer
|
||||||
size={TileLayers.layers[0].size}
|
tileLayer={TileLayers.layers[0]}
|
||||||
tiles={TileLayers.layers[0].data}
|
|
||||||
tileset="/assets/tileset.json"
|
|
||||||
tileSize={{x: 16, y: 16}}
|
|
||||||
x={-cx}
|
x={-cx}
|
||||||
y={-cy}
|
y={-cy}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,18 +1,9 @@
|
||||||
import {Assets} from '@pixi/assets';
|
|
||||||
import {Sprite as PixiSprite} from '@pixi/react';
|
import {Sprite as PixiSprite} from '@pixi/react';
|
||||||
import {useEffect, useState} from 'react';
|
|
||||||
|
import useAsset from '@/hooks/use-asset.js';
|
||||||
|
|
||||||
export default function Sprite({entity}) {
|
export default function Sprite({entity}) {
|
||||||
const [asset, setAsset] = useState();
|
const asset = useAsset(entity.Sprite.source);
|
||||||
useEffect(() => {
|
|
||||||
const asset = Assets.get(entity.Sprite.source);
|
|
||||||
if (asset) {
|
|
||||||
setAsset(asset);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Assets.load(entity.Sprite.source).then(setAsset);
|
|
||||||
}
|
|
||||||
}, [setAsset, entity.Sprite.source]);
|
|
||||||
if (!asset) {
|
if (!asset) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +1,33 @@
|
||||||
import {useEffect, useState} from 'react';
|
|
||||||
import {Assets} from '@pixi/assets';
|
|
||||||
import {PixiComponent} from '@pixi/react';
|
import {PixiComponent} from '@pixi/react';
|
||||||
import '@pixi/spritesheet'; // NECESSARY!
|
import '@pixi/spritesheet'; // NECESSARY!
|
||||||
import {CompositeTilemap} from '@pixi/tilemap';
|
import {CompositeTilemap} from '@pixi/tilemap';
|
||||||
|
|
||||||
|
import useAsset from '@/hooks/use-asset.js';
|
||||||
|
|
||||||
const TileLayerInternal = PixiComponent('TileLayer', {
|
const TileLayerInternal = PixiComponent('TileLayer', {
|
||||||
create: () => new CompositeTilemap(),
|
create: () => new CompositeTilemap(),
|
||||||
applyProps: (tilemap, {tiles: oldTiles}, props) => {
|
applyProps: (tilemap, {tileLayer: oldTileLayer}, props) => {
|
||||||
const {asset, tiles, tileset, tileSize, size, x, y} = props;
|
const {asset, tileLayer, x, y} = props;
|
||||||
const extless = tileset.slice('/assets/'.length, -'.json'.length);
|
const extless = tileLayer.source.slice('/assets/'.length, -'.json'.length);
|
||||||
const {textures} = asset;
|
const {textures} = asset;
|
||||||
tilemap.position.x = x;
|
tilemap.position.x = x;
|
||||||
tilemap.position.y = y;
|
tilemap.position.y = y;
|
||||||
if (tiles === oldTiles) {
|
if (tileLayer === oldTileLayer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tilemap.clear();
|
tilemap.clear();
|
||||||
let i = 0;
|
let i = 0;
|
||||||
for (let y = 0; y < size.y; ++y) {
|
for (let y = 0; y < tileLayer.area.y; ++y) {
|
||||||
for (let x = 0; x < size.x; ++x) {
|
for (let x = 0; x < tileLayer.area.x; ++x) {
|
||||||
tilemap.tile(textures[`${extless}/${tiles[i++]}`], tileSize.x * x, tileSize.y * y);
|
tilemap.tile(textures[`${extless}/${tileLayer.data[i++]}`], tileLayer.tileSize.x * x, tileLayer.tileSize.y * y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export default function TileLayer(props) {
|
export default function TileLayer(props) {
|
||||||
const {tileset} = props;
|
const {tileLayer} = props;
|
||||||
const [asset, setAsset] = useState();
|
const asset = useAsset(tileLayer.source);
|
||||||
useEffect(() => {
|
|
||||||
const asset = Assets.get(tileset);
|
|
||||||
if (asset) {
|
|
||||||
setAsset(asset);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Assets.load(tileset).then(setAsset);
|
|
||||||
}
|
|
||||||
}, [setAsset, tileset]);
|
|
||||||
if (!asset) {
|
if (!asset) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -44,7 +35,6 @@ export default function TileLayer(props) {
|
||||||
<TileLayerInternal
|
<TileLayerInternal
|
||||||
{...props}
|
{...props}
|
||||||
asset={asset}
|
asset={asset}
|
||||||
tileset={tileset}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user