refactor: input
This commit is contained in:
parent
b100b523f5
commit
28e5e9f56f
|
@ -1,6 +1,6 @@
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
|
|
||||||
import {ActionRegistry, InputNormalizer} from '@avocado/input';
|
import {InputNormalizer} from '@avocado/input';
|
||||||
import {setSelfEntity, useSelfEntity} from '@humus/core';
|
import {setSelfEntity, useSelfEntity} from '@humus/core';
|
||||||
import {useDispatch} from '@latus/redux';
|
import {useDispatch} from '@latus/redux';
|
||||||
import {useSocket} from '@latus/socket';
|
import {useSocket} from '@latus/socket';
|
||||||
|
@ -26,23 +26,18 @@ const Play = () => {
|
||||||
};
|
};
|
||||||
}, [dispatch, socket, uuid]);
|
}, [dispatch, socket, uuid]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!ref.current) {
|
if (!ref.current || !selfEntity) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
const inputNormalizer = new InputNormalizer();
|
const inputNormalizer = new InputNormalizer();
|
||||||
inputNormalizer.listen(window.document.body);
|
inputNormalizer.listen(window.document.body);
|
||||||
const actionRegistry = new ActionRegistry();
|
selfEntity.listenForInput(inputNormalizer);
|
||||||
actionRegistry.setActionTransformerFor('UseItem', (type) => (
|
selfEntity.actionRegistry.setTransformerFor('UseItem', (type) => (
|
||||||
selfEntity && 'keyDown' === type ? selfEntity.activeSlotIndex : -1
|
'keyDown' === type ? selfEntity.activeSlotIndex : -1
|
||||||
));
|
));
|
||||||
actionRegistry.listen(inputNormalizer);
|
|
||||||
const inputHandle = setInterval(() => {
|
const inputHandle = setInterval(() => {
|
||||||
const inputStream = actionRegistry.drain();
|
const inputStream = selfEntity.drainInput();
|
||||||
if (inputStream.length > 0) {
|
if (inputStream.length > 0) {
|
||||||
// Inject input.
|
|
||||||
if (selfEntity) {
|
|
||||||
selfEntity.inputStream = inputStream;
|
|
||||||
}
|
|
||||||
const sending = inputStream.filter(({action}) => {
|
const sending = inputStream.filter(({action}) => {
|
||||||
if (action.match(/^HotbarSlot(\d)/)) {
|
if (action.match(/^HotbarSlot(\d)/)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -2,6 +2,7 @@ import {
|
||||||
TickingPromise,
|
TickingPromise,
|
||||||
} from '@avocado/core';
|
} from '@avocado/core';
|
||||||
import {Vector} from '@avocado/math';
|
import {Vector} from '@avocado/math';
|
||||||
|
import {ActionRegistry} from '@avocado/input';
|
||||||
import {Trait} from '@avocado/traits';
|
import {Trait} from '@avocado/traits';
|
||||||
import {
|
import {
|
||||||
compose,
|
compose,
|
||||||
|
@ -18,15 +19,85 @@ const decorate = compose(
|
||||||
// Input handling.
|
// Input handling.
|
||||||
export default () => class Controllable extends decorate(Trait) {
|
export default () => class Controllable extends decorate(Trait) {
|
||||||
|
|
||||||
|
#actionRegistry;
|
||||||
|
|
||||||
#itemPromise;
|
#itemPromise;
|
||||||
|
|
||||||
#itemUseRequest = -1;
|
#itemUseRequest = -1;
|
||||||
|
|
||||||
|
#queued = [];
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.on('controllableMovementChanged', this.updateAnimation, this);
|
this.on('controllableMovementChanged', this.updateAnimation, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get actionRegistry() {
|
||||||
|
return this.#actionRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
|
static defaultParams() {
|
||||||
|
return {
|
||||||
|
actions: {
|
||||||
|
HotbarSlot0: [
|
||||||
|
{type: 'key', index: '1'},
|
||||||
|
],
|
||||||
|
HotbarSlot1: [
|
||||||
|
{type: 'key', index: '2'},
|
||||||
|
],
|
||||||
|
HotbarSlot2: [
|
||||||
|
{type: 'key', index: '3'},
|
||||||
|
],
|
||||||
|
HotbarSlot3: [
|
||||||
|
{type: 'key', index: '4'},
|
||||||
|
],
|
||||||
|
HotbarSlot4: [
|
||||||
|
{type: 'key', index: '5'},
|
||||||
|
],
|
||||||
|
HotbarSlot5: [
|
||||||
|
{type: 'key', index: '6'},
|
||||||
|
],
|
||||||
|
HotbarSlot6: [
|
||||||
|
{type: 'key', index: '7'},
|
||||||
|
],
|
||||||
|
HotbarSlot7: [
|
||||||
|
{type: 'key', index: '8'},
|
||||||
|
],
|
||||||
|
HotbarSlot8: [
|
||||||
|
{type: 'key', index: '9'},
|
||||||
|
],
|
||||||
|
HotbarSlot9: [
|
||||||
|
{type: 'key', index: '0'},
|
||||||
|
],
|
||||||
|
HotbarSlotNext: [
|
||||||
|
{type: 'key', index: 'WheelDown'},
|
||||||
|
],
|
||||||
|
HotbarSlotPrevious: [
|
||||||
|
{type: 'key', index: 'WheelUp'},
|
||||||
|
],
|
||||||
|
MoveUp: [
|
||||||
|
{type: 'key', index: 'w'},
|
||||||
|
],
|
||||||
|
MoveLeft: [
|
||||||
|
{type: 'key', index: 'a'},
|
||||||
|
],
|
||||||
|
MoveDown: [
|
||||||
|
{type: 'key', index: 's'},
|
||||||
|
],
|
||||||
|
MoveRight: [
|
||||||
|
{type: 'key', index: 'd'},
|
||||||
|
],
|
||||||
|
UseItem: [
|
||||||
|
{type: 'key', index: 'ArrowLeft'},
|
||||||
|
{type: 'button', index: 0},
|
||||||
|
],
|
||||||
|
Interact: [
|
||||||
|
{type: 'key', index: 'e'},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static dependencies() {
|
static dependencies() {
|
||||||
return [
|
return [
|
||||||
'Animated',
|
'Animated',
|
||||||
|
@ -36,6 +107,10 @@ export default () => class Controllable extends decorate(Trait) {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.#actionRegistry.stopListening();
|
||||||
|
}
|
||||||
|
|
||||||
set inputStream(inputStream) {
|
set inputStream(inputStream) {
|
||||||
for (let i = 0; i < inputStream.length; i++) {
|
for (let i = 0; i < inputStream.length; i++) {
|
||||||
const {action, value} = inputStream[i];
|
const {action, value} = inputStream[i];
|
||||||
|
@ -76,9 +151,31 @@ export default () => class Controllable extends decorate(Trait) {
|
||||||
async load(json) {
|
async load(json) {
|
||||||
await super.load(json);
|
await super.load(json);
|
||||||
this.entity.on('isMobileChanged', this.updateAnimation, this);
|
this.entity.on('isMobileChanged', this.updateAnimation, this);
|
||||||
|
this.#actionRegistry = new ActionRegistry(this.params.actions);
|
||||||
|
}
|
||||||
|
|
||||||
|
methods() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
drainInput: () => {
|
||||||
|
const drained = this.#queued;
|
||||||
|
this.#queued = [];
|
||||||
|
return drained;
|
||||||
|
},
|
||||||
|
|
||||||
|
listenForInput: (inputNormalizer) => {
|
||||||
|
this.#actionRegistry.listen(inputNormalizer);
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
tick(elapsed) {
|
tick(elapsed) {
|
||||||
|
if ('client' === process.env.SIDE) {
|
||||||
|
const drained = this.#actionRegistry.drain();
|
||||||
|
this.inputStream = drained;
|
||||||
|
this.#queued.push(...drained);
|
||||||
|
}
|
||||||
if (-1 !== this.#itemUseRequest && !this.#itemPromise) {
|
if (-1 !== this.#itemUseRequest && !this.#itemPromise) {
|
||||||
this.#itemPromise = this.entity.useItemInSlot(this.#itemUseRequest);
|
this.#itemPromise = this.entity.useItemInSlot(this.#itemUseRequest);
|
||||||
Promise.resolve(this.#itemPromise).then(() => {
|
Promise.resolve(this.#itemPromise).then(() => {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user