feat: real visible AABB
This commit is contained in:
parent
5db0478b19
commit
183c8254a2
|
@ -3,6 +3,9 @@ import Component from '@/ecs/component.js';
|
||||||
import vector2d from "./helpers/vector-2d";
|
import vector2d from "./helpers/vector-2d";
|
||||||
|
|
||||||
export default class Sprite extends Component {
|
export default class Sprite extends Component {
|
||||||
|
async load(instance) {
|
||||||
|
instance.$$sourceJson = await this.ecs.readJson(instance.source);
|
||||||
|
}
|
||||||
static properties = {
|
static properties = {
|
||||||
anchor: vector2d('float32', {x: 0.5, y: 0.5}),
|
anchor: vector2d('float32', {x: 0.5, y: 0.5}),
|
||||||
animation: {type: 'string'},
|
animation: {type: 'string'},
|
||||||
|
|
|
@ -9,12 +9,24 @@ export default class CalculateAabbs extends System {
|
||||||
}
|
}
|
||||||
|
|
||||||
tick() {
|
tick() {
|
||||||
for (const {Position: {x, y}, VisibleAabb} of this.ecs.changed(['Position'])) {
|
for (const entity of this.ecs.changed(['Position'])) {
|
||||||
|
const {Position: {x, y}, Sprite, VisibleAabb} = entity;
|
||||||
if (VisibleAabb) {
|
if (VisibleAabb) {
|
||||||
VisibleAabb.x0 = x - 32;
|
let size = undefined;
|
||||||
VisibleAabb.x1 = x + 32;
|
if (Sprite) {
|
||||||
VisibleAabb.y0 = y - 32;
|
const frame = Sprite.animation
|
||||||
VisibleAabb.y1 = y + 32;
|
? Sprite.$$sourceJson.animations[Sprite.animation][Sprite.frame]
|
||||||
|
: '';
|
||||||
|
size = Sprite.$$sourceJson.frames[frame].sourceSize;
|
||||||
|
}
|
||||||
|
/* v8 ignore next 3 */
|
||||||
|
if (!size) {
|
||||||
|
throw new Error(`no size for aabb for entity ${entity.id}(${JSON.stringify(entity.toJSON(), null, 2)})`);
|
||||||
|
}
|
||||||
|
VisibleAabb.x0 = x - ((size.w ) * (Sprite.anchor.x));
|
||||||
|
VisibleAabb.x1 = x + ((size.w ) * (1 - Sprite.anchor.x));
|
||||||
|
VisibleAabb.y0 = y - ((size.h ) * (Sprite.anchor.y));
|
||||||
|
VisibleAabb.y1 = y + ((size.h ) * (1 - Sprite.anchor.y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ export default class Engine {
|
||||||
|
|
||||||
connections = [];
|
connections = [];
|
||||||
connectedPlayers = new Map();
|
connectedPlayers = new Map();
|
||||||
|
connectingPlayers = [];
|
||||||
ecses = {};
|
ecses = {};
|
||||||
frame = 0;
|
frame = 0;
|
||||||
handle;
|
handle;
|
||||||
|
@ -53,7 +54,7 @@ export default class Engine {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
acceptActions() {
|
async acceptActions() {
|
||||||
for (const [
|
for (const [
|
||||||
entity,
|
entity,
|
||||||
payload,
|
payload,
|
||||||
|
@ -103,21 +104,28 @@ export default class Engine {
|
||||||
}
|
}
|
||||||
|
|
||||||
async connectPlayer(connection, id) {
|
async connectPlayer(connection, id) {
|
||||||
const entityJson = await this.loadPlayer(id);
|
this.connectingPlayers.push([connection, id]);
|
||||||
if (!this.ecses[entityJson.Ecs.path]) {
|
}
|
||||||
await this.loadEcs(entityJson.Ecs.path);
|
|
||||||
|
async connectPlayers() {
|
||||||
|
for (const [connection, id] of this.connectingPlayers) {
|
||||||
|
const entityJson = await this.loadPlayer(id);
|
||||||
|
if (!this.ecses[entityJson.Ecs.path]) {
|
||||||
|
await this.loadEcs(entityJson.Ecs.path);
|
||||||
|
}
|
||||||
|
const ecs = this.ecses[entityJson.Ecs.path];
|
||||||
|
const entity = await ecs.create(entityJson);
|
||||||
|
this.connections.push(connection);
|
||||||
|
this.connectedPlayers.set(
|
||||||
|
connection,
|
||||||
|
{
|
||||||
|
entity: ecs.get(entity),
|
||||||
|
id,
|
||||||
|
memory: new Set(),
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
const ecs = this.ecses[entityJson.Ecs.path];
|
this.connectingPlayers = [];
|
||||||
const entity = await ecs.create(entityJson);
|
|
||||||
this.connections.push(connection);
|
|
||||||
this.connectedPlayers.set(
|
|
||||||
connection,
|
|
||||||
{
|
|
||||||
entity: ecs.get(entity),
|
|
||||||
id,
|
|
||||||
memory: new Set(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createEcs() {
|
createEcs() {
|
||||||
|
@ -146,7 +154,7 @@ export default class Engine {
|
||||||
Position: {x: 100, y: 100},
|
Position: {x: 100, y: 100},
|
||||||
Sprite: {
|
Sprite: {
|
||||||
anchor: {x: 0.5, y: 0.8},
|
anchor: {x: 0.5, y: 0.8},
|
||||||
source: '/assets/shit-shack/shit-shack.png',
|
source: '/assets/shit-shack/shit-shack.json',
|
||||||
},
|
},
|
||||||
VisibleAabb: {},
|
VisibleAabb: {},
|
||||||
});
|
});
|
||||||
|
@ -290,19 +298,22 @@ export default class Engine {
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
this.handle = setInterval(() => {
|
const loop = async () => {
|
||||||
|
await this.connectPlayers();
|
||||||
|
await this.acceptActions();
|
||||||
const elapsed = (Date.now() - this.last) / 1000;
|
const elapsed = (Date.now() - this.last) / 1000;
|
||||||
this.last = Date.now();
|
this.last = Date.now();
|
||||||
this.acceptActions();
|
|
||||||
this.tick(elapsed);
|
this.tick(elapsed);
|
||||||
this.update(elapsed);
|
this.update(elapsed);
|
||||||
this.setClean();
|
this.setClean();
|
||||||
this.frame += 1;
|
this.frame += 1;
|
||||||
}, 1000 / TPS);
|
this.handle = setTimeout(loop, 1000 / TPS);
|
||||||
|
};
|
||||||
|
loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
stop() {
|
stop() {
|
||||||
clearInterval(this.handle);
|
clearTimeout(this.handle);
|
||||||
this.handle = undefined;
|
this.handle = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,9 @@ export default function Entities({entities}) {
|
||||||
}, [entities, ecs, mainEntity]);
|
}, [entities, ecs, mainEntity]);
|
||||||
const renderables = [];
|
const renderables = [];
|
||||||
for (const id in entities) {
|
for (const id in entities) {
|
||||||
|
if ('1' === id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const isHighlightedInteraction = id == willInteractWith;
|
const isHighlightedInteraction = id == willInteractWith;
|
||||||
renderables.push(
|
renderables.push(
|
||||||
<Entity
|
<Entity
|
||||||
|
|
|
@ -6,6 +6,21 @@ import {useDebug} from '@/context/debug.js';
|
||||||
import Emitter from './emitter.jsx';
|
import Emitter from './emitter.jsx';
|
||||||
import Sprite from './sprite.jsx';
|
import Sprite from './sprite.jsx';
|
||||||
|
|
||||||
|
function VisibleAabb({x0, y0, x1, y1}) {
|
||||||
|
const draw = useCallback((g) => {
|
||||||
|
g.clear();
|
||||||
|
g.lineStyle(0.5, 0xff00ff);
|
||||||
|
g.moveTo(-0.25, -0.25);
|
||||||
|
g.lineTo(x1 - x0, 0);
|
||||||
|
g.lineTo(x1 - x0, y1 - y0);
|
||||||
|
g.lineTo(0, y1 - y0);
|
||||||
|
g.lineTo(0, 0);
|
||||||
|
}, [x0, x1, y0, y1]);
|
||||||
|
return (
|
||||||
|
<Graphics draw={draw} x={x0} y={y0} />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function Crosshair({x, y}) {
|
function Crosshair({x, y}) {
|
||||||
const draw = useCallback((g) => {
|
const draw = useCallback((g) => {
|
||||||
g.clear();
|
g.clear();
|
||||||
|
@ -52,6 +67,14 @@ function Entity({entity, ...rest}) {
|
||||||
{debug && entity.Position && (
|
{debug && entity.Position && (
|
||||||
<Crosshair x={entity.Position.x} y={entity.Position.y} />
|
<Crosshair x={entity.Position.x} y={entity.Position.y} />
|
||||||
)}
|
)}
|
||||||
|
{debug && (
|
||||||
|
<VisibleAabb
|
||||||
|
x0={entity.VisibleAabb.x0}
|
||||||
|
x1={entity.VisibleAabb.x1}
|
||||||
|
y0={entity.VisibleAabb.y0}
|
||||||
|
y1={entity.VisibleAabb.y1}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,11 @@ export default function Sprite({entity, ...rest}) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let texture;
|
let texture;
|
||||||
if (asset.textures) {
|
if (asset.data.animations) {
|
||||||
const animation = asset.animations[entity.Sprite.animation]
|
texture = asset.animations[entity.Sprite.animation][entity.Sprite.frame];
|
||||||
texture = animation[entity.Sprite.frame];
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
texture = asset;
|
texture = asset.textures[''];
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<PixiSprite
|
<PixiSprite
|
||||||
|
|
25
package-lock.json
generated
25
package-lock.json
generated
|
@ -47,7 +47,6 @@
|
||||||
"eslint-plugin-jsx-a11y": "^6.7.1",
|
"eslint-plugin-jsx-a11y": "^6.7.1",
|
||||||
"eslint-plugin-react": "^7.33.2",
|
"eslint-plugin-react": "^7.33.2",
|
||||||
"eslint-plugin-react-hooks": "^4.6.0",
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
"image-size": "^1.1.1",
|
|
||||||
"storybook": "^8.1.6",
|
"storybook": "^8.1.6",
|
||||||
"vite": "^5.1.0",
|
"vite": "^5.1.0",
|
||||||
"vitest": "^1.6.0"
|
"vitest": "^1.6.0"
|
||||||
|
@ -11305,21 +11304,6 @@
|
||||||
"node": ">= 4"
|
"node": ">= 4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/image-size": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"queue": "6.0.2"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"image-size": "bin/image-size.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=16.x"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/import-fresh": {
|
"node_modules/import-fresh": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||||
|
@ -15161,15 +15145,6 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/queue": {
|
|
||||||
"version": "6.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz",
|
|
||||||
"integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"inherits": "~2.0.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/queue-microtask": {
|
"node_modules/queue-microtask": {
|
||||||
"version": "1.2.3",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||||
|
|
|
@ -54,7 +54,6 @@
|
||||||
"eslint-plugin-jsx-a11y": "^6.7.1",
|
"eslint-plugin-jsx-a11y": "^6.7.1",
|
||||||
"eslint-plugin-react": "^7.33.2",
|
"eslint-plugin-react": "^7.33.2",
|
||||||
"eslint-plugin-react-hooks": "^4.6.0",
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
"image-size": "^1.1.1",
|
|
||||||
"storybook": "^8.1.6",
|
"storybook": "^8.1.6",
|
||||||
"vite": "^5.1.0",
|
"vite": "^5.1.0",
|
||||||
"vitest": "^1.6.0"
|
"vitest": "^1.6.0"
|
||||||
|
|
1
public/assets/shit-shack/shit-shack.json
Normal file
1
public/assets/shit-shack/shit-shack.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"frames":{"":{"frame":{"x":0,"y":0,"w":110,"h":102},"spriteSourceSize":{"x":0,"y":0,"w":110,"h":102},"sourceSize":{"w":110,"h":102}}},"meta":{"format":"RGBA8888","image":"./shit-shack.png","scale":1,"size":{"w":110,"h":102}}}
|
Loading…
Reference in New Issue
Block a user