Compare commits

...

4 Commits

Author SHA1 Message Date
cha0s
547cd5a9b9 fix: relax 2024-06-13 23:51:06 -05:00
cha0s
162a1f9b8a ui: hotbar 2024-06-13 22:01:07 -05:00
cha0s
c1758ef3d6 refactor: tidy 2024-06-13 21:10:34 -05:00
cha0s
e9da3871a4 chore: deprecation 2024-06-13 21:00:30 -05:00
7 changed files with 68 additions and 48 deletions

View File

@ -22,7 +22,7 @@ test('visibility-based updates', async () => {
// Tick and get update. Should be a partial update. // Tick and get update. Should be a partial update.
engine.tick(1); engine.tick(1);
expect(engine.updateFor(undefined)) expect(engine.updateFor(undefined))
.to.deep.equal({ .to.deep.include({
2: { 2: {
Position: {x: (RESOLUTION.x * 1.5) + 32 - 1}, Position: {x: (RESOLUTION.x * 1.5) + 32 - 1},
VisibleAabb: { VisibleAabb: {
@ -34,10 +34,10 @@ test('visibility-based updates', async () => {
// Tick and get update. Should remove the entity. // Tick and get update. Should remove the entity.
engine.tick(1); engine.tick(1);
expect(engine.updateFor(undefined)) expect(engine.updateFor(undefined))
.to.deep.equal({2: false}); .to.deep.include({2: false});
// Aim back toward visible area and tick. Should be a full update for that entity. // Aim back toward visible area and tick. Should be a full update for that entity.
entity.Momentum.x = -1; entity.Momentum.x = -1;
engine.tick(1); engine.tick(1);
expect(engine.updateFor(undefined)) expect(engine.updateFor(undefined))
.to.deep.equal({2: ecs.get(2).toJSON()}); .to.deep.include({2: ecs.get(2).toJSON()});
}); });

View File

@ -1,4 +1,6 @@
.dom { .dom {
display: flex;
flex-direction: column;
height: calc(100% / var(--scale)); height: calc(100% / var(--scale));
position: absolute; position: absolute;
top: 0; top: 0;

View File

@ -6,7 +6,7 @@ import Slot from './slot.jsx';
*/ */
export default function Hotbar({active, onActivate, slots}) { export default function Hotbar({active, onActivate, slots}) {
const Slots = slots.map((slot, i) => ( const Slots = slots.map((slot, i) => (
<div <button
className={ className={
[styles.slotWrapper, active === i && styles.active] [styles.slotWrapper, active === i && styles.active]
.filter(Boolean).join(' ') .filter(Boolean).join(' ')
@ -15,7 +15,7 @@ export default function Hotbar({active, onActivate, slots}) {
key={i} key={i}
> >
<Slot {...slot} /> <Slot {...slot} />
</div> </button>
)); ));
return ( return (
<div <div

View File

@ -1,22 +1,32 @@
.hotbar { .hotbar {
align-self: center;
--border: calc(var(--unit) * 3px); --border: calc(var(--unit) * 3px);
background-color: rgba(0, 0, 0, 0.2); background-color: rgba(0, 0, 0, 0.2);
border: var(--border) solid #444444; border: var(--border) solid #444444;
box-sizing: border-box; box-sizing: border-box;
display: inline-block; display: inline-block;
left: calc(var(--unit) * 225px);
line-height: 0; line-height: 0;
position: absolute; position: absolute;
top: calc(var(--unit) * 25px); top: calc(var(--unit) * 25px);
} }
.slotWrapper { .slotWrapper {
background-color: transparent;
border: var(--border) solid #999999; border: var(--border) solid #999999;
box-sizing: border-box; box-sizing: border-box;
display: inline-block; display: inline-block;
line-height: 0; line-height: 0;
padding: 0;
&.active + .slotWrapper {
border-left: none;
}
&:not(:last-child) {
border-right: none;
}
&.active { &.active {
border-right: var(--border) solid #999999;
border-color: yellow; border-color: yellow;
} }

View File

@ -2,7 +2,7 @@ import {
Stage as PixiStage, Stage as PixiStage,
} from '@pixi/react'; } from '@pixi/react';
import {SCALE_MODES} from '@pixi/constants'; import {SCALE_MODES} from '@pixi/constants';
import {settings} from '@pixi/settings'; import {BaseTexture} from '@pixi/core';
import {RESOLUTION} from '@/constants.js'; import {RESOLUTION} from '@/constants.js';
import ClientContext from '@/context/client.js'; import ClientContext from '@/context/client.js';
@ -10,7 +10,7 @@ import ClientContext from '@/context/client.js';
import Ecs from './ecs.jsx'; import Ecs from './ecs.jsx';
import styles from './pixi.module.css'; import styles from './pixi.module.css';
settings.SCALE_MODE = SCALE_MODES.NEAREST; BaseTexture.defaultOptions.scaleMode = SCALE_MODES.NEAREST;
const ContextBridge = ({ children, Context, render }) => { const ContextBridge = ({ children, Context, render }) => {
return ( return (

View File

@ -58,7 +58,7 @@ export default function Ui({disconnected}) {
</style> </style>
<Pixi /> <Pixi />
<Dom> <Dom>
<HotBar active={0} slots={Array(10).fill(0).map(() => {})} /> <HotBar active={1} slots={Array(10).fill(0).map(() => {})} />
{showDisconnected && ( {showDisconnected && (
<Disconnected /> <Disconnected />
)} )}

View File

@ -19,45 +19,53 @@ function onUpgrade(request, socket, head) {
} }
} }
let engine;
let onConnect;
function createOnConnect(engine) {
onConnect = async (ws) => {
ws.on('close', () => {
engine.disconnectPlayer(ws);
})
ws.on('message', (packed) => {
engine.server.accept(ws, new DataView(packed.buffer, packed.byteOffset, packed.length));
});
await engine.connectPlayer(ws);
};
wss.on('connection', onConnect);
}
class SocketServer extends Server {
transmit(ws, packed) { ws.send(packed); }
}
async function createEngine(Engine) {
engine = new Engine(SocketServer);
await engine.load();
engine.start();
return engine;
}
async function remakeServer(Engine) {
if (onConnect) {
wss.off('connection', onConnect);
}
if (engine) {
for (const [connection] of engine.connectedPlayers) {
connection.close();
}
}
createOnConnect(await createEngine(Engine));
}
await remakeServer(Engine);
if (import.meta.hot) {
import.meta.hot.accept('./engine/engine.js', async ({default: Engine}) => {
await remakeServer(Engine);
});
}
export default async function listen(server) { export default async function listen(server) {
server.on('upgrade', onUpgrade); server.on('upgrade', onUpgrade);
class SocketServer extends Server {
transmit(ws, packed) { ws.send(packed); }
}
let onConnect;
function makeOnConnect(engine) {
return async (ws) => {
ws.on('close', () => {
engine.disconnectPlayer(ws);
})
ws.on('message', (packed) => {
engine.server.accept(ws, new DataView(packed.buffer, packed.byteOffset, packed.length));
});
await engine.connectPlayer(ws);
};
}
let engine;
async function makeEngine(Engine) {
const engine = new Engine(SocketServer);
await engine.load();
engine.start();
return engine;
}
engine = await makeEngine(Engine);
wss.on('connection', onConnect = makeOnConnect(engine));
if (import.meta.hot) {
import.meta.hot.accept('./engine/engine.js', async ({default: Engine}) => {
wss.off('connection', onConnect);
for (const [connection] of engine.connectedPlayers) {
connection.close();
}
engine = await makeEngine(Engine);
wss.on('connection', onConnect = makeOnConnect(engine));
});
}
} }