flow
This commit is contained in:
parent
ec0487d49c
commit
156e7c7f47
|
@ -18,12 +18,20 @@ module.exports = {
|
|||
const {files = [], name} = neutrino.options.packageJson;
|
||||
files
|
||||
.filter((file) => {
|
||||
const {source} = neutrino.options;
|
||||
try {
|
||||
require.resolve(`${neutrino.options.source}/${file}`);
|
||||
require.resolve(`${source}/${file}`);
|
||||
return true;
|
||||
}
|
||||
catch (error) {
|
||||
return false;
|
||||
const ext = extname(file);
|
||||
try {
|
||||
require.resolve(`${source}/${dirname(file)}/${basename(file, ext)}/index${ext}`);
|
||||
return true;
|
||||
}
|
||||
catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
})
|
||||
.forEach((file) => {
|
||||
|
|
|
@ -20,9 +20,9 @@
|
|||
"index.js.map"
|
||||
],
|
||||
"dependencies": {
|
||||
"@avocado/core": "^2.0.0",
|
||||
"@avocado/entity": "^2.0.0",
|
||||
"@latus/core": "^2.0.0",
|
||||
"@avocado/core": "2.0.0",
|
||||
"@avocado/traits": "^2.0.0",
|
||||
"@latus/core": "2.0.0",
|
||||
"debug": "4.3.1",
|
||||
"deepmerge": "^4.2.2",
|
||||
"lodash.mapvalues": "^4.6.0"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {StateProperty, Trait} from '@avocado/entity';
|
||||
import {StateProperty, Trait} from '@avocado/traits';
|
||||
import {compose} from '@latus/core';
|
||||
import mapValues from 'lodash.mapvalues';
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,14 +20,15 @@
|
|||
"index.js.map"
|
||||
],
|
||||
"dependencies": {
|
||||
"@avocado/behavior": "^2.0.0",
|
||||
"@avocado/behavior": "2.0.0",
|
||||
"@avocado/core": "2.0.0",
|
||||
"@avocado/math": "2.0.0",
|
||||
"@avocado/resource": "2.0.0",
|
||||
"@avocado/s13n": "^2.0.0",
|
||||
"@avocado/timing": "^2.0.0",
|
||||
"@latus/core": "^2.0.0",
|
||||
"@latus/socket": "^2.0.0",
|
||||
"@avocado/s13n": "2.0.0",
|
||||
"@avocado/timing": "2.0.0",
|
||||
"@avocado/traits": "^2.0.0",
|
||||
"@latus/core": "2.0.0",
|
||||
"@latus/socket": "2.0.0",
|
||||
"debug": "4.3.1",
|
||||
"deepmerge": "^4.2.2",
|
||||
"lodash.without": "^4.4.0"
|
||||
|
|
|
@ -3,7 +3,7 @@ import merge from 'deepmerge';
|
|||
import without from 'lodash.without';
|
||||
|
||||
import {fastApply} from '@avocado/core';
|
||||
import {Synchronized} from '@avocado/s13n';
|
||||
import {normalize, Synchronized} from '@avocado/s13n';
|
||||
import Resource from '@avocado/resource';
|
||||
import {
|
||||
compose,
|
||||
|
@ -25,7 +25,6 @@ const decorate = compose(
|
|||
);
|
||||
|
||||
let numericUid = AVOCADO_SERVER ? 1 : 1000000000;
|
||||
|
||||
export default (latus) => class Entity extends decorate(Resource) {
|
||||
|
||||
constructor(json, jsonext) {
|
||||
|
@ -85,7 +84,7 @@ export default (latus) => class Entity extends decorate(Resource) {
|
|||
debug(`Tried to add trait "${type}" when it already exists!`);
|
||||
return;
|
||||
}
|
||||
const {type: Trait} = traitFromType(latus);
|
||||
const {[type]: Trait} = traitFromType(latus);
|
||||
if (!Trait) {
|
||||
debug(`Tried to add trait "${type}" which isn't registered!`);
|
||||
return;
|
||||
|
@ -222,7 +221,7 @@ export default (latus) => class Entity extends decorate(Resource) {
|
|||
const traits = Object.entries(json.traits);
|
||||
for (let i = 0; i < traits.length; i++) {
|
||||
const [type, trait] = traits[i];
|
||||
const {type: Trait} = traitFromType(latus);
|
||||
const {[type]: Trait} = traitFromType(latus);
|
||||
if (Trait) {
|
||||
pristine.traits[type] = merge(Trait.defaultJSON(), trait);
|
||||
}
|
||||
|
@ -243,17 +242,12 @@ export default (latus) => class Entity extends decorate(Resource) {
|
|||
const traits = Object.entries(this._traits);
|
||||
for (let i = 0; i < traits.length; i++) {
|
||||
const [type, trait] = traits[i];
|
||||
let traitPackets = trait.packets(informed);
|
||||
if (traitPackets) {
|
||||
if (!Array.isArray(traitPackets)) {
|
||||
traitPackets = [traitPackets];
|
||||
}
|
||||
if (traitPackets.length > 0) {
|
||||
updates.push({
|
||||
type,
|
||||
packets: traitPackets,
|
||||
});
|
||||
}
|
||||
const traitPackets = normalize(latus, trait.packets(informed));
|
||||
if (traitPackets.length > 0) {
|
||||
updates.push({
|
||||
type,
|
||||
packets: traitPackets,
|
||||
});
|
||||
}
|
||||
}
|
||||
if (updates.length > 0) {
|
||||
|
@ -293,7 +287,7 @@ export default (latus) => class Entity extends decorate(Resource) {
|
|||
const implementation = this._hooks[hook].find(({type: hookType}) => hookType === type);
|
||||
this._hooks[hook].splice(this._hooks[hook].indexOf(implementation), 1);
|
||||
}
|
||||
const {type: Trait} = traitFromType(latus);
|
||||
const {[type]: Trait} = traitFromType(latus);
|
||||
const properties = enumerateTraitAccessorKeys(Trait.prototype);
|
||||
for (let i = 0; i < properties.length; ++i) {
|
||||
const property = properties[i];
|
||||
|
|
|
@ -1,24 +1,13 @@
|
|||
import {gather} from '@latus/core';
|
||||
|
||||
import Entity from './entity';
|
||||
import Packets from './packets';
|
||||
import Traits from './traits';
|
||||
|
||||
export default {
|
||||
hooks: {
|
||||
'@avocado/entity/traits': Traits,
|
||||
'@avocado/traits': Traits,
|
||||
'@avocado/s13n/synchronized': (latus) => ({
|
||||
Entity: Entity(latus),
|
||||
}),
|
||||
'@latus/core/starting': (latus) => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
latus.config['%traits'] = gather(
|
||||
latus,
|
||||
'@avocado/entity/traits',
|
||||
'id',
|
||||
'type',
|
||||
);
|
||||
},
|
||||
'@latus/socket/packets': Packets,
|
||||
},
|
||||
};
|
||||
|
|
2
packages/entity/src/list/index.js
Normal file
2
packages/entity/src/list/index.js
Normal file
|
@ -0,0 +1,2 @@
|
|||
export {EntityList} from './list';
|
||||
export {EntityListView} from './view';
|
268
packages/entity/src/list/list.js
Normal file
268
packages/entity/src/list/list.js
Normal file
|
@ -0,0 +1,268 @@
|
|||
import {Class, compose, EventEmitter} from '@latus/core';
|
||||
import {QuadTree, Rectangle} from '@avocado/math';
|
||||
import {
|
||||
normalize,
|
||||
synchronized,
|
||||
SynchronizedCreatePacket,
|
||||
SynchronizedDestroyPacket,
|
||||
} from '@avocado/s13n';
|
||||
|
||||
const decorate = compose(
|
||||
EventEmitter,
|
||||
);
|
||||
|
||||
export default (latus) => class EntityList extends decorate(Class) {
|
||||
|
||||
constructor(entities = []) {
|
||||
super();
|
||||
this._afterDestructionTickers = [];
|
||||
this._entities = {};
|
||||
this._entityTickers = [];
|
||||
this._flatEntities = [];
|
||||
this._informedEntities = new Map();
|
||||
this._quadTree = new QuadTree();
|
||||
const {fromName: {Entity}} = synchronized(latus);
|
||||
const entities = await Promise.all(entities.map(Entity.load));
|
||||
for (let i = 0; i < entities.length; i++) {
|
||||
const entityJSON = entities[i];
|
||||
if (entityJSON.uri) {
|
||||
Entity.read(entityJSON.uri).then((readJSON) => {
|
||||
this.addEntity(new Entity(readJSON, entityJSON));
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.addEntity(new Entity(json[i]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async acceptPacket(packet) {
|
||||
if ('EntityListUpdateEntityPacket' === packet.constructor.name) {
|
||||
for (let i = 0; i < packet.data.length; i++) {
|
||||
const {uuid, packets} = packet.data[i];
|
||||
for (let j = 0; j < packets.length; j++) {
|
||||
if (this._entities[uuid]) {
|
||||
this._entities[uuid].acceptPacket(packets[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (packet instanceof SynchronizedCreatePacket) {
|
||||
const {fromName: {Entity}} = synchronized(latus);
|
||||
this.addEntity(await Entity.load(packet.data.spec));
|
||||
}
|
||||
if (packet instanceof SynchronizedDestroyPacket) {
|
||||
const uuid = packet.data.synchronized.id;
|
||||
if (this._entities[uuid]) {
|
||||
this._entities[uuid].destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addEntity(entity) {
|
||||
const uuid = entity.instanceUuid;
|
||||
// Already exists?
|
||||
if (this._entities[uuid]) {
|
||||
return;
|
||||
}
|
||||
this._entities[uuid] = entity;
|
||||
this._flatEntities.push(entity);
|
||||
this._entityTickers.push(entity.tick);
|
||||
if (AVOCADO_SERVER) {
|
||||
this._informedEntities.set(entity, []);
|
||||
}
|
||||
entity.hydrate();
|
||||
entity.attachToList(this);
|
||||
entity.once('destroy', () => {
|
||||
this.removeEntity(entity);
|
||||
// In the process of destroying, allow entities to specify tickers that
|
||||
// must live on past destruction.
|
||||
const tickers = entity.invokeHookFlat('afterDestructionTickers');
|
||||
for (let i = 0; i < tickers.length; i++) {
|
||||
const ticker = tickers[i];
|
||||
this._afterDestructionTickers.push(ticker);
|
||||
}
|
||||
});
|
||||
this.emit('entityAdded', entity);
|
||||
}
|
||||
|
||||
cleanPackets() {
|
||||
for (let i = 0; i < this._flatEntities.length; i++) {
|
||||
this._flatEntities[i].cleanPackets();
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
for (let i = 0; i < this._flatEntities.length; i++) {
|
||||
this._flatEntities[i].destroy();
|
||||
}
|
||||
}
|
||||
|
||||
// static async extendJson(json) {
|
||||
// const extended = await super.extendJson(json);
|
||||
// if (extended)
|
||||
// extended.sound = new Howl(json);
|
||||
// await new Promise((resolve) => {
|
||||
// extended.sound.once('load', resolve);
|
||||
// });
|
||||
// return extended;
|
||||
// }
|
||||
|
||||
findEntity(uuid) {
|
||||
return uuid in this._entities
|
||||
? this._entities[uuid]
|
||||
: undefined;
|
||||
}
|
||||
|
||||
fromJSON(json) {
|
||||
for (let i = 0; i < json.length; i++) {
|
||||
const entityJSON = json[i];
|
||||
if (entityJSON.uri) {
|
||||
Entity.read(entityJSON.uri).then((readJSON) => {
|
||||
this.addEntity(new Entity(readJSON, entityJSON));
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.addEntity(new Entity(json[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
packets(informed) {
|
||||
const packets = [];
|
||||
// Visible entities.
|
||||
const {areaToInform} = informed;
|
||||
const previousVisibleEntities = this._informedEntities.get(informed);
|
||||
const visibleEntities = this.visibleEntities(areaToInform);
|
||||
const updates = [];
|
||||
for (let i = 0; i < visibleEntities.length; i++) {
|
||||
const entity = visibleEntities[i];
|
||||
// Newly visible entity.
|
||||
const index = previousVisibleEntities.indexOf(entity);
|
||||
if (-1 === index) {
|
||||
packets.push(entity.createPacket(informed));
|
||||
}
|
||||
// Still visible entity.
|
||||
else {
|
||||
const entityPackets = normalize(entity.packets(informed));
|
||||
if (entityPackets.length > 0) {
|
||||
updates.push({
|
||||
uuid: entity.instanceUuid,
|
||||
packets: entityPackets,
|
||||
});
|
||||
}
|
||||
previousVisibleEntities.splice(index, 1);
|
||||
}
|
||||
}
|
||||
// Send updates.
|
||||
this._informedEntities.set(informed, visibleEntities);
|
||||
if (updates.length > 0) {
|
||||
packets.push([
|
||||
'EntityListUpdateEntityPacket',
|
||||
updates,
|
||||
]);
|
||||
}
|
||||
// Send destroys.
|
||||
for (let i = 0; i < previousVisibleEntities.length; i++) {
|
||||
const entity = previousVisibleEntities[i];
|
||||
// Newly removed entity.
|
||||
if (-1 === visibleEntities.indexOf(entity)) {
|
||||
packets.push(entity.destroyPacket(informed));
|
||||
}
|
||||
}
|
||||
return packets;
|
||||
}
|
||||
|
||||
get quadTree() {
|
||||
return this._quadTree;
|
||||
}
|
||||
|
||||
removeEntity(entity) {
|
||||
const uuid = entity.instanceUuid;
|
||||
if (!(uuid in this._entities)) {
|
||||
return;
|
||||
}
|
||||
if (AVOCADO_SERVER) {
|
||||
this._informedEntities.delete(entity);
|
||||
}
|
||||
entity.detachFromList();
|
||||
delete this._entities[uuid];
|
||||
this._flatEntities.splice(this._flatEntities.indexOf(entity), 1);
|
||||
this._entityTickers.splice(this._entityTickers.indexOf(entity.tick), 1);
|
||||
this.emit('entityRemoved', entity);
|
||||
}
|
||||
|
||||
tick(elapsed) {
|
||||
// Run after destruction tickers.
|
||||
if (this._afterDestructionTickers.length > 0) {
|
||||
this.tickAfterDestructionTickers(elapsed);
|
||||
}
|
||||
// Run normal tickers.
|
||||
this.tickEntities(elapsed);
|
||||
}
|
||||
|
||||
tickAfterDestructionTickers(elapsed) {
|
||||
const finishedTickers = [];
|
||||
for (let i = 0; i < this._afterDestructionTickers.length; ++i) {
|
||||
const ticker = this._afterDestructionTickers[i];
|
||||
if (ticker(elapsed)) {
|
||||
finishedTickers.push(ticker);
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < finishedTickers.length; ++i) {
|
||||
const ticker = finishedTickers[i];
|
||||
const index = this._afterDestructionTickers.indexOf(ticker);
|
||||
this._afterDestructionTickers.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
tickEntities(elapsed) {
|
||||
for (let i = 0; i < this._entityTickers.length; i++) {
|
||||
this._entityTickers[i](elapsed);
|
||||
}
|
||||
}
|
||||
|
||||
toNetwork(informed) {
|
||||
const {areaToInform} = informed;
|
||||
const visibleEntities = this.visibleEntities(areaToInform);
|
||||
// Mark as notified.
|
||||
this._informedEntities.set(informed, visibleEntities);
|
||||
return visibleEntities.map((entity) => entity.toNetwork(informed));
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const json = [];
|
||||
for (let i = 0; i < this._flatEntities.length; i++) {
|
||||
const entity = this._flatEntities[i];
|
||||
json.push(entity.mergeDiff(entity.toJSON()));
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
visibleEntities(query) {
|
||||
const entities = [];
|
||||
const entitiesChecked = [];
|
||||
const quadTree = this._quadTree;
|
||||
const nodes = quadTree.search(query);
|
||||
// Check all nodes.
|
||||
for (let i = 0; i < nodes.length; ++i) {
|
||||
const node = nodes[i];
|
||||
const entity = node.data[2];
|
||||
const aabb = node.data[3];
|
||||
if (-1 === entitiesChecked.indexOf(entity)) {
|
||||
entitiesChecked.push(entity);
|
||||
// Make sure the AABB is actually in the query due to expansion.
|
||||
if (entity.isVisible && Rectangle.intersects(query, aabb)) {
|
||||
entities.push(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
|
||||
visibleEntitiesWithUri(query, uri) {
|
||||
return this.visibleEntities(query).filter((entity) => entity.uri === uri);
|
||||
}
|
||||
|
||||
};
|
35
packages/entity/src/list/view.js
Normal file
35
packages/entity/src/list/view.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
import {Container, Sprite} from '@avocado/graphics';
|
||||
|
||||
export class EntityListView extends Container {
|
||||
|
||||
constructor(entityList) {
|
||||
super();
|
||||
this.entityList = entityList;
|
||||
entityList.on('entityAdded', this.onListEntityAdded, this);
|
||||
entityList.on('entityRemoved', this.onListEntityRemoved, this);
|
||||
for (const entity of entityList) {
|
||||
this.onListEntityAdded(entity);
|
||||
}
|
||||
}
|
||||
|
||||
onListEntityAdded(entity) {
|
||||
entity.hydrate();
|
||||
if (entity.is('visible')) {
|
||||
this.addChild(entity.container);
|
||||
}
|
||||
}
|
||||
|
||||
onListEntityRemoved(entity) {
|
||||
if (entity.is('visible')) {
|
||||
this.removeChild(entity.container);
|
||||
}
|
||||
}
|
||||
|
||||
renderTick(elapsed) {
|
||||
for (const entity of this.entityList) {
|
||||
entity.renderTick(elapsed);
|
||||
}
|
||||
super.renderTick(elapsed);
|
||||
}
|
||||
|
||||
}
|
3
packages/entity/src/packets/died.js
Normal file
3
packages/entity/src/packets/died.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
import {Packet} from '@latus/socket';
|
||||
|
||||
export default class DiedPacket extends Packet {}
|
35
packages/entity/src/packets/entity-list-update-entity.js
Normal file
35
packages/entity/src/packets/entity-list-update-entity.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
import {packetFromName, Packet} from '@latus/socket';
|
||||
|
||||
export default (latus) => class EntityListUpdateEntityPacket extends Packet {
|
||||
|
||||
static pack(packet) {
|
||||
const {BundlePacket} = packetFromName(latus);
|
||||
const data = packet.data[1];
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
data[i].packets = BundlePacket.packPacket(
|
||||
new BundlePacket(data[i].packets),
|
||||
);
|
||||
}
|
||||
return super.pack(packet);
|
||||
}
|
||||
|
||||
static get data() {
|
||||
return [
|
||||
{
|
||||
uuid: 'uint32',
|
||||
packets: 'buffer',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
static unpack(packet) {
|
||||
const {BundlePacket} = packetFromName(latus);
|
||||
const unpacked = super.unpack(packet);
|
||||
const {data} = unpacked;
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
data[i].packets = BundlePacket.unpack(data[i].packets).data;
|
||||
}
|
||||
return unpacked;
|
||||
}
|
||||
|
||||
};
|
|
@ -1,5 +1,15 @@
|
|||
import Died from './died';
|
||||
import EntityListUpdateEntity from './entity-list-update-entity';
|
||||
import EntityUpdateTrait from './entity-update-trait';
|
||||
import TraitUpdateAlive from './trait-update-alive';
|
||||
import TraitUpdateDirectionalDirection from './trait-update-directional-direction';
|
||||
import TraitUpdatePositionedPosition from './trait-update-positioned-position';
|
||||
|
||||
export default (latus) => ({
|
||||
Died,
|
||||
EntityListUpdateEntity: EntityListUpdateEntity(latus),
|
||||
EntityUpdateTrait: EntityUpdateTrait(latus),
|
||||
TraitUpdateAlive,
|
||||
TraitUpdateDirectionalDirection,
|
||||
TraitUpdatePositionedPosition,
|
||||
});
|
||||
|
|
12
packages/entity/src/packets/trait-update-alive.js
Normal file
12
packages/entity/src/packets/trait-update-alive.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import {Packet} from '@latus/socket';
|
||||
|
||||
export default class TraitUpdateAlivePacket extends Packet {
|
||||
|
||||
static get data() {
|
||||
return {
|
||||
life: 'uint16',
|
||||
maxLife: 'uint16',
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import {Packet} from '@latus/socket';
|
||||
|
||||
export default class TraitUpdateDirectionalDirectionPacket extends Packet {
|
||||
|
||||
static get data() {
|
||||
return 'uint8';
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
import {Vector} from '@avocado/math';
|
||||
import {Packet} from '@latus/socket';
|
||||
|
||||
export default class TraitUpdatePositionedPositionPacket extends Packet {
|
||||
|
||||
static pack(packet) {
|
||||
const data = packet.data[1];
|
||||
data.position = Vector.packToUint32(data.position);
|
||||
return super.pack(packet);
|
||||
}
|
||||
|
||||
static get schema() {
|
||||
return {
|
||||
...super.schema,
|
||||
data: {
|
||||
position: 'uint32',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static unpack(packet) {
|
||||
const unpacked = super.unpack(packet);
|
||||
const {data} = unpacked;
|
||||
data.position = Vector.unpackFromUint32(data.position);
|
||||
return unpacked;
|
||||
}
|
||||
|
||||
}
|
22
packages/entity/src/trait/index.js
Normal file
22
packages/entity/src/trait/index.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
import {gather} from '@latus/core';
|
||||
|
||||
export {default as Trait} from './trait';
|
||||
export {default as StateProperty} from './state-property';
|
||||
|
||||
export const traitFromId = (latus) => latus.config['%traits'].fromId;
|
||||
|
||||
export const traitFromType = (latus) => latus.config['%traits'].fromType;
|
||||
|
||||
export default {
|
||||
hooks: {
|
||||
'@latus/core/starting': (latus) => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
latus.config['%traits'] = gather(
|
||||
latus,
|
||||
'@avocado/traits',
|
||||
'id',
|
||||
'type',
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
26
packages/entity/src/trait/state-property.js
Normal file
26
packages/entity/src/trait/state-property.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
import {Property} from '@avocado/core';
|
||||
|
||||
export default function StateProperty(key, meta = {}) {
|
||||
const transformedKey = `$$avocado_state_property_${key}`;
|
||||
return (Superclass) => {
|
||||
/* eslint-disable func-names, no-new-func, no-param-reassign */
|
||||
meta.emit = meta.emit || function (...args) {
|
||||
this.entity.emit(...args);
|
||||
};
|
||||
meta.initialize = meta.initialize || function () {
|
||||
this[transformedKey] = this.state[key];
|
||||
};
|
||||
meta.get = meta.get || new Function(`
|
||||
return this.${transformedKey};
|
||||
`);
|
||||
meta.set = meta.set || new Function('value', `
|
||||
if (value !== this.${transformedKey}) {
|
||||
this.setDirty();
|
||||
}
|
||||
this.${transformedKey} = value;
|
||||
this.state['${key}'] = value;
|
||||
`);
|
||||
/* eslint-enable func-names, no-new-func, no-param-reassign */
|
||||
return Property(key, meta)(Superclass);
|
||||
};
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
import {Property} from '@avocado/core';
|
||||
import {Synchronized} from '@avocado/s13n';
|
||||
import {compose, Class} from '@latus/core';
|
||||
|
||||
|
@ -6,10 +5,6 @@ const decorate = compose(
|
|||
Synchronized,
|
||||
);
|
||||
|
||||
export const traitFromId = (latus) => latus.config['%traits'].fromId;
|
||||
|
||||
export const traitFromType = (latus) => latus.config['%traits'].fromType;
|
||||
|
||||
export default class Trait extends decorate(Class) {
|
||||
|
||||
constructor(entity, params, state) {
|
||||
|
@ -160,28 +155,3 @@ export default class Trait extends decorate(Class) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
export function StateProperty(key, meta = {}) {
|
||||
const transformedKey = `$$avocado_state_property_${key}`;
|
||||
return (Superclass) => {
|
||||
/* eslint-disable func-names, no-new-func, no-param-reassign */
|
||||
meta.emit = meta.emit || function (...args) {
|
||||
this.entity.emit(...args);
|
||||
};
|
||||
meta.initialize = meta.initialize || function () {
|
||||
this[transformedKey] = this.state[key];
|
||||
};
|
||||
meta.get = meta.get || new Function(`
|
||||
return this.${transformedKey};
|
||||
`);
|
||||
meta.set = meta.set || new Function('value', `
|
||||
if (value !== this.${transformedKey}) {
|
||||
this.setDirty();
|
||||
}
|
||||
this.${transformedKey} = value;
|
||||
this.state['${key}'] = value;
|
||||
`);
|
||||
/* eslint-enable func-names, no-new-func, no-param-reassign */
|
||||
return Property(key, meta)(Superclass);
|
||||
};
|
||||
}
|
|
@ -6,9 +6,8 @@ import {
|
|||
compile,
|
||||
Context,
|
||||
} from '@avocado/behavior';
|
||||
import {compose} from '@avocado/core';
|
||||
|
||||
import Trait, {StateProperty} from '../trait';
|
||||
import {StateProperty, Trait} from '@avocado/traits';
|
||||
import {compose} from '@latus/core';
|
||||
|
||||
const decorate = compose(
|
||||
StateProperty('isDying', {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import {compose} from '@avocado/core';
|
||||
import {Vector} from '@avocado/math';
|
||||
|
||||
import Trait, {StateProperty} from '../trait';
|
||||
import {StateProperty, Trait} from '@avocado/traits';
|
||||
import {compose} from '@latus/core';
|
||||
|
||||
const decorate = compose(
|
||||
StateProperty('direction', {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {compose, TickingPromise} from '@avocado/core';
|
||||
import {TickingPromise} from '@avocado/core';
|
||||
import {TransitionResult} from '@avocado/timing';
|
||||
|
||||
import Trait, {StateProperty} from '../trait';
|
||||
import {StateProperty, Trait} from '@avocado/traits';
|
||||
import {compose} from '@latus/core';
|
||||
|
||||
const decorate = compose(
|
||||
StateProperty('name'),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {Rectangle} from '@avocado/math';
|
||||
|
||||
import Trait from '../trait';
|
||||
import {Trait} from '../trait';
|
||||
|
||||
export default class Listed extends Trait {
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {compose, TickingPromise} from '@avocado/core';
|
||||
import {TickingPromise} from '@avocado/core';
|
||||
import {Vector} from '@avocado/math';
|
||||
|
||||
import Trait, {StateProperty} from '../trait';
|
||||
import {StateProperty, Trait} from '@avocado/traits';
|
||||
import {compose} from '@latus/core';
|
||||
|
||||
const decorate = compose(
|
||||
StateProperty('isMobile'),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {compose} from '@avocado/core';
|
||||
import {compose} from '@latus/core';
|
||||
|
||||
import Trait from '../trait';
|
||||
import {Trait} from '../trait';
|
||||
|
||||
const decorate = compose(
|
||||
);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {compose, EventEmitter} from '@avocado/core';
|
||||
import {Vector} from '@avocado/math';
|
||||
import {compose, EventEmitter} from '@latus/core';
|
||||
|
||||
import Trait from '../trait';
|
||||
import {Trait} from '../trait';
|
||||
|
||||
const decorate = compose(
|
||||
EventEmitter,
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import {compose} from '@latus/core';
|
||||
import {synchronized} from '@avocado/s13n';
|
||||
import {StateProperty, Trait} from '@avocado/traits';
|
||||
import merge from 'deepmerge';
|
||||
|
||||
import Trait, {StateProperty} from '../trait';
|
||||
|
||||
const decorate = compose(
|
||||
StateProperty('isSpawning', {
|
||||
track: true,
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
|
||||
"@avocado/behavior@2.0.0", "@avocado/behavior@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fbehavior/-/behavior-2.0.0.tgz#6478ca2f16957c3a010f792e013f4688583bf033"
|
||||
integrity sha512-psHGbLG/EVaY6/9FwCvnNYA7LLXYVUQUiDbXZAyhkPNV5dAEmcQX8LdYUxDJ2Q32upow15+t8Np8u0XHcOHc4g==
|
||||
resolved "http://172.18.0.8:4873/@avocado%2fbehavior/-/behavior-2.0.0.tgz#5a59518aa2dadb24dcc7a81dfad3a544a0131e15"
|
||||
integrity sha512-AUrVcrNUNTDLrKa9PsxuvnCuRm+n1yKtDXjoXYzJ4NgHBT0//A6Jp6S0odURTprVsd1Ef77U8WpAj8GdU7ekQQ==
|
||||
dependencies:
|
||||
"@avocado/core" "^2.0.0"
|
||||
"@avocado/core" "2.0.0"
|
||||
"@avocado/entity" "2.0.0"
|
||||
"@latus/core" "^2.0.0"
|
||||
"@latus/core" "2.0.0"
|
||||
debug "4.3.1"
|
||||
deepmerge "^4.2.2"
|
||||
lodash.mapvalues "^4.6.0"
|
||||
|
@ -23,14 +23,15 @@
|
|||
|
||||
"@avocado/entity@2.0.0", "@avocado/entity@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fentity/-/entity-2.0.0.tgz#b2bf5e249949a7dd0d67a39c0748ff318ffbc5ec"
|
||||
integrity sha512-ywhhF/8w8ofBcmoBFIcTAfbn4EgabH9JrwlPqCwUbNfhPNAFPeetUeilPcgEMd4F47CtyoQcqKOgagJzKN1ocQ==
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fentity/-/entity-2.0.0.tgz#935d667171b849d5764728ab1af30fe4a017c7b3"
|
||||
integrity sha512-F/yDjVQbBnZEQPQ29ZKO0x8dgPiqM1VUnAr4qLekxIvIgQt6Vn7n7AOaIZZLsHy5yjZI0JzjoaELqUlT3NHi2w==
|
||||
dependencies:
|
||||
"@avocado/behavior" "2.0.0"
|
||||
"@avocado/behavior" "^2.0.0"
|
||||
"@avocado/core" "2.0.0"
|
||||
"@avocado/math" "2.0.0"
|
||||
"@avocado/resource" "2.0.0"
|
||||
"@avocado/s13n" "2.0.0"
|
||||
"@avocado/s13n" "^2.0.0"
|
||||
"@avocado/timing" "^2.0.0"
|
||||
"@latus/core" "^2.0.0"
|
||||
"@latus/socket" "^2.0.0"
|
||||
debug "4.3.1"
|
||||
|
@ -39,13 +40,14 @@
|
|||
|
||||
"@avocado/graphics@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fgraphics/-/graphics-2.0.0.tgz#411b06aeada19698eac275d5ae30348e6a5bfad9"
|
||||
integrity sha512-zhxqAMOPzXeN4rd4Bv5u/7MsOBf5YX4p78znIpjrI/69QycYu+KSSBpgksQEwx0JwYWRNWcNw+5a4Q72nPVJuQ==
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fgraphics/-/graphics-2.0.0.tgz#cc83b17a13ba5baf4bc1ed5345ead5090bb41fff"
|
||||
integrity sha512-aHpkLHaeR9Ujd1sxLCALKK79BV1CGau8MilqZxucc9JbnXllXhACBKrvHjRg33OT9NKlXLDF87svATJsrFqwGQ==
|
||||
dependencies:
|
||||
"@avocado/core" "2.0.0"
|
||||
"@avocado/entity" "2.0.0"
|
||||
"@avocado/input" "2.0.0"
|
||||
"@avocado/math" "2.0.0"
|
||||
"@avocado/resource" "^2.0.0"
|
||||
"@avocado/resource" "2.0.0"
|
||||
"@latus/core" "^2.0.0"
|
||||
"@latus/socket" "^2.0.0"
|
||||
"@pixi/constants" "^5.3.6"
|
||||
|
@ -58,6 +60,7 @@
|
|||
"@pixi/sprite" "^5.3.6"
|
||||
"@pixi/text" "^5.3.6"
|
||||
debug "4.3.1"
|
||||
image-size "^0.9.3"
|
||||
|
||||
"@avocado/input@2.0.0":
|
||||
version "2.0.0"
|
||||
|
@ -79,8 +82,8 @@
|
|||
|
||||
"@avocado/resource@2.0.0", "@avocado/resource@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fresource/-/resource-2.0.0.tgz#a7b594584c172cff472d9a298bcd9d62c27186f2"
|
||||
integrity sha512-q7MacbQl1ozA5Z3ZOKyUcMRBJAhly19dCtrNxYCki7mXIe1DoP0VvipFIgMlquLhkmtxxT2uMzVvHeJxhDxsgw==
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fresource/-/resource-2.0.0.tgz#2eb014c2c876f3f51bc71d6594d93091b22013c8"
|
||||
integrity sha512-3dks0rsuY1twlLm+vTrsqfV9anXR/0ZdQfe2YAJIdmiVQ7QEB2mQhUgMvqjgsuhI7ad1ygxD/I9hXBjl6CvyjA==
|
||||
dependencies:
|
||||
"@avocado/core" "^2.0.0"
|
||||
"@latus/core" "^2.0.0"
|
||||
|
@ -88,17 +91,7 @@
|
|||
deepmerge "^4.2.2"
|
||||
uuid "^8.3.2"
|
||||
|
||||
"@avocado/s13n@2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fs13n/-/s13n-2.0.0.tgz#73804668f5744dffb358d14a4ee486250a79b222"
|
||||
integrity sha512-Hy0U7PWHVUhpDFFyOD20xKVNUP5FEgjJWkDS0WQHYwtQFi4FysHl80POxxNDvGEsQ4kkgNBwvudmOKoOORe9SA==
|
||||
dependencies:
|
||||
"@latus/core" "^2.0.0"
|
||||
"@latus/socket" "^2.0.0"
|
||||
debug "4.3.1"
|
||||
msgpack-lite "^0.1.26"
|
||||
|
||||
"@avocado/s13n@^2.0.0":
|
||||
"@avocado/s13n@2.0.0", "@avocado/s13n@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fs13n/-/s13n-2.0.0.tgz#ec6b7c9d28753c21c5fe265a5d2f2be5bc752d69"
|
||||
integrity sha512-b+eTosKoNIh4Mhd5HEbCJ366sXMsYgnqFYHHHRDWGScOnr+RvYI4aa8gIqDRQ+F0WMfXs03R9sEGB/fmoFYCtg==
|
||||
|
@ -108,7 +101,7 @@
|
|||
debug "4.3.1"
|
||||
msgpack-lite "^0.1.26"
|
||||
|
||||
"@avocado/timing@^2.0.0":
|
||||
"@avocado/timing@2.0.0", "@avocado/timing@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2ftiming/-/timing-2.0.0.tgz#de76571519cb835a7f45528e91bdb9a18f1947fa"
|
||||
integrity sha512-pJITg7q3kX9H2XEFP+jHPMiY317o4rCb/zzBdUbqC1RY5z5Et/LeTkQa/pd4IPqXeUK9omW4eM24jdCp8uH1tg==
|
||||
|
@ -122,6 +115,16 @@
|
|||
"@latus/socket" "^2.0.0"
|
||||
debug "4.3.1"
|
||||
|
||||
"@avocado/traits@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "http://172.18.0.8:4873/@avocado%2ftraits/-/traits-2.0.0.tgz#4717919e101a4fa81469bc5efe7c5478bb293a4e"
|
||||
integrity sha512-7siD4XME3NzhTholUPndRYloHowV8z/s+FnzqG7p2/idNHrXURXsVBeYBI9lcM0SX1ONY+9OVdH0ykiu5qBScg==
|
||||
dependencies:
|
||||
"@avocado/core" "^2.0.0"
|
||||
"@avocado/s13n" "^2.0.0"
|
||||
"@latus/core" "^2.0.0"
|
||||
debug "4.3.1"
|
||||
|
||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.11":
|
||||
version "7.12.11"
|
||||
resolved "https://npm.i12e.cha0s.io/@babel%2fcode-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
|
||||
|
@ -1012,7 +1015,7 @@
|
|||
minimatch "^3.0.4"
|
||||
strip-json-comments "^3.1.1"
|
||||
|
||||
"@latus/core@^2.0.0":
|
||||
"@latus/core@2.0.0", "@latus/core@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@latus%2fcore/-/core-2.0.0.tgz#4447b4bba265b684035be1dacefd6ba4913a47d4"
|
||||
integrity sha512-OSsbO4wvVJFPZTMRDX5LAXOA+MQY8FOSK7PcTEJKeiRqOMeMIVkZc6q6KNlUIYivE+87rlM7S/CctHoA7uvQvg==
|
||||
|
@ -1040,10 +1043,10 @@
|
|||
webpack-hot-middleware "^2.25.0"
|
||||
webpack-virtual-modules "^0.4.1"
|
||||
|
||||
"@latus/socket@^2.0.0":
|
||||
"@latus/socket@2.0.0", "@latus/socket@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@latus%2fsocket/-/socket-2.0.0.tgz#2a35bba0db3542ab18a913320f7f6d24228ab5f1"
|
||||
integrity sha512-qAWV/+3GI/GNyu/Ls6EFZpZr+2Q288YtgyjOzCNm6nRwy9N+JGJs1Y7yhJlLuao0K5EzHuYif3Vpo4DeRIVqNw==
|
||||
resolved "https://npm.i12e.cha0s.io/@latus%2fsocket/-/socket-2.0.0.tgz#3dc0f02ec3e24e515ba6fc9302e7ac4a63351e25"
|
||||
integrity sha512-0NlEYCBPkxtFX0utLhMacqGhd6rtSaQTudMXTtwuWxqRdkzJb4aC5BJ2BtDj0iH5KGCdbcQ4kE1cGGKdOk5mMA==
|
||||
dependencies:
|
||||
"@latus/core" "^2.0.0"
|
||||
"@latus/http" "^2.0.0"
|
||||
|
@ -1183,31 +1186,31 @@
|
|||
babel-merge "^3.0.0"
|
||||
deepmerge "^1.5.2"
|
||||
|
||||
"@pixi/constants@5.3.6", "@pixi/constants@^5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fconstants/-/constants-5.3.6.tgz#b3b61b5d5047d022df3b8bed82eeb2b052457ded"
|
||||
integrity sha512-4FF6GIj88/rddqMJeVlbxKUDgSpb6vSX9yWR1S17Urn4B3RCZErlfSEcTIuSOpLbs0F1h9K7UdIrzbJp2aefzw==
|
||||
"@pixi/constants@5.3.7", "@pixi/constants@^5.3.6":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fconstants/-/constants-5.3.7.tgz#a2e1789a98deb3713cfcb3eba3db84588bc9161e"
|
||||
integrity sha512-MBcgIM/mSqonFezkCI9080IqNlc0wb8S9QJ5otBdseOWUQa/ua2jF7Jd1sCBGmi0IzS9/NOHFXzZVTdS7AC7Ow==
|
||||
|
||||
"@pixi/core@5.3.6", "@pixi/core@^5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fcore/-/core-5.3.6.tgz#85559a71fd35c459c094ff30899f85cbcf8d2f81"
|
||||
integrity sha512-Q5myUdcaJH5dtWbxerLn6YSFR3AjIgk58o7x7CzymJ7U5kdBjNB0yNdMVSbDQpf+lK4edtWYpuelot7SAthk+g==
|
||||
"@pixi/core@5.3.7", "@pixi/core@^5.3.6":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fcore/-/core-5.3.7.tgz#a8d65ca17f0c4ef8c0c5a22d31b9e02a4ab73b93"
|
||||
integrity sha512-WBhU2f5aJSVVaFP55FFBFKjKlRf5fYGxgA/U3kD4yD4Y3d3d6V3MIZv+o0VX+kBs1Eq7ePZqEv2smDrlzzMEjQ==
|
||||
dependencies:
|
||||
"@pixi/constants" "5.3.6"
|
||||
"@pixi/math" "5.3.6"
|
||||
"@pixi/runner" "5.3.6"
|
||||
"@pixi/settings" "5.3.6"
|
||||
"@pixi/ticker" "5.3.6"
|
||||
"@pixi/utils" "5.3.6"
|
||||
"@pixi/constants" "5.3.7"
|
||||
"@pixi/math" "5.3.7"
|
||||
"@pixi/runner" "5.3.7"
|
||||
"@pixi/settings" "5.3.7"
|
||||
"@pixi/ticker" "5.3.7"
|
||||
"@pixi/utils" "5.3.7"
|
||||
|
||||
"@pixi/display@5.3.6", "@pixi/display@^5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fdisplay/-/display-5.3.6.tgz#90a629c4d9b7a118b7b8cc0ea4b843d1b93026f3"
|
||||
integrity sha512-cbUaWz2R2vNO5BD9Ic6hYyazQQV8ndQfPonbBcehQQhNC+aZjuYgarHqiUb4Z7/GKkRQzB9WyoT8P5V5LppufQ==
|
||||
"@pixi/display@5.3.7", "@pixi/display@^5.3.6":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fdisplay/-/display-5.3.7.tgz#b661d2ecfd2a67f213665a0698acd29e17eee8fe"
|
||||
integrity sha512-ma1JyLe5vaEgmaOR+anvj5YOKqT9OEWnboIe7NVmwGF1CZ7JFnB12rsRulHUsSaFG9bP5xjvroAZjFg/WvyGLw==
|
||||
dependencies:
|
||||
"@pixi/math" "5.3.6"
|
||||
"@pixi/settings" "5.3.6"
|
||||
"@pixi/utils" "5.3.6"
|
||||
"@pixi/math" "5.3.7"
|
||||
"@pixi/settings" "5.3.7"
|
||||
"@pixi/utils" "5.3.7"
|
||||
|
||||
"@pixi/filter-advanced-bloom@^3.2.0":
|
||||
version "3.2.0"
|
||||
|
@ -1217,11 +1220,11 @@
|
|||
"@pixi/filter-kawase-blur" "3.2.0"
|
||||
|
||||
"@pixi/filter-color-matrix@^5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2ffilter-color-matrix/-/filter-color-matrix-5.3.6.tgz#466f563e20721900b202a87c8d47a5ea8e31c741"
|
||||
integrity sha512-u/OZEPhdMT2rzCNZZXBsIwVyp79X4rM029JMioJdYrFEPDnAuDIBKrY5//gOHFdQlYsjRIaW0IcykCPqUvBs3A==
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2ffilter-color-matrix/-/filter-color-matrix-5.3.7.tgz#230cafe46bde36e25441b13f3ac5dd8e8fee4311"
|
||||
integrity sha512-Z12cxoHx9uMh3CZ0PLVRzsaFHHF/CfU3J83KI9k+Bg/DFOh/J/5EToCd44jYJbMKp3nvXcO1EJyZ3wwC/IsyfQ==
|
||||
dependencies:
|
||||
"@pixi/core" "5.3.6"
|
||||
"@pixi/core" "5.3.7"
|
||||
|
||||
"@pixi/filter-kawase-blur@3.2.0":
|
||||
version "3.2.0"
|
||||
|
@ -1229,71 +1232,71 @@
|
|||
integrity sha512-IO1UKn/XLvnV+ya4r1UOC9fTfXZjWvH9m6eQ/U+moBsQN5I5FihQfXCu586X4jb9VHNu3gFl7SUzirobhBfgtA==
|
||||
|
||||
"@pixi/graphics@^5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fgraphics/-/graphics-5.3.6.tgz#1d38359926d174cccd3219936285140b715344e7"
|
||||
integrity sha512-FDZlAkxrbCZTjzNMWW6q6N/GAfyfftwHOGb67oLJ+NCG2wagOGUPQYRRGBK5f45dgDdM+1is7UwbhdQ8Rvg9ig==
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fgraphics/-/graphics-5.3.7.tgz#36ae80e2508e0a9c61ce454807d517d370d90a74"
|
||||
integrity sha512-+6+bT/AC29a1Hw5XDxsH1UqBsXSqcna7wNTTrBQ02owotIJtyRc6w48f5qxzhxycumyVCR87IV5tAtdwX3xhag==
|
||||
dependencies:
|
||||
"@pixi/constants" "5.3.6"
|
||||
"@pixi/core" "5.3.6"
|
||||
"@pixi/display" "5.3.6"
|
||||
"@pixi/math" "5.3.6"
|
||||
"@pixi/sprite" "5.3.6"
|
||||
"@pixi/utils" "5.3.6"
|
||||
"@pixi/constants" "5.3.7"
|
||||
"@pixi/core" "5.3.7"
|
||||
"@pixi/display" "5.3.7"
|
||||
"@pixi/math" "5.3.7"
|
||||
"@pixi/sprite" "5.3.7"
|
||||
"@pixi/utils" "5.3.7"
|
||||
|
||||
"@pixi/math@5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fmath/-/math-5.3.6.tgz#3933bae1a0af912b4384389b63ceffdcf108723a"
|
||||
integrity sha512-ccW/LrSsLaHunj1ztfp2UpxKGftiaK/nURZa51CFhbGYQBrYZBk27x1fgwGAs4ualTtqZOeyaLhv4nY0ljm5Qw==
|
||||
"@pixi/math@5.3.7":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fmath/-/math-5.3.7.tgz#066e7ea149fd38db8d8a9584aac5f41d02b36bdd"
|
||||
integrity sha512-WnjUwX7rkxR36F0xknpsNd9BsfQosV0BbyFE0Il88IURBM3Tu9X4tC7RGJDgWU+aXw23HgHu0j+MWJrCVCM2fA==
|
||||
|
||||
"@pixi/runner@5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2frunner/-/runner-5.3.6.tgz#b123f1a674aa249e4067ff00f9a3027d01ac69a8"
|
||||
integrity sha512-qiGoMVk0P0p3IfH5LTIH/dKyiNUzIHMxoykPODWni648hFa4CEFpG3bHJorcyYvmALCFgHjH2hhrqQexK3T6Kw==
|
||||
"@pixi/runner@5.3.7":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2frunner/-/runner-5.3.7.tgz#78ed2c92b392b8c099d2e4557dded7faa921446b"
|
||||
integrity sha512-kt5apNb21HAvpBaDaPRs33k2O0VzrKe13w4we8iftCpXX8w68ErAY1lH68vmtDNrxnlHg4M9nRgEoMeiHlo2RA==
|
||||
|
||||
"@pixi/settings@5.3.6", "@pixi/settings@^5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fsettings/-/settings-5.3.6.tgz#d138ba2180557174c3f942fc9656de35f1a77026"
|
||||
integrity sha512-hWMC1KwB2InFoJPdnI97ckHX0Z7912aaB2oQUJwKv0hhSrc8vxq9Dg6UofVY+wGMHDVCvqJPnvCsTYuKUmwRxw==
|
||||
"@pixi/settings@5.3.7", "@pixi/settings@^5.3.6":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fsettings/-/settings-5.3.7.tgz#b661883231bf2a1ff5260c214bd0c4b438759841"
|
||||
integrity sha512-g6AoRSGWxU34gtKSQwX2AMQoLUv86L/5iIXRsqo+X4bfUSCenTci1X7ueVrSIbo39dxh6IOpriZF2Yk3TeHG5w==
|
||||
dependencies:
|
||||
ismobilejs "^1.1.0"
|
||||
|
||||
"@pixi/sprite@5.3.6", "@pixi/sprite@^5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fsprite/-/sprite-5.3.6.tgz#04c13b0ce1c7379a2f570d28db58d1f54ce44c55"
|
||||
integrity sha512-Q5nRj7mhWuVHvn2rMtlf+6CdTjdovxX0R9ANffPcY7EODn5m7F4GpXEwBOjDICtVyHXrXhz2k4Gi2XWPFeeZ7A==
|
||||
"@pixi/sprite@5.3.7", "@pixi/sprite@^5.3.6":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fsprite/-/sprite-5.3.7.tgz#c6edf3d4a9928868696b62e35a60ded27d167058"
|
||||
integrity sha512-Bjl+NOOvigEzUsm1cDr1KmBUpPSWO8pDXpUPTi+v2N75gwRfTycmj5f2TU0QmMW3Gc6sv0CB0AkL7dkMPwPb8g==
|
||||
dependencies:
|
||||
"@pixi/constants" "5.3.6"
|
||||
"@pixi/core" "5.3.6"
|
||||
"@pixi/display" "5.3.6"
|
||||
"@pixi/math" "5.3.6"
|
||||
"@pixi/settings" "5.3.6"
|
||||
"@pixi/utils" "5.3.6"
|
||||
"@pixi/constants" "5.3.7"
|
||||
"@pixi/core" "5.3.7"
|
||||
"@pixi/display" "5.3.7"
|
||||
"@pixi/math" "5.3.7"
|
||||
"@pixi/settings" "5.3.7"
|
||||
"@pixi/utils" "5.3.7"
|
||||
|
||||
"@pixi/text@^5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2ftext/-/text-5.3.6.tgz#55b45c8968a28304f5b7aef289e6f062772a060a"
|
||||
integrity sha512-maEZoIysPOuzzSH+TN2cGnqDDMdTVtFNY9dJdKgmMleY9oCPES/iiNkcdki40S9JfaM7GM3ywn2xbJruJ5aZCg==
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2ftext/-/text-5.3.7.tgz#cb71b2576bdc1f66fb79977d281f9575dd06d3d5"
|
||||
integrity sha512-WVAc31MDgHTvP0dJNWsvLVJhjeVGZ3NrLpHcH9iIAd6HVO5Z+i+fk4zvodD+Y7jWU0psx8ZD8xe1wy8ECfbCBA==
|
||||
dependencies:
|
||||
"@pixi/core" "5.3.6"
|
||||
"@pixi/math" "5.3.6"
|
||||
"@pixi/settings" "5.3.6"
|
||||
"@pixi/sprite" "5.3.6"
|
||||
"@pixi/utils" "5.3.6"
|
||||
"@pixi/core" "5.3.7"
|
||||
"@pixi/math" "5.3.7"
|
||||
"@pixi/settings" "5.3.7"
|
||||
"@pixi/sprite" "5.3.7"
|
||||
"@pixi/utils" "5.3.7"
|
||||
|
||||
"@pixi/ticker@5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fticker/-/ticker-5.3.6.tgz#022416047199ae1ac875f750efddfb0a0ba20abd"
|
||||
integrity sha512-3BHDrFyI5aHcAlo9fdQ5pd4U1pwt5QwGpbM9EshFL2NeNdumAeZQJ850DXFhVfFAXhhNljEQTFNZ44sTIsAy6Q==
|
||||
"@pixi/ticker@5.3.7":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fticker/-/ticker-5.3.7.tgz#c331b270042d507fe18543ae435a9a857a8fd5ae"
|
||||
integrity sha512-ZEXiJwPtuPeWa0QmRODF5qK0+ugZu/xeq7QxCvFOCc3NFVBeGms4g92HPucOju9R7jcODIoJxtICALsuwLAr9w==
|
||||
dependencies:
|
||||
"@pixi/settings" "5.3.6"
|
||||
"@pixi/settings" "5.3.7"
|
||||
|
||||
"@pixi/utils@5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2futils/-/utils-5.3.6.tgz#63ada7f024884390324b430ad19b6e031791c319"
|
||||
integrity sha512-Ilix2qpF89SSyoUpPsjH2RB7Os6ceQ+gts55zpMbLyxMyuMH6GlZ9WgUEhAakkUEtQ6imi3ZZAxCNLAEWNB+cw==
|
||||
"@pixi/utils@5.3.7":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2futils/-/utils-5.3.7.tgz#55fe2a2fbf0fba842da5a602576ce68c498e7e16"
|
||||
integrity sha512-f8zAeHHURxfwBr8MZiXEIwY2h9wbS6vN0ypvapGvKFOexZ1EInTs35FhEiRWzLEPLHyn1RgCdKzR2zl++E4tIw==
|
||||
dependencies:
|
||||
"@pixi/constants" "5.3.6"
|
||||
"@pixi/settings" "5.3.6"
|
||||
"@pixi/constants" "5.3.7"
|
||||
"@pixi/settings" "5.3.7"
|
||||
earcut "^2.1.5"
|
||||
eventemitter3 "^3.1.0"
|
||||
url "^0.11.0"
|
||||
|
@ -2214,9 +2217,9 @@ camelcase@^6.0.0:
|
|||
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
|
||||
|
||||
caniuse-lite@^1.0.30001165:
|
||||
version "1.0.30001170"
|
||||
resolved "https://npm.i12e.cha0s.io/caniuse-lite/-/caniuse-lite-1.0.30001170.tgz#0088bfecc6a14694969e391cc29d7eb6362ca6a7"
|
||||
integrity sha512-Dd4d/+0tsK0UNLrZs3CvNukqalnVTRrxb5mcQm8rHL49t7V5ZaTygwXkrq+FB+dVDf++4ri8eJnFEJAB8332PA==
|
||||
version "1.0.30001171"
|
||||
resolved "https://npm.i12e.cha0s.io/caniuse-lite/-/caniuse-lite-1.0.30001171.tgz#3291e11e02699ad0a29e69b8d407666fc843eba7"
|
||||
integrity sha512-5Alrh8TTYPG9IH4UkRqEBZoEToWRLvPbSQokvzSz0lii8/FOWKG4keO1HoYfPWs8IF/NH/dyNPg1cmJGvV3Zlg==
|
||||
|
||||
chai@4.2.0:
|
||||
version "4.2.0"
|
||||
|
@ -2702,7 +2705,7 @@ debug@4.3.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
|
|||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
debug@^3.1.1, debug@^3.2.5:
|
||||
debug@^3.1.1, debug@^3.2.6:
|
||||
version "3.2.7"
|
||||
resolved "https://npm.i12e.cha0s.io/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
|
||||
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
|
||||
|
@ -3150,7 +3153,7 @@ es-abstract@^1.17.0-next.1:
|
|||
string.prototype.trimend "^1.0.1"
|
||||
string.prototype.trimstart "^1.0.1"
|
||||
|
||||
es-abstract@^1.18.0-next.0, es-abstract@^1.18.0-next.1:
|
||||
es-abstract@^1.18.0-next.1:
|
||||
version "1.18.0-next.1"
|
||||
resolved "https://npm.i12e.cha0s.io/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68"
|
||||
integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==
|
||||
|
@ -3289,9 +3292,9 @@ eslint-plugin-react-hooks@^4.2.0:
|
|||
integrity sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==
|
||||
|
||||
eslint-plugin-react@^7.21.5:
|
||||
version "7.21.5"
|
||||
resolved "https://npm.i12e.cha0s.io/eslint-plugin-react/-/eslint-plugin-react-7.21.5.tgz#50b21a412b9574bfe05b21db176e8b7b3b15bff3"
|
||||
integrity sha512-8MaEggC2et0wSF6bUeywF7qQ46ER81irOdWS4QWxnnlAEsnzeBevk1sWh7fhpCghPpXb+8Ks7hvaft6L/xsR6g==
|
||||
version "7.22.0"
|
||||
resolved "https://npm.i12e.cha0s.io/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz#3d1c542d1d3169c45421c1215d9470e341707269"
|
||||
integrity sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA==
|
||||
dependencies:
|
||||
array-includes "^3.1.1"
|
||||
array.prototype.flatmap "^1.2.3"
|
||||
|
@ -3592,14 +3595,7 @@ fastparse@^1.1.1:
|
|||
resolved "https://npm.i12e.cha0s.io/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9"
|
||||
integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==
|
||||
|
||||
faye-websocket@^0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://npm.i12e.cha0s.io/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
|
||||
integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=
|
||||
dependencies:
|
||||
websocket-driver ">=0.5.1"
|
||||
|
||||
faye-websocket@~0.11.1:
|
||||
faye-websocket@^0.11.3:
|
||||
version "0.11.3"
|
||||
resolved "https://npm.i12e.cha0s.io/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e"
|
||||
integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==
|
||||
|
@ -3852,7 +3848,7 @@ get-func-name@^2.0.0:
|
|||
resolved "https://npm.i12e.cha0s.io/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
|
||||
integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=
|
||||
|
||||
get-intrinsic@^1.0.0, get-intrinsic@^1.0.1:
|
||||
get-intrinsic@^1.0.0, get-intrinsic@^1.0.1, get-intrinsic@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://npm.i12e.cha0s.io/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49"
|
||||
integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==
|
||||
|
@ -4273,6 +4269,13 @@ ignore@^4.0.6:
|
|||
resolved "https://npm.i12e.cha0s.io/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
|
||||
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
|
||||
|
||||
image-size@^0.9.3:
|
||||
version "0.9.3"
|
||||
resolved "https://npm.i12e.cha0s.io/image-size/-/image-size-0.9.3.tgz#f7efce6b0a1649b44b9bc43b9d9a5acf272264b6"
|
||||
integrity sha512-5SakFa79uhUVSjKeQE30GVzzLJ0QNzB53+I+/VD1vIesD6GP6uatWIlgU0uisFNLt1u0d6kBydp7yfk+lLJhLQ==
|
||||
dependencies:
|
||||
queue "6.0.1"
|
||||
|
||||
import-fresh@^3.0.0, import-fresh@^3.2.1:
|
||||
version "3.3.0"
|
||||
resolved "https://npm.i12e.cha0s.io/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
||||
|
@ -4689,7 +4692,7 @@ json-stable-stringify-without-jsonify@^1.0.1:
|
|||
resolved "https://npm.i12e.cha0s.io/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
|
||||
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
|
||||
|
||||
json3@^3.3.2:
|
||||
json3@^3.3.3:
|
||||
version "3.3.3"
|
||||
resolved "https://npm.i12e.cha0s.io/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
|
||||
integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==
|
||||
|
@ -5401,7 +5404,7 @@ object-hash@^2.0.3:
|
|||
resolved "https://npm.i12e.cha0s.io/object-hash/-/object-hash-2.1.1.tgz#9447d0279b4fcf80cff3259bf66a1dc73afabe09"
|
||||
integrity sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==
|
||||
|
||||
object-inspect@^1.8.0:
|
||||
object-inspect@^1.8.0, object-inspect@^1.9.0:
|
||||
version "1.9.0"
|
||||
resolved "https://npm.i12e.cha0s.io/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a"
|
||||
integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==
|
||||
|
@ -6082,6 +6085,13 @@ querystringify@^2.1.1:
|
|||
resolved "https://npm.i12e.cha0s.io/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
|
||||
integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
|
||||
|
||||
queue@6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://npm.i12e.cha0s.io/queue/-/queue-6.0.1.tgz#abd5a5b0376912f070a25729e0b6a7d565683791"
|
||||
integrity sha512-AJBQabRCCNr9ANq8v77RJEv73DPbn55cdTb+Giq4X0AVnNVZvMHlYp7XlQiN+1npCZj1DuSmaA2hYVUUDgxFDg==
|
||||
dependencies:
|
||||
inherits "~2.0.3"
|
||||
|
||||
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://npm.i12e.cha0s.io/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
|
||||
|
@ -6433,7 +6443,7 @@ select-hose@^2.0.0:
|
|||
resolved "https://npm.i12e.cha0s.io/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
||||
integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
|
||||
|
||||
selfsigned@^1.10.7:
|
||||
selfsigned@^1.10.8:
|
||||
version "1.10.8"
|
||||
resolved "https://npm.i12e.cha0s.io/selfsigned/-/selfsigned-1.10.8.tgz#0d17208b7d12c33f8eac85c41835f27fc3d81a30"
|
||||
integrity sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==
|
||||
|
@ -6581,12 +6591,13 @@ shebang-regex@^3.0.0:
|
|||
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
||||
|
||||
side-channel@^1.0.2, side-channel@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://npm.i12e.cha0s.io/side-channel/-/side-channel-1.0.3.tgz#cdc46b057550bbab63706210838df5d4c19519c3"
|
||||
integrity sha512-A6+ByhlLkksFoUepsGxfj5x1gTSrs+OydsRptUxeNCabQpCFUvcwIczgOigI8vhY/OJCnPnyE9rGiwgvr9cS1g==
|
||||
version "1.0.4"
|
||||
resolved "https://npm.i12e.cha0s.io/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
|
||||
integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
|
||||
dependencies:
|
||||
es-abstract "^1.18.0-next.0"
|
||||
object-inspect "^1.8.0"
|
||||
call-bind "^1.0.0"
|
||||
get-intrinsic "^1.0.2"
|
||||
object-inspect "^1.9.0"
|
||||
|
||||
signal-exit@^3.0.0:
|
||||
version "3.0.3"
|
||||
|
@ -6692,26 +6703,26 @@ socket.io@2.3.0:
|
|||
socket.io-client "2.3.0"
|
||||
socket.io-parser "~3.4.0"
|
||||
|
||||
sockjs-client@1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://npm.i12e.cha0s.io/sockjs-client/-/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5"
|
||||
integrity sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==
|
||||
sockjs-client@^1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://npm.i12e.cha0s.io/sockjs-client/-/sockjs-client-1.5.0.tgz#2f8ff5d4b659e0d092f7aba0b7c386bd2aa20add"
|
||||
integrity sha512-8Dt3BDi4FYNrCFGTL/HtwVzkARrENdwOUf1ZoW/9p3M8lZdFT35jVdrHza+qgxuG9H3/shR4cuX/X9umUrjP8Q==
|
||||
dependencies:
|
||||
debug "^3.2.5"
|
||||
debug "^3.2.6"
|
||||
eventsource "^1.0.7"
|
||||
faye-websocket "~0.11.1"
|
||||
inherits "^2.0.3"
|
||||
json3 "^3.3.2"
|
||||
url-parse "^1.4.3"
|
||||
faye-websocket "^0.11.3"
|
||||
inherits "^2.0.4"
|
||||
json3 "^3.3.3"
|
||||
url-parse "^1.4.7"
|
||||
|
||||
sockjs@0.3.20:
|
||||
version "0.3.20"
|
||||
resolved "https://npm.i12e.cha0s.io/sockjs/-/sockjs-0.3.20.tgz#b26a283ec562ef8b2687b44033a4eeceac75d855"
|
||||
integrity sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==
|
||||
sockjs@^0.3.21:
|
||||
version "0.3.21"
|
||||
resolved "https://npm.i12e.cha0s.io/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417"
|
||||
integrity sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==
|
||||
dependencies:
|
||||
faye-websocket "^0.10.0"
|
||||
faye-websocket "^0.11.3"
|
||||
uuid "^3.4.0"
|
||||
websocket-driver "0.6.5"
|
||||
websocket-driver "^0.7.4"
|
||||
|
||||
sort-keys@^1.0.0:
|
||||
version "1.1.2"
|
||||
|
@ -7313,7 +7324,7 @@ url-loader@^4.1.1:
|
|||
mime-types "^2.1.27"
|
||||
schema-utils "^3.0.0"
|
||||
|
||||
url-parse@^1.4.3:
|
||||
url-parse@^1.4.3, url-parse@^1.4.7:
|
||||
version "1.4.7"
|
||||
resolved "https://npm.i12e.cha0s.io/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278"
|
||||
integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==
|
||||
|
@ -7477,9 +7488,9 @@ webpack-dev-middleware@^4.0.2:
|
|||
schema-utils "^3.0.0"
|
||||
|
||||
webpack-dev-server@^3.11.0:
|
||||
version "3.11.0"
|
||||
resolved "https://npm.i12e.cha0s.io/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz#8f154a3bce1bcfd1cc618ef4e703278855e7ff8c"
|
||||
integrity sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==
|
||||
version "3.11.1"
|
||||
resolved "https://npm.i12e.cha0s.io/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz#c74028bf5ba8885aaf230e48a20e8936ab8511f0"
|
||||
integrity sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ==
|
||||
dependencies:
|
||||
ansi-html "0.0.7"
|
||||
bonjour "^3.5.0"
|
||||
|
@ -7501,11 +7512,11 @@ webpack-dev-server@^3.11.0:
|
|||
p-retry "^3.0.1"
|
||||
portfinder "^1.0.26"
|
||||
schema-utils "^1.0.0"
|
||||
selfsigned "^1.10.7"
|
||||
selfsigned "^1.10.8"
|
||||
semver "^6.3.0"
|
||||
serve-index "^1.9.1"
|
||||
sockjs "0.3.20"
|
||||
sockjs-client "1.4.0"
|
||||
sockjs "^0.3.21"
|
||||
sockjs-client "^1.5.0"
|
||||
spdy "^4.0.2"
|
||||
strip-ansi "^3.0.1"
|
||||
supports-color "^6.1.0"
|
||||
|
@ -7580,14 +7591,7 @@ webpack@^4:
|
|||
watchpack "^1.7.4"
|
||||
webpack-sources "^1.4.1"
|
||||
|
||||
websocket-driver@0.6.5:
|
||||
version "0.6.5"
|
||||
resolved "https://npm.i12e.cha0s.io/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36"
|
||||
integrity sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=
|
||||
dependencies:
|
||||
websocket-extensions ">=0.1.1"
|
||||
|
||||
websocket-driver@>=0.5.1:
|
||||
websocket-driver@>=0.5.1, websocket-driver@^0.7.4:
|
||||
version "0.7.4"
|
||||
resolved "https://npm.i12e.cha0s.io/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760"
|
||||
integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==
|
||||
|
@ -7666,9 +7670,9 @@ ws@^6.2.1:
|
|||
async-limiter "~1.0.0"
|
||||
|
||||
ws@^7.1.2:
|
||||
version "7.4.1"
|
||||
resolved "https://npm.i12e.cha0s.io/ws/-/ws-7.4.1.tgz#a333be02696bd0e54cea0434e21dcc8a9ac294bb"
|
||||
integrity sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==
|
||||
version "7.4.2"
|
||||
resolved "https://npm.i12e.cha0s.io/ws/-/ws-7.4.2.tgz#782100048e54eb36fe9843363ab1c68672b261dd"
|
||||
integrity sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==
|
||||
|
||||
ws@~6.1.0:
|
||||
version "6.1.4"
|
||||
|
|
|
@ -1 +1,19 @@
|
|||
const banner = require('@neutrinojs/banner');
|
||||
|
||||
module.exports = require('../../config/.neutrinorc');
|
||||
|
||||
const code = [
|
||||
"if (process && 'client' !== process.env.SIDE) {",
|
||||
"require('pirates').addHook(",
|
||||
"(code, filename) => '',",
|
||||
"{",
|
||||
"ignoreNodeModules: false,",
|
||||
"matcher: (filename) => filename.match('@pixi')",
|
||||
"}",
|
||||
")",
|
||||
"}",
|
||||
].join('');
|
||||
|
||||
module.exports.use.push(banner({
|
||||
banner: code,
|
||||
}))
|
||||
|
|
|
@ -21,12 +21,12 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@avocado/core": "2.0.0",
|
||||
"@avocado/entity": "2.0.0",
|
||||
"@avocado/input": "2.0.0",
|
||||
"@avocado/math": "2.0.0",
|
||||
"@avocado/resource": "^2.0.0",
|
||||
"@avocado/resource": "2.0.0",
|
||||
"@avocado/traits": "^2.0.0",
|
||||
"@latus/core": "^2.0.0",
|
||||
"@latus/socket": "^2.0.0",
|
||||
"@latus/socket": "2.0.0",
|
||||
"@pixi/constants": "^5.3.6",
|
||||
"@pixi/core": "^5.3.6",
|
||||
"@pixi/display": "^5.3.6",
|
||||
|
@ -36,10 +36,12 @@
|
|||
"@pixi/settings": "^5.3.6",
|
||||
"@pixi/sprite": "^5.3.6",
|
||||
"@pixi/text": "^5.3.6",
|
||||
"debug": "4.3.1"
|
||||
"debug": "4.3.1",
|
||||
"image-size": "^0.9.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@neutrinojs/airbnb-base": "^9.4.0",
|
||||
"@neutrinojs/banner": "9.4.0",
|
||||
"@neutrinojs/copy": "9.4.0",
|
||||
"@neutrinojs/mocha": "^9.4.0",
|
||||
"@neutrinojs/react": "^9.4.0",
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import {Vector} from '@avocado/math';
|
||||
import {Class, compose} from '@avocado/core';
|
||||
import {RenderTexture} from '@pixi/core';
|
||||
import {Class, compose} from '@latus/core';
|
||||
|
||||
import Image from './image';
|
||||
|
||||
const {
|
||||
SIDE,
|
||||
} = process.env;
|
||||
|
||||
const decorate = compose(
|
||||
Vector.Mixin('size', 'width', 'height', {
|
||||
default: [0, 0],
|
||||
|
@ -14,11 +17,25 @@ export default class Canvas extends decorate(Class) {
|
|||
|
||||
constructor(size = [0, 0]) {
|
||||
super();
|
||||
this.renderTexture = RenderTexture.create(size[0], size[1]);
|
||||
if ('client' === SIDE) {
|
||||
// eslint-disable-next-line global-require
|
||||
const {RenderTexture} = require('@pixi/core');
|
||||
this.renderTexture = RenderTexture.create();
|
||||
}
|
||||
else {
|
||||
this.renderTexture = {
|
||||
height: 0,
|
||||
isFake: true,
|
||||
width: 0,
|
||||
};
|
||||
}
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.renderTexture.destroy();
|
||||
if (!this.renderTexture.isFake) {
|
||||
this.renderTexture.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
get internal() {
|
||||
|
@ -34,13 +51,20 @@ export default class Canvas extends decorate(Class) {
|
|||
}
|
||||
|
||||
set size(size) {
|
||||
this.renderTexture.resize(size[0], size[1]);
|
||||
if (this.renderTexture.isFake) {
|
||||
[this.renderTexture.width, this.renderTexture.height] = size;
|
||||
}
|
||||
else {
|
||||
this.renderTexture.resize(size[0], size[1]);
|
||||
}
|
||||
super.size = size;
|
||||
}
|
||||
|
||||
toImage() {
|
||||
const image = new Image();
|
||||
image.texture = this.renderTexture.clone();
|
||||
if (!this.renderTexture.isFake) {
|
||||
image.texture = this.renderTexture.clone();
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,34 @@
|
|||
import {Container as PIXIContainer} from '@pixi/display';
|
||||
import {AdvancedBloomFilter} from '@pixi/filter-advanced-bloom';
|
||||
import {ColorMatrixFilter} from '@pixi/filter-color-matrix';
|
||||
// import {AdvancedBloomFilter} from '@pixi/filter-advanced-bloom';
|
||||
// import {ColorMatrixFilter} from '@pixi/filter-color-matrix';
|
||||
|
||||
import Renderable from './renderable';
|
||||
|
||||
const {
|
||||
SIDE,
|
||||
} = process.env;
|
||||
|
||||
export default class Container extends Renderable {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._children = [];
|
||||
this._childrenIndexes = new Map();
|
||||
this.container = new PIXIContainer();
|
||||
if ('client' === SIDE) {
|
||||
// eslint-disable-next-line global-require
|
||||
const {Container: PIXIContainer} = require('@pixi/display');
|
||||
this.container = new PIXIContainer();
|
||||
}
|
||||
else {
|
||||
this.container = {
|
||||
isFake: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
addChild(child) {
|
||||
if (this.container.isFake) {
|
||||
return;
|
||||
}
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
child.parent = this;
|
||||
this.isDirty = true;
|
||||
|
@ -26,14 +41,16 @@ export default class Container extends Renderable {
|
|||
return this._children;
|
||||
}
|
||||
|
||||
desaturate() {
|
||||
const filter = new ColorMatrixFilter();
|
||||
filter.desaturate();
|
||||
this.container.filters = [filter];
|
||||
}
|
||||
// desaturate() {
|
||||
// const filter = new ColorMatrixFilter();
|
||||
// filter.desaturate();
|
||||
// this.container.filters = [filter];
|
||||
// }
|
||||
|
||||
destroy() {
|
||||
this.container.filters = [];
|
||||
if (!this.container.isFake) {
|
||||
this.container.filters = [];
|
||||
}
|
||||
this.children.forEach((child) => {
|
||||
this.removeChild(child);
|
||||
child.destroy();
|
||||
|
@ -45,40 +62,42 @@ export default class Container extends Renderable {
|
|||
return this.container;
|
||||
}
|
||||
|
||||
night(intensity = 1) {
|
||||
let filter;
|
||||
const {filters} = this.container;
|
||||
if (filters && filters.length > 0 && filters[0] instanceof ColorMatrixFilter) {
|
||||
[filter] = filters;
|
||||
}
|
||||
else {
|
||||
filter = new ColorMatrixFilter();
|
||||
}
|
||||
const nightness = 0.1;
|
||||
const double = nightness * 2;
|
||||
const half = nightness / 2;
|
||||
const redDown = 1 - (intensity * (1 + double));
|
||||
const blueUp = 1 - (intensity * (1 - half));
|
||||
const scale = intensity * nightness;
|
||||
const matrix = [
|
||||
redDown, -scale, 0, 0, 0,
|
||||
-scale, (1 - intensity), scale, 0, 0,
|
||||
0, scale, blueUp, 0, 0,
|
||||
0, 0, 0, 1, 0,
|
||||
];
|
||||
filter._loadMatrix(matrix);
|
||||
this.container.filters = [filter];
|
||||
}
|
||||
// night(intensity = 1) {
|
||||
// let filter;
|
||||
// const {filters} = this.container;
|
||||
// if (filters && filters.length > 0 && filters[0] instanceof ColorMatrixFilter) {
|
||||
// [filter] = filters;
|
||||
// }
|
||||
// else {
|
||||
// filter = new ColorMatrixFilter();
|
||||
// }
|
||||
// const nightness = 0.1;
|
||||
// const double = nightness * 2;
|
||||
// const half = nightness / 2;
|
||||
// const redDown = 1 - (intensity * (1 + double));
|
||||
// const blueUp = 1 - (intensity * (1 - half));
|
||||
// const scale = intensity * nightness;
|
||||
// const matrix = [
|
||||
// redDown, -scale, 0, 0, 0,
|
||||
// -scale, (1 - intensity), scale, 0, 0,
|
||||
// 0, scale, blueUp, 0, 0,
|
||||
// 0, 0, 0, 1, 0,
|
||||
// ];
|
||||
// filter._loadMatrix(matrix);
|
||||
// this.container.filters = [filter];
|
||||
// }
|
||||
|
||||
paused(intensity = 1) {
|
||||
const filter = new ColorMatrixFilter();
|
||||
filter.sepia();
|
||||
filter.brightness(1 - intensity, true);
|
||||
this.container.filters = [filter];
|
||||
}
|
||||
// paused(intensity = 1) {
|
||||
// const filter = new ColorMatrixFilter();
|
||||
// filter.sepia();
|
||||
// filter.brightness(1 - intensity, true);
|
||||
// this.container.filters = [filter];
|
||||
// }
|
||||
|
||||
removeAllFilters() {
|
||||
this.container.filters = [];
|
||||
if (!this.container.isFake) {
|
||||
this.container.filters = [];
|
||||
}
|
||||
}
|
||||
|
||||
_removeChild(child) {
|
||||
|
@ -87,7 +106,9 @@ export default class Container extends Renderable {
|
|||
return;
|
||||
}
|
||||
this._children.splice(index, 1);
|
||||
this.container.removeChild(child.internal);
|
||||
if (!this.container.isFake) {
|
||||
this.container.removeChild(child.internal);
|
||||
}
|
||||
}
|
||||
|
||||
removeChild(child) {
|
||||
|
@ -130,7 +151,9 @@ export default class Container extends Renderable {
|
|||
const rIndex = this._childrenIndexes.get(r);
|
||||
return lIndex - rIndex;
|
||||
});
|
||||
this.container.children = this._children.map((child) => child.internal);
|
||||
if (!this.container.isFake) {
|
||||
this.container.children = this._children.map((child) => child.internal);
|
||||
}
|
||||
this._resetChildrenIndexes();
|
||||
}
|
||||
|
||||
|
@ -141,27 +164,27 @@ export default class Container extends Renderable {
|
|||
}
|
||||
}
|
||||
|
||||
sepia() {
|
||||
const filter = new ColorMatrixFilter();
|
||||
filter.sepia();
|
||||
this.container.filters = [filter];
|
||||
}
|
||||
// sepia() {
|
||||
// const filter = new ColorMatrixFilter();
|
||||
// filter.sepia();
|
||||
// this.container.filters = [filter];
|
||||
// }
|
||||
|
||||
setFilter(filter) {
|
||||
switch (filter) {
|
||||
case 'bloom':
|
||||
this.container.filters = [
|
||||
new AdvancedBloomFilter({
|
||||
threshold: 0.5,
|
||||
bloomScale: 0.8,
|
||||
brightness: 0.7,
|
||||
blur: 2,
|
||||
quality: 6,
|
||||
}),
|
||||
];
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
// setFilter(filter) {
|
||||
// switch (filter) {
|
||||
// case 'bloom':
|
||||
// this.container.filters = [
|
||||
// new AdvancedBloomFilter({
|
||||
// threshold: 0.5,
|
||||
// bloomScale: 0.8,
|
||||
// brightness: 0.7,
|
||||
// blur: 2,
|
||||
// quality: 6,
|
||||
// }),
|
||||
// ];
|
||||
// break;
|
||||
// default:
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
|
@ -1,60 +1,46 @@
|
|||
import {BaseTexture, Texture} from '@pixi/core';
|
||||
import {SCALE_MODES} from '@pixi/constants';
|
||||
|
||||
import {Resource} from '@avocado/resource';
|
||||
|
||||
const {
|
||||
SIDE,
|
||||
} = process.env;
|
||||
|
||||
export default class Image extends Resource {
|
||||
|
||||
constructor() {
|
||||
constructor(buffer) {
|
||||
super();
|
||||
this.texture = null;
|
||||
if (buffer) {
|
||||
if ('client' === SIDE) {
|
||||
// eslint-disable-next-line global-require
|
||||
const {Texture} = require('@pixi/core');
|
||||
this.texture = Texture.fromBuffer(buffer);
|
||||
}
|
||||
else {
|
||||
// eslint-disable-next-line global-require
|
||||
const imageSize = require('image-size');
|
||||
const {height, width} = imageSize(buffer);
|
||||
this.texture = {
|
||||
height,
|
||||
isFake: true,
|
||||
width,
|
||||
};
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.texture = {
|
||||
height: 0,
|
||||
isFake: true,
|
||||
width: 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.texture.destroy();
|
||||
}
|
||||
|
||||
static fromHtmlCanvas(htmlCanvas) {
|
||||
const baseTexture = BaseTexture.from(
|
||||
htmlCanvas,
|
||||
SCALE_MODES.NEAREST,
|
||||
);
|
||||
const image = new Image();
|
||||
image.texture = new Texture(baseTexture);
|
||||
return image;
|
||||
}
|
||||
|
||||
static load(uri) {
|
||||
return this.loadBaseTexture(uri).then((baseTexture) => {
|
||||
const image = new Image();
|
||||
image.uri = uri;
|
||||
image.texture = new Texture(baseTexture);
|
||||
return image;
|
||||
});
|
||||
}
|
||||
|
||||
static loadBaseTexture(uri) {
|
||||
if (!this.baseTextureCache) {
|
||||
this.baseTextureCache = {};
|
||||
if (!this.texture.isFake) {
|
||||
this.texture.destroy();
|
||||
}
|
||||
if (this.baseTextureCache[uri]) {
|
||||
return Promise.resolve(this.baseTextureCache[uri]);
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
const baseTexture = BaseTexture.from(uri);
|
||||
baseTexture.once('error', () => {
|
||||
reject(new Error(`Couldn't load image "${uri}"`));
|
||||
});
|
||||
baseTexture.once('loaded', () => {
|
||||
resolve(this.baseTextureCache[uri] = baseTexture);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
get height() {
|
||||
if (!this.texture) {
|
||||
return 0;
|
||||
}
|
||||
return this.texture.height;
|
||||
}
|
||||
|
||||
|
@ -63,27 +49,25 @@ export default class Image extends Resource {
|
|||
}
|
||||
|
||||
subimage(rectangle) {
|
||||
const frame = {
|
||||
x: rectangle[0],
|
||||
y: rectangle[1],
|
||||
width: rectangle[2],
|
||||
height: rectangle[3],
|
||||
};
|
||||
const subimage = new Image();
|
||||
subimage.texture = new Texture(this.texture, frame);
|
||||
if (this.texture.isFake) {
|
||||
[, , subimage.texture.width, subimage.texture.height] = rectangle;
|
||||
}
|
||||
else {
|
||||
const frame = {
|
||||
x: rectangle[0],
|
||||
y: rectangle[1],
|
||||
width: rectangle[2],
|
||||
height: rectangle[3],
|
||||
};
|
||||
// eslint-disable-next-line global-require
|
||||
const {Texture} = require('@pixi/core');
|
||||
subimage.texture = new Texture(this.texture, frame);
|
||||
}
|
||||
return subimage;
|
||||
}
|
||||
|
||||
updateBaseTexture() {
|
||||
if (this.texture && this.texture.baseTexture) {
|
||||
this.texture.baseTexture.update();
|
||||
}
|
||||
}
|
||||
|
||||
get width() {
|
||||
if (!this.texture) {
|
||||
return 0;
|
||||
}
|
||||
return this.texture.width;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import {SCALE_MODES} from '@pixi/constants';
|
||||
import {Renderer, BatchRenderer} from '@pixi/core';
|
||||
import {settings} from '@pixi/settings';
|
||||
import packets from './packets';
|
||||
import traits from './traits';
|
||||
|
||||
const {
|
||||
SIDE,
|
||||
} = process.env;
|
||||
|
||||
export {default as Canvas} from './canvas';
|
||||
export {default as Color} from './color';
|
||||
|
@ -12,7 +15,23 @@ export {default as Renderer} from './renderer';
|
|||
export {default as Sprite} from './sprite';
|
||||
export {default as Stage} from './stage';
|
||||
export {default as Text} from './text';
|
||||
// Pixelly!
|
||||
settings.SCALE_MODE = SCALE_MODES.NEAREST;
|
||||
// Lil pixi management.
|
||||
Renderer.registerPlugin('batch', BatchRenderer);
|
||||
|
||||
if ('client' === SIDE) {
|
||||
const [
|
||||
{SCALE_MODES}, {Renderer, BatchRenderer}, {settings},
|
||||
] = [
|
||||
// eslint-disable-next-line global-require
|
||||
require('@pixi/constants'), require('@pixi/core'), require('@pixi/settings'),
|
||||
];
|
||||
// Pixelly!
|
||||
settings.SCALE_MODE = SCALE_MODES.NEAREST;
|
||||
// Lil pixi management.
|
||||
Renderer.registerPlugin('batch', BatchRenderer);
|
||||
}
|
||||
|
||||
export default {
|
||||
hooks: {
|
||||
'@avocado/traits': traits,
|
||||
'@latus/socket/packets': packets,
|
||||
},
|
||||
};
|
||||
|
|
5
packages/graphics/src/packets/index.js
Normal file
5
packages/graphics/src/packets/index.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
import TraitUpdateVisible from './trait-update-visible';
|
||||
|
||||
export default () => ({
|
||||
TraitUpdateVisible,
|
||||
});
|
|
@ -1,7 +1,9 @@
|
|||
import {Graphics} from '@pixi/graphics';
|
||||
|
||||
import Renderable from './renderable';
|
||||
|
||||
const {
|
||||
SIDE,
|
||||
} = process.env;
|
||||
|
||||
export default class Primitives extends Renderable {
|
||||
|
||||
static fillStyle(color) {
|
||||
|
@ -14,35 +16,52 @@ export default class Primitives extends Renderable {
|
|||
|
||||
constructor() {
|
||||
super();
|
||||
this.primitives = new Graphics();
|
||||
if ('client' === SIDE) {
|
||||
// eslint-disable-next-line global-require
|
||||
const {Graphics} = require('@pixi/graphics');
|
||||
this.primitives = new Graphics();
|
||||
}
|
||||
else {
|
||||
this.primitives = {
|
||||
isFake: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.primitives.clear();
|
||||
if (!this.primitives.isFake) {
|
||||
this.primitives.clear();
|
||||
}
|
||||
}
|
||||
|
||||
drawCircle(position, radius, lineStyle, fillStyle) {
|
||||
this._wrapStyle('drawCircle', '3rd', lineStyle, fillStyle, () => {
|
||||
this.primitives.drawCircle(position[0], position[1], radius);
|
||||
});
|
||||
if (!this.primitives.isFake) {
|
||||
this._wrapStyle('drawCircle', '3rd', lineStyle, fillStyle, () => {
|
||||
this.primitives.drawCircle(position[0], position[1], radius);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
drawLine(p1, p2, lineStyle, fillStyle) {
|
||||
this._wrapStyle('drawLine', '3rd', lineStyle, fillStyle, () => {
|
||||
this.primitives.moveTo(p1[0], p1[1]);
|
||||
this.primitives.lineTo(p2[0], p2[1]);
|
||||
});
|
||||
if (!this.primitives.isFake) {
|
||||
this._wrapStyle('drawLine', '3rd', lineStyle, fillStyle, () => {
|
||||
this.primitives.moveTo(p1[0], p1[1]);
|
||||
this.primitives.lineTo(p2[0], p2[1]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
drawRectangle(rectangle, lineStyle, fillStyle) {
|
||||
this._wrapStyle('drawLine', '2nd', lineStyle, fillStyle, () => {
|
||||
this.primitives.drawRect(
|
||||
rectangle[0],
|
||||
rectangle[1],
|
||||
rectangle[2],
|
||||
rectangle[3],
|
||||
);
|
||||
});
|
||||
if (!this.primitives.isFake) {
|
||||
this._wrapStyle('drawLine', '2nd', lineStyle, fillStyle, () => {
|
||||
this.primitives.drawRect(
|
||||
rectangle[0],
|
||||
rectangle[1],
|
||||
rectangle[2],
|
||||
rectangle[3],
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
get internal() {
|
||||
|
|
|
@ -1,9 +1,22 @@
|
|||
import {Renderer as PIXIRenderer} from '@pixi/core';
|
||||
const {
|
||||
SIDE,
|
||||
} = process.env;
|
||||
|
||||
export default class Renderer {
|
||||
|
||||
constructor(size = [0, 0]) {
|
||||
this.renderer = new PIXIRenderer({width: size[0], height: size[1]});
|
||||
if ('client' === SIDE) {
|
||||
// eslint-disable-next-line global-require
|
||||
const {Renderer: PIXIRenderer} = require('@pixi/core');
|
||||
this.renderer = new PIXIRenderer({width: size[0], height: size[1]});
|
||||
}
|
||||
else {
|
||||
this.renderer = {
|
||||
height: 0,
|
||||
isFake: true,
|
||||
width: 0,
|
||||
};
|
||||
}
|
||||
[this.renderer.view.width, this.renderer.view.height] = size;
|
||||
}
|
||||
|
||||
|
@ -12,16 +25,18 @@ export default class Renderer {
|
|||
}
|
||||
|
||||
get element() {
|
||||
return this.renderer.view;
|
||||
return this.renderer.isFake ? undefined : this.renderer.view;
|
||||
}
|
||||
|
||||
get height() {
|
||||
return this.element.height;
|
||||
return this.renderer.isFake ? 0 : this.element.height;
|
||||
}
|
||||
|
||||
render(item, canvas) {
|
||||
const canvasInternal = canvas ? canvas.internal : undefined;
|
||||
this.renderer.render(item.internal, canvasInternal);
|
||||
if (!this.renderer.isFake) {
|
||||
const canvasInternal = canvas ? canvas.internal : undefined;
|
||||
this.renderer.render(item.internal, canvasInternal);
|
||||
}
|
||||
}
|
||||
|
||||
get size() {
|
||||
|
@ -29,7 +44,7 @@ export default class Renderer {
|
|||
}
|
||||
|
||||
get width() {
|
||||
return this.element.width;
|
||||
return this.renderer.isFake ? 0 : this.element.width;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,13 +1,24 @@
|
|||
import {Sprite as PIXISprite} from '@pixi/sprite';
|
||||
|
||||
import Renderable from './renderable';
|
||||
|
||||
const {
|
||||
SIDE,
|
||||
} = process.env;
|
||||
|
||||
export default class Sprite extends Renderable {
|
||||
|
||||
constructor(image) {
|
||||
super();
|
||||
this._image = image;
|
||||
this.sprite = new PIXISprite(image.texture);
|
||||
if ('client' === SIDE) {
|
||||
// eslint-disable-next-line global-require
|
||||
const {Sprite: PIXISprite} = require('@pixi/sprite');
|
||||
this.sprite = new PIXISprite(image.texture);
|
||||
}
|
||||
else {
|
||||
this.sprite = {
|
||||
isFake: true,
|
||||
};
|
||||
}
|
||||
this.anchor = [0.5, 0.5];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import {compose, Property} from '@avocado/core';
|
||||
import {Property} from '@avocado/core';
|
||||
import {InputNormalizer} from '@avocado/input';
|
||||
import {Vector} from '@avocado/math';
|
||||
import {compose} from '@latus/core';
|
||||
|
||||
import Container from './container';
|
||||
import Renderer from './renderer';
|
||||
|
|
|
@ -1,12 +1,23 @@
|
|||
import {Text as PIXIText} from '@pixi/text';
|
||||
|
||||
import Renderable from './renderable';
|
||||
|
||||
const {
|
||||
SIDE,
|
||||
} = process.env;
|
||||
|
||||
export default class Text extends Renderable {
|
||||
|
||||
constructor(text, style) {
|
||||
super();
|
||||
this.text = new PIXIText(text, style);
|
||||
if ('client' === SIDE) {
|
||||
// eslint-disable-next-line global-require
|
||||
const {Text: PIXIText} = require('@pixi/text');
|
||||
this.text = new PIXIText(text, style);
|
||||
}
|
||||
else {
|
||||
this.text = {
|
||||
isFake: true,
|
||||
};
|
||||
}
|
||||
this.anchor = [0.5, 0.5];
|
||||
}
|
||||
|
||||
|
|
13
packages/graphics/src/traits/index.js
Normal file
13
packages/graphics/src/traits/index.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import Pictured from './pictured';
|
||||
import Primitive from './primitive';
|
||||
import Staged from './staged';
|
||||
import Textual from './textual';
|
||||
import Visible from './visible';
|
||||
|
||||
export default () => ({
|
||||
Pictured,
|
||||
Primitive,
|
||||
Staged,
|
||||
Textual,
|
||||
Visible,
|
||||
});
|
|
@ -1,4 +1,4 @@
|
|||
import {StateProperty, Trait} from '@avocado/entity';
|
||||
import {StateProperty, Trait} from '@avocado/traits';
|
||||
import {Rectangle, Vector} from '@avocado/math';
|
||||
import {compose} from '@latus/core';
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Trait} from '@avocado/entity';
|
||||
import {Trait} from '@avocado/traits';
|
||||
|
||||
import Color from '../color';
|
||||
import Primitives from '../primitives';
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {compose, Property} from '@avocado/core';
|
||||
import {Trait} from '@avocado/entity';
|
||||
import {Property} from '@avocado/core';
|
||||
import {Trait} from '@avocado/traits';
|
||||
import {compose} from '@latus/core';
|
||||
|
||||
const decorate = compose(
|
||||
Property('stage', {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {compose} from '@avocado/core';
|
||||
import {StateProperty, Trait} from '@avocado/entity';
|
||||
import {StateProperty, Trait} from '@avocado/traits';
|
||||
import {compose} from '@latus/core';
|
||||
|
||||
import Text from '../text';
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {compose} from '@avocado/core';
|
||||
import {StateProperty, Trait} from '@avocado/entity';
|
||||
import {StateProperty, Trait} from '@avocado/traits';
|
||||
import {Rectangle} from '@avocado/math';
|
||||
import {compose} from '@latus/core';
|
||||
|
||||
import Container from '../container';
|
||||
|
||||
|
|
BIN
packages/graphics/test/fixtures/test.png
vendored
Normal file
BIN
packages/graphics/test/fixtures/test.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 207 B |
|
@ -2,18 +2,6 @@
|
|||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@avocado/behavior@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fbehavior/-/behavior-2.0.0.tgz#6478ca2f16957c3a010f792e013f4688583bf033"
|
||||
integrity sha512-psHGbLG/EVaY6/9FwCvnNYA7LLXYVUQUiDbXZAyhkPNV5dAEmcQX8LdYUxDJ2Q32upow15+t8Np8u0XHcOHc4g==
|
||||
dependencies:
|
||||
"@avocado/core" "^2.0.0"
|
||||
"@avocado/entity" "2.0.0"
|
||||
"@latus/core" "^2.0.0"
|
||||
debug "4.3.1"
|
||||
deepmerge "^4.2.2"
|
||||
lodash.mapvalues "^4.6.0"
|
||||
|
||||
"@avocado/core@2.0.0", "@avocado/core@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fcore/-/core-2.0.0.tgz#636ea3c3b54a38538c59485080f6a0e48f1798e7"
|
||||
|
@ -21,45 +9,6 @@
|
|||
dependencies:
|
||||
debug "4.3.1"
|
||||
|
||||
"@avocado/entity@2.0.0", "@avocado/entity@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fentity/-/entity-2.0.0.tgz#30339ca125508848056d158817f7f02ab12384e6"
|
||||
integrity sha512-XE+pYl9C6SrknSrOM7Lge0scG3O5v26OjO6mjcnandl66BkPKHKQveJBAEhEf4Gx5hlPObkDiY+QMJ4YzRBHcQ==
|
||||
dependencies:
|
||||
"@avocado/behavior" "^2.0.0"
|
||||
"@avocado/core" "2.0.0"
|
||||
"@avocado/math" "2.0.0"
|
||||
"@avocado/resource" "2.0.0"
|
||||
"@avocado/s13n" "^2.0.0"
|
||||
"@avocado/timing" "^2.0.0"
|
||||
"@latus/core" "^2.0.0"
|
||||
"@latus/socket" "^2.0.0"
|
||||
debug "4.3.1"
|
||||
deepmerge "^4.2.2"
|
||||
lodash.without "^4.4.0"
|
||||
|
||||
"@avocado/graphics@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fgraphics/-/graphics-2.0.0.tgz#7a136ed9448be44eeec291cb546c847e04d3cf92"
|
||||
integrity sha512-yfgug627SeIMrTqxWDZOEuu6J9/nRzyPWoOaIvqFvtlzvBf6C+mlfdhcc5FW2J/9g2LbLvk4XYN4OINBd50DsA==
|
||||
dependencies:
|
||||
"@avocado/core" "2.0.0"
|
||||
"@avocado/input" "2.0.0"
|
||||
"@avocado/math" "2.0.0"
|
||||
"@avocado/resource" "^2.0.0"
|
||||
"@latus/core" "^2.0.0"
|
||||
"@latus/socket" "^2.0.0"
|
||||
"@pixi/constants" "^5.3.6"
|
||||
"@pixi/core" "^5.3.6"
|
||||
"@pixi/display" "^5.3.6"
|
||||
"@pixi/filter-advanced-bloom" "^3.2.0"
|
||||
"@pixi/filter-color-matrix" "^5.3.6"
|
||||
"@pixi/graphics" "^5.3.6"
|
||||
"@pixi/settings" "^5.3.6"
|
||||
"@pixi/sprite" "^5.3.6"
|
||||
"@pixi/text" "^5.3.6"
|
||||
debug "4.3.1"
|
||||
|
||||
"@avocado/input@2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2finput/-/input-2.0.0.tgz#fd6c9eb436416a008f5502cf6bba3f9277256021"
|
||||
|
@ -69,7 +18,7 @@
|
|||
"@latus/socket" "^2.0.0"
|
||||
debug "4.3.1"
|
||||
|
||||
"@avocado/math@2.0.0", "@avocado/math@^2.0.0":
|
||||
"@avocado/math@2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fmath/-/math-2.0.0.tgz#8c1a04a08a1085c646029c21e7e49798227bee35"
|
||||
integrity sha512-SvF3pEYkg6L082ydxHNS/TMOrdC1d55fiYIsocX7y8ym7ySO2lH2pzoOo4/1AndQjkU5zpw3ENAm+FCDT0goug==
|
||||
|
@ -78,10 +27,10 @@
|
|||
d3-quadtree "^2.0.0"
|
||||
debug "4.3.1"
|
||||
|
||||
"@avocado/resource@2.0.0", "@avocado/resource@^2.0.0":
|
||||
"@avocado/resource@2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fresource/-/resource-2.0.0.tgz#a7b594584c172cff472d9a298bcd9d62c27186f2"
|
||||
integrity sha512-q7MacbQl1ozA5Z3ZOKyUcMRBJAhly19dCtrNxYCki7mXIe1DoP0VvipFIgMlquLhkmtxxT2uMzVvHeJxhDxsgw==
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fresource/-/resource-2.0.0.tgz#2eb014c2c876f3f51bc71d6594d93091b22013c8"
|
||||
integrity sha512-3dks0rsuY1twlLm+vTrsqfV9anXR/0ZdQfe2YAJIdmiVQ7QEB2mQhUgMvqjgsuhI7ad1ygxD/I9hXBjl6CvyjA==
|
||||
dependencies:
|
||||
"@avocado/core" "^2.0.0"
|
||||
"@latus/core" "^2.0.0"
|
||||
|
@ -99,18 +48,14 @@
|
|||
debug "4.3.1"
|
||||
msgpack-lite "^0.1.26"
|
||||
|
||||
"@avocado/timing@^2.0.0":
|
||||
"@avocado/traits@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2ftiming/-/timing-2.0.0.tgz#de76571519cb835a7f45528e91bdb9a18f1947fa"
|
||||
integrity sha512-pJITg7q3kX9H2XEFP+jHPMiY317o4rCb/zzBdUbqC1RY5z5Et/LeTkQa/pd4IPqXeUK9omW4eM24jdCp8uH1tg==
|
||||
resolved "http://172.18.0.8:4873/@avocado%2ftraits/-/traits-2.0.0.tgz#4717919e101a4fa81469bc5efe7c5478bb293a4e"
|
||||
integrity sha512-7siD4XME3NzhTholUPndRYloHowV8z/s+FnzqG7p2/idNHrXURXsVBeYBI9lcM0SX1ONY+9OVdH0ykiu5qBScg==
|
||||
dependencies:
|
||||
"@avocado/core" "^2.0.0"
|
||||
"@avocado/entity" "^2.0.0"
|
||||
"@avocado/graphics" "^2.0.0"
|
||||
"@avocado/math" "^2.0.0"
|
||||
"@avocado/resource" "^2.0.0"
|
||||
"@avocado/s13n" "^2.0.0"
|
||||
"@latus/core" "^2.0.0"
|
||||
"@latus/socket" "^2.0.0"
|
||||
debug "4.3.1"
|
||||
|
||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.11":
|
||||
|
@ -1031,7 +976,7 @@
|
|||
webpack-hot-middleware "^2.25.0"
|
||||
webpack-virtual-modules "^0.4.1"
|
||||
|
||||
"@latus/socket@^2.0.0":
|
||||
"@latus/socket@2.0.0", "@latus/socket@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@latus%2fsocket/-/socket-2.0.0.tgz#2a35bba0db3542ab18a913320f7f6d24228ab5f1"
|
||||
integrity sha512-qAWV/+3GI/GNyu/Ls6EFZpZr+2Q288YtgyjOzCNm6nRwy9N+JGJs1Y7yhJlLuao0K5EzHuYif3Vpo4DeRIVqNw==
|
||||
|
@ -1054,6 +999,11 @@
|
|||
eslint-config-airbnb-base "^14.2.1"
|
||||
eslint-plugin-import "^2.22.1"
|
||||
|
||||
"@neutrinojs/banner@9.4.0":
|
||||
version "9.4.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@neutrinojs%2fbanner/-/banner-9.4.0.tgz#897308ba73bf530f9f0eaa412a8f7596d76249e9"
|
||||
integrity sha512-ZpAmGbpexGEwoHQV2B4lbK2cCUcCR5ImF9mxs3Bs6wXgRJLI9nCzxp/eBGgl1hhv5Zwi8AwdUGfP1Uno/HlZcw==
|
||||
|
||||
"@neutrinojs/clean@9.5.0":
|
||||
version "9.5.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@neutrinojs%2fclean/-/clean-9.5.0.tgz#77cfb0add1584741c7501f5e12ad206b67f216bf"
|
||||
|
@ -1174,31 +1124,31 @@
|
|||
babel-merge "^3.0.0"
|
||||
deepmerge "^1.5.2"
|
||||
|
||||
"@pixi/constants@5.3.6", "@pixi/constants@^5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fconstants/-/constants-5.3.6.tgz#b3b61b5d5047d022df3b8bed82eeb2b052457ded"
|
||||
integrity sha512-4FF6GIj88/rddqMJeVlbxKUDgSpb6vSX9yWR1S17Urn4B3RCZErlfSEcTIuSOpLbs0F1h9K7UdIrzbJp2aefzw==
|
||||
"@pixi/constants@5.3.7", "@pixi/constants@^5.3.6":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fconstants/-/constants-5.3.7.tgz#a2e1789a98deb3713cfcb3eba3db84588bc9161e"
|
||||
integrity sha512-MBcgIM/mSqonFezkCI9080IqNlc0wb8S9QJ5otBdseOWUQa/ua2jF7Jd1sCBGmi0IzS9/NOHFXzZVTdS7AC7Ow==
|
||||
|
||||
"@pixi/core@5.3.6", "@pixi/core@^5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fcore/-/core-5.3.6.tgz#85559a71fd35c459c094ff30899f85cbcf8d2f81"
|
||||
integrity sha512-Q5myUdcaJH5dtWbxerLn6YSFR3AjIgk58o7x7CzymJ7U5kdBjNB0yNdMVSbDQpf+lK4edtWYpuelot7SAthk+g==
|
||||
"@pixi/core@5.3.7", "@pixi/core@^5.3.6":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fcore/-/core-5.3.7.tgz#a8d65ca17f0c4ef8c0c5a22d31b9e02a4ab73b93"
|
||||
integrity sha512-WBhU2f5aJSVVaFP55FFBFKjKlRf5fYGxgA/U3kD4yD4Y3d3d6V3MIZv+o0VX+kBs1Eq7ePZqEv2smDrlzzMEjQ==
|
||||
dependencies:
|
||||
"@pixi/constants" "5.3.6"
|
||||
"@pixi/math" "5.3.6"
|
||||
"@pixi/runner" "5.3.6"
|
||||
"@pixi/settings" "5.3.6"
|
||||
"@pixi/ticker" "5.3.6"
|
||||
"@pixi/utils" "5.3.6"
|
||||
"@pixi/constants" "5.3.7"
|
||||
"@pixi/math" "5.3.7"
|
||||
"@pixi/runner" "5.3.7"
|
||||
"@pixi/settings" "5.3.7"
|
||||
"@pixi/ticker" "5.3.7"
|
||||
"@pixi/utils" "5.3.7"
|
||||
|
||||
"@pixi/display@5.3.6", "@pixi/display@^5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fdisplay/-/display-5.3.6.tgz#90a629c4d9b7a118b7b8cc0ea4b843d1b93026f3"
|
||||
integrity sha512-cbUaWz2R2vNO5BD9Ic6hYyazQQV8ndQfPonbBcehQQhNC+aZjuYgarHqiUb4Z7/GKkRQzB9WyoT8P5V5LppufQ==
|
||||
"@pixi/display@5.3.7", "@pixi/display@^5.3.6":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fdisplay/-/display-5.3.7.tgz#b661d2ecfd2a67f213665a0698acd29e17eee8fe"
|
||||
integrity sha512-ma1JyLe5vaEgmaOR+anvj5YOKqT9OEWnboIe7NVmwGF1CZ7JFnB12rsRulHUsSaFG9bP5xjvroAZjFg/WvyGLw==
|
||||
dependencies:
|
||||
"@pixi/math" "5.3.6"
|
||||
"@pixi/settings" "5.3.6"
|
||||
"@pixi/utils" "5.3.6"
|
||||
"@pixi/math" "5.3.7"
|
||||
"@pixi/settings" "5.3.7"
|
||||
"@pixi/utils" "5.3.7"
|
||||
|
||||
"@pixi/filter-advanced-bloom@^3.2.0":
|
||||
version "3.2.0"
|
||||
|
@ -1208,11 +1158,11 @@
|
|||
"@pixi/filter-kawase-blur" "3.2.0"
|
||||
|
||||
"@pixi/filter-color-matrix@^5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2ffilter-color-matrix/-/filter-color-matrix-5.3.6.tgz#466f563e20721900b202a87c8d47a5ea8e31c741"
|
||||
integrity sha512-u/OZEPhdMT2rzCNZZXBsIwVyp79X4rM029JMioJdYrFEPDnAuDIBKrY5//gOHFdQlYsjRIaW0IcykCPqUvBs3A==
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2ffilter-color-matrix/-/filter-color-matrix-5.3.7.tgz#230cafe46bde36e25441b13f3ac5dd8e8fee4311"
|
||||
integrity sha512-Z12cxoHx9uMh3CZ0PLVRzsaFHHF/CfU3J83KI9k+Bg/DFOh/J/5EToCd44jYJbMKp3nvXcO1EJyZ3wwC/IsyfQ==
|
||||
dependencies:
|
||||
"@pixi/core" "5.3.6"
|
||||
"@pixi/core" "5.3.7"
|
||||
|
||||
"@pixi/filter-kawase-blur@3.2.0":
|
||||
version "3.2.0"
|
||||
|
@ -1220,71 +1170,71 @@
|
|||
integrity sha512-IO1UKn/XLvnV+ya4r1UOC9fTfXZjWvH9m6eQ/U+moBsQN5I5FihQfXCu586X4jb9VHNu3gFl7SUzirobhBfgtA==
|
||||
|
||||
"@pixi/graphics@^5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fgraphics/-/graphics-5.3.6.tgz#1d38359926d174cccd3219936285140b715344e7"
|
||||
integrity sha512-FDZlAkxrbCZTjzNMWW6q6N/GAfyfftwHOGb67oLJ+NCG2wagOGUPQYRRGBK5f45dgDdM+1is7UwbhdQ8Rvg9ig==
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fgraphics/-/graphics-5.3.7.tgz#36ae80e2508e0a9c61ce454807d517d370d90a74"
|
||||
integrity sha512-+6+bT/AC29a1Hw5XDxsH1UqBsXSqcna7wNTTrBQ02owotIJtyRc6w48f5qxzhxycumyVCR87IV5tAtdwX3xhag==
|
||||
dependencies:
|
||||
"@pixi/constants" "5.3.6"
|
||||
"@pixi/core" "5.3.6"
|
||||
"@pixi/display" "5.3.6"
|
||||
"@pixi/math" "5.3.6"
|
||||
"@pixi/sprite" "5.3.6"
|
||||
"@pixi/utils" "5.3.6"
|
||||
"@pixi/constants" "5.3.7"
|
||||
"@pixi/core" "5.3.7"
|
||||
"@pixi/display" "5.3.7"
|
||||
"@pixi/math" "5.3.7"
|
||||
"@pixi/sprite" "5.3.7"
|
||||
"@pixi/utils" "5.3.7"
|
||||
|
||||
"@pixi/math@5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fmath/-/math-5.3.6.tgz#3933bae1a0af912b4384389b63ceffdcf108723a"
|
||||
integrity sha512-ccW/LrSsLaHunj1ztfp2UpxKGftiaK/nURZa51CFhbGYQBrYZBk27x1fgwGAs4ualTtqZOeyaLhv4nY0ljm5Qw==
|
||||
"@pixi/math@5.3.7":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fmath/-/math-5.3.7.tgz#066e7ea149fd38db8d8a9584aac5f41d02b36bdd"
|
||||
integrity sha512-WnjUwX7rkxR36F0xknpsNd9BsfQosV0BbyFE0Il88IURBM3Tu9X4tC7RGJDgWU+aXw23HgHu0j+MWJrCVCM2fA==
|
||||
|
||||
"@pixi/runner@5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2frunner/-/runner-5.3.6.tgz#b123f1a674aa249e4067ff00f9a3027d01ac69a8"
|
||||
integrity sha512-qiGoMVk0P0p3IfH5LTIH/dKyiNUzIHMxoykPODWni648hFa4CEFpG3bHJorcyYvmALCFgHjH2hhrqQexK3T6Kw==
|
||||
"@pixi/runner@5.3.7":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2frunner/-/runner-5.3.7.tgz#78ed2c92b392b8c099d2e4557dded7faa921446b"
|
||||
integrity sha512-kt5apNb21HAvpBaDaPRs33k2O0VzrKe13w4we8iftCpXX8w68ErAY1lH68vmtDNrxnlHg4M9nRgEoMeiHlo2RA==
|
||||
|
||||
"@pixi/settings@5.3.6", "@pixi/settings@^5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fsettings/-/settings-5.3.6.tgz#d138ba2180557174c3f942fc9656de35f1a77026"
|
||||
integrity sha512-hWMC1KwB2InFoJPdnI97ckHX0Z7912aaB2oQUJwKv0hhSrc8vxq9Dg6UofVY+wGMHDVCvqJPnvCsTYuKUmwRxw==
|
||||
"@pixi/settings@5.3.7", "@pixi/settings@^5.3.6":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fsettings/-/settings-5.3.7.tgz#b661883231bf2a1ff5260c214bd0c4b438759841"
|
||||
integrity sha512-g6AoRSGWxU34gtKSQwX2AMQoLUv86L/5iIXRsqo+X4bfUSCenTci1X7ueVrSIbo39dxh6IOpriZF2Yk3TeHG5w==
|
||||
dependencies:
|
||||
ismobilejs "^1.1.0"
|
||||
|
||||
"@pixi/sprite@5.3.6", "@pixi/sprite@^5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fsprite/-/sprite-5.3.6.tgz#04c13b0ce1c7379a2f570d28db58d1f54ce44c55"
|
||||
integrity sha512-Q5nRj7mhWuVHvn2rMtlf+6CdTjdovxX0R9ANffPcY7EODn5m7F4GpXEwBOjDICtVyHXrXhz2k4Gi2XWPFeeZ7A==
|
||||
"@pixi/sprite@5.3.7", "@pixi/sprite@^5.3.6":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fsprite/-/sprite-5.3.7.tgz#c6edf3d4a9928868696b62e35a60ded27d167058"
|
||||
integrity sha512-Bjl+NOOvigEzUsm1cDr1KmBUpPSWO8pDXpUPTi+v2N75gwRfTycmj5f2TU0QmMW3Gc6sv0CB0AkL7dkMPwPb8g==
|
||||
dependencies:
|
||||
"@pixi/constants" "5.3.6"
|
||||
"@pixi/core" "5.3.6"
|
||||
"@pixi/display" "5.3.6"
|
||||
"@pixi/math" "5.3.6"
|
||||
"@pixi/settings" "5.3.6"
|
||||
"@pixi/utils" "5.3.6"
|
||||
"@pixi/constants" "5.3.7"
|
||||
"@pixi/core" "5.3.7"
|
||||
"@pixi/display" "5.3.7"
|
||||
"@pixi/math" "5.3.7"
|
||||
"@pixi/settings" "5.3.7"
|
||||
"@pixi/utils" "5.3.7"
|
||||
|
||||
"@pixi/text@^5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2ftext/-/text-5.3.6.tgz#55b45c8968a28304f5b7aef289e6f062772a060a"
|
||||
integrity sha512-maEZoIysPOuzzSH+TN2cGnqDDMdTVtFNY9dJdKgmMleY9oCPES/iiNkcdki40S9JfaM7GM3ywn2xbJruJ5aZCg==
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2ftext/-/text-5.3.7.tgz#cb71b2576bdc1f66fb79977d281f9575dd06d3d5"
|
||||
integrity sha512-WVAc31MDgHTvP0dJNWsvLVJhjeVGZ3NrLpHcH9iIAd6HVO5Z+i+fk4zvodD+Y7jWU0psx8ZD8xe1wy8ECfbCBA==
|
||||
dependencies:
|
||||
"@pixi/core" "5.3.6"
|
||||
"@pixi/math" "5.3.6"
|
||||
"@pixi/settings" "5.3.6"
|
||||
"@pixi/sprite" "5.3.6"
|
||||
"@pixi/utils" "5.3.6"
|
||||
"@pixi/core" "5.3.7"
|
||||
"@pixi/math" "5.3.7"
|
||||
"@pixi/settings" "5.3.7"
|
||||
"@pixi/sprite" "5.3.7"
|
||||
"@pixi/utils" "5.3.7"
|
||||
|
||||
"@pixi/ticker@5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fticker/-/ticker-5.3.6.tgz#022416047199ae1ac875f750efddfb0a0ba20abd"
|
||||
integrity sha512-3BHDrFyI5aHcAlo9fdQ5pd4U1pwt5QwGpbM9EshFL2NeNdumAeZQJ850DXFhVfFAXhhNljEQTFNZ44sTIsAy6Q==
|
||||
"@pixi/ticker@5.3.7":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2fticker/-/ticker-5.3.7.tgz#c331b270042d507fe18543ae435a9a857a8fd5ae"
|
||||
integrity sha512-ZEXiJwPtuPeWa0QmRODF5qK0+ugZu/xeq7QxCvFOCc3NFVBeGms4g92HPucOju9R7jcODIoJxtICALsuwLAr9w==
|
||||
dependencies:
|
||||
"@pixi/settings" "5.3.6"
|
||||
"@pixi/settings" "5.3.7"
|
||||
|
||||
"@pixi/utils@5.3.6":
|
||||
version "5.3.6"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2futils/-/utils-5.3.6.tgz#63ada7f024884390324b430ad19b6e031791c319"
|
||||
integrity sha512-Ilix2qpF89SSyoUpPsjH2RB7Os6ceQ+gts55zpMbLyxMyuMH6GlZ9WgUEhAakkUEtQ6imi3ZZAxCNLAEWNB+cw==
|
||||
"@pixi/utils@5.3.7":
|
||||
version "5.3.7"
|
||||
resolved "https://npm.i12e.cha0s.io/@pixi%2futils/-/utils-5.3.7.tgz#55fe2a2fbf0fba842da5a602576ce68c498e7e16"
|
||||
integrity sha512-f8zAeHHURxfwBr8MZiXEIwY2h9wbS6vN0ypvapGvKFOexZ1EInTs35FhEiRWzLEPLHyn1RgCdKzR2zl++E4tIw==
|
||||
dependencies:
|
||||
"@pixi/constants" "5.3.6"
|
||||
"@pixi/settings" "5.3.6"
|
||||
"@pixi/constants" "5.3.7"
|
||||
"@pixi/settings" "5.3.7"
|
||||
earcut "^2.1.5"
|
||||
eventemitter3 "^3.1.0"
|
||||
url "^0.11.0"
|
||||
|
@ -2205,9 +2155,9 @@ camelcase@^6.0.0:
|
|||
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
|
||||
|
||||
caniuse-lite@^1.0.30001165:
|
||||
version "1.0.30001170"
|
||||
resolved "https://npm.i12e.cha0s.io/caniuse-lite/-/caniuse-lite-1.0.30001170.tgz#0088bfecc6a14694969e391cc29d7eb6362ca6a7"
|
||||
integrity sha512-Dd4d/+0tsK0UNLrZs3CvNukqalnVTRrxb5mcQm8rHL49t7V5ZaTygwXkrq+FB+dVDf++4ri8eJnFEJAB8332PA==
|
||||
version "1.0.30001171"
|
||||
resolved "https://npm.i12e.cha0s.io/caniuse-lite/-/caniuse-lite-1.0.30001171.tgz#3291e11e02699ad0a29e69b8d407666fc843eba7"
|
||||
integrity sha512-5Alrh8TTYPG9IH4UkRqEBZoEToWRLvPbSQokvzSz0lii8/FOWKG4keO1HoYfPWs8IF/NH/dyNPg1cmJGvV3Zlg==
|
||||
|
||||
chai@4.2.0:
|
||||
version "4.2.0"
|
||||
|
@ -2693,7 +2643,7 @@ debug@4.3.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
|
|||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
debug@^3.1.1, debug@^3.2.5:
|
||||
debug@^3.1.1, debug@^3.2.6:
|
||||
version "3.2.7"
|
||||
resolved "https://npm.i12e.cha0s.io/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
|
||||
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
|
||||
|
@ -3141,7 +3091,7 @@ es-abstract@^1.17.0-next.1:
|
|||
string.prototype.trimend "^1.0.1"
|
||||
string.prototype.trimstart "^1.0.1"
|
||||
|
||||
es-abstract@^1.18.0-next.0, es-abstract@^1.18.0-next.1:
|
||||
es-abstract@^1.18.0-next.1:
|
||||
version "1.18.0-next.1"
|
||||
resolved "https://npm.i12e.cha0s.io/es-abstract/-/es-abstract-1.18.0-next.1.tgz#6e3a0a4bda717e5023ab3b8e90bec36108d22c68"
|
||||
integrity sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==
|
||||
|
@ -3583,14 +3533,7 @@ fastparse@^1.1.1:
|
|||
resolved "https://npm.i12e.cha0s.io/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9"
|
||||
integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==
|
||||
|
||||
faye-websocket@^0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://npm.i12e.cha0s.io/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
|
||||
integrity sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=
|
||||
dependencies:
|
||||
websocket-driver ">=0.5.1"
|
||||
|
||||
faye-websocket@~0.11.1:
|
||||
faye-websocket@^0.11.3:
|
||||
version "0.11.3"
|
||||
resolved "https://npm.i12e.cha0s.io/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e"
|
||||
integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==
|
||||
|
@ -3843,7 +3786,7 @@ get-func-name@^2.0.0:
|
|||
resolved "https://npm.i12e.cha0s.io/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
|
||||
integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=
|
||||
|
||||
get-intrinsic@^1.0.0, get-intrinsic@^1.0.1:
|
||||
get-intrinsic@^1.0.0, get-intrinsic@^1.0.1, get-intrinsic@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://npm.i12e.cha0s.io/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49"
|
||||
integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==
|
||||
|
@ -4264,6 +4207,13 @@ ignore@^4.0.6:
|
|||
resolved "https://npm.i12e.cha0s.io/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
|
||||
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
|
||||
|
||||
image-size@^0.9.3:
|
||||
version "0.9.3"
|
||||
resolved "https://npm.i12e.cha0s.io/image-size/-/image-size-0.9.3.tgz#f7efce6b0a1649b44b9bc43b9d9a5acf272264b6"
|
||||
integrity sha512-5SakFa79uhUVSjKeQE30GVzzLJ0QNzB53+I+/VD1vIesD6GP6uatWIlgU0uisFNLt1u0d6kBydp7yfk+lLJhLQ==
|
||||
dependencies:
|
||||
queue "6.0.1"
|
||||
|
||||
import-fresh@^3.0.0, import-fresh@^3.2.1:
|
||||
version "3.3.0"
|
||||
resolved "https://npm.i12e.cha0s.io/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
||||
|
@ -4680,7 +4630,7 @@ json-stable-stringify-without-jsonify@^1.0.1:
|
|||
resolved "https://npm.i12e.cha0s.io/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
|
||||
integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
|
||||
|
||||
json3@^3.3.2:
|
||||
json3@^3.3.3:
|
||||
version "3.3.3"
|
||||
resolved "https://npm.i12e.cha0s.io/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
|
||||
integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==
|
||||
|
@ -4829,21 +4779,11 @@ lodash.flatten@^4.4.0:
|
|||
resolved "https://npm.i12e.cha0s.io/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
|
||||
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
|
||||
|
||||
lodash.mapvalues@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://npm.i12e.cha0s.io/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c"
|
||||
integrity sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=
|
||||
|
||||
lodash.omit@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://npm.i12e.cha0s.io/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60"
|
||||
integrity sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=
|
||||
|
||||
lodash.without@^4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://npm.i12e.cha0s.io/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac"
|
||||
integrity sha1-PNRXSgC2e643OpS3SHcmQFB7eqw=
|
||||
|
||||
lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20:
|
||||
version "4.17.20"
|
||||
resolved "https://npm.i12e.cha0s.io/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
|
||||
|
@ -5392,7 +5332,7 @@ object-hash@^2.0.3:
|
|||
resolved "https://npm.i12e.cha0s.io/object-hash/-/object-hash-2.1.1.tgz#9447d0279b4fcf80cff3259bf66a1dc73afabe09"
|
||||
integrity sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ==
|
||||
|
||||
object-inspect@^1.8.0:
|
||||
object-inspect@^1.8.0, object-inspect@^1.9.0:
|
||||
version "1.9.0"
|
||||
resolved "https://npm.i12e.cha0s.io/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a"
|
||||
integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==
|
||||
|
@ -6073,6 +6013,13 @@ querystringify@^2.1.1:
|
|||
resolved "https://npm.i12e.cha0s.io/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
|
||||
integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
|
||||
|
||||
queue@6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://npm.i12e.cha0s.io/queue/-/queue-6.0.1.tgz#abd5a5b0376912f070a25729e0b6a7d565683791"
|
||||
integrity sha512-AJBQabRCCNr9ANq8v77RJEv73DPbn55cdTb+Giq4X0AVnNVZvMHlYp7XlQiN+1npCZj1DuSmaA2hYVUUDgxFDg==
|
||||
dependencies:
|
||||
inherits "~2.0.3"
|
||||
|
||||
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://npm.i12e.cha0s.io/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
|
||||
|
@ -6424,7 +6371,7 @@ select-hose@^2.0.0:
|
|||
resolved "https://npm.i12e.cha0s.io/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
||||
integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
|
||||
|
||||
selfsigned@^1.10.7:
|
||||
selfsigned@^1.10.8:
|
||||
version "1.10.8"
|
||||
resolved "https://npm.i12e.cha0s.io/selfsigned/-/selfsigned-1.10.8.tgz#0d17208b7d12c33f8eac85c41835f27fc3d81a30"
|
||||
integrity sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==
|
||||
|
@ -6572,12 +6519,13 @@ shebang-regex@^3.0.0:
|
|||
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
||||
|
||||
side-channel@^1.0.2, side-channel@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://npm.i12e.cha0s.io/side-channel/-/side-channel-1.0.3.tgz#cdc46b057550bbab63706210838df5d4c19519c3"
|
||||
integrity sha512-A6+ByhlLkksFoUepsGxfj5x1gTSrs+OydsRptUxeNCabQpCFUvcwIczgOigI8vhY/OJCnPnyE9rGiwgvr9cS1g==
|
||||
version "1.0.4"
|
||||
resolved "https://npm.i12e.cha0s.io/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
|
||||
integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
|
||||
dependencies:
|
||||
es-abstract "^1.18.0-next.0"
|
||||
object-inspect "^1.8.0"
|
||||
call-bind "^1.0.0"
|
||||
get-intrinsic "^1.0.2"
|
||||
object-inspect "^1.9.0"
|
||||
|
||||
signal-exit@^3.0.0:
|
||||
version "3.0.3"
|
||||
|
@ -6683,26 +6631,26 @@ socket.io@2.3.0:
|
|||
socket.io-client "2.3.0"
|
||||
socket.io-parser "~3.4.0"
|
||||
|
||||
sockjs-client@1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://npm.i12e.cha0s.io/sockjs-client/-/sockjs-client-1.4.0.tgz#c9f2568e19c8fd8173b4997ea3420e0bb306c7d5"
|
||||
integrity sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==
|
||||
sockjs-client@^1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://npm.i12e.cha0s.io/sockjs-client/-/sockjs-client-1.5.0.tgz#2f8ff5d4b659e0d092f7aba0b7c386bd2aa20add"
|
||||
integrity sha512-8Dt3BDi4FYNrCFGTL/HtwVzkARrENdwOUf1ZoW/9p3M8lZdFT35jVdrHza+qgxuG9H3/shR4cuX/X9umUrjP8Q==
|
||||
dependencies:
|
||||
debug "^3.2.5"
|
||||
debug "^3.2.6"
|
||||
eventsource "^1.0.7"
|
||||
faye-websocket "~0.11.1"
|
||||
inherits "^2.0.3"
|
||||
json3 "^3.3.2"
|
||||
url-parse "^1.4.3"
|
||||
faye-websocket "^0.11.3"
|
||||
inherits "^2.0.4"
|
||||
json3 "^3.3.3"
|
||||
url-parse "^1.4.7"
|
||||
|
||||
sockjs@0.3.20:
|
||||
version "0.3.20"
|
||||
resolved "https://npm.i12e.cha0s.io/sockjs/-/sockjs-0.3.20.tgz#b26a283ec562ef8b2687b44033a4eeceac75d855"
|
||||
integrity sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==
|
||||
sockjs@^0.3.21:
|
||||
version "0.3.21"
|
||||
resolved "https://npm.i12e.cha0s.io/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417"
|
||||
integrity sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==
|
||||
dependencies:
|
||||
faye-websocket "^0.10.0"
|
||||
faye-websocket "^0.11.3"
|
||||
uuid "^3.4.0"
|
||||
websocket-driver "0.6.5"
|
||||
websocket-driver "^0.7.4"
|
||||
|
||||
sort-keys@^1.0.0:
|
||||
version "1.1.2"
|
||||
|
@ -7304,7 +7252,7 @@ url-loader@^4.1.1:
|
|||
mime-types "^2.1.27"
|
||||
schema-utils "^3.0.0"
|
||||
|
||||
url-parse@^1.4.3:
|
||||
url-parse@^1.4.3, url-parse@^1.4.7:
|
||||
version "1.4.7"
|
||||
resolved "https://npm.i12e.cha0s.io/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278"
|
||||
integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==
|
||||
|
@ -7468,9 +7416,9 @@ webpack-dev-middleware@^4.0.2:
|
|||
schema-utils "^3.0.0"
|
||||
|
||||
webpack-dev-server@^3.11.0:
|
||||
version "3.11.0"
|
||||
resolved "https://npm.i12e.cha0s.io/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz#8f154a3bce1bcfd1cc618ef4e703278855e7ff8c"
|
||||
integrity sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==
|
||||
version "3.11.1"
|
||||
resolved "https://npm.i12e.cha0s.io/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz#c74028bf5ba8885aaf230e48a20e8936ab8511f0"
|
||||
integrity sha512-u4R3mRzZkbxQVa+MBWi2uVpB5W59H3ekZAJsQlKUTdl7Elcah2EhygTPLmeFXybQkf9i2+L0kn7ik9SnXa6ihQ==
|
||||
dependencies:
|
||||
ansi-html "0.0.7"
|
||||
bonjour "^3.5.0"
|
||||
|
@ -7492,11 +7440,11 @@ webpack-dev-server@^3.11.0:
|
|||
p-retry "^3.0.1"
|
||||
portfinder "^1.0.26"
|
||||
schema-utils "^1.0.0"
|
||||
selfsigned "^1.10.7"
|
||||
selfsigned "^1.10.8"
|
||||
semver "^6.3.0"
|
||||
serve-index "^1.9.1"
|
||||
sockjs "0.3.20"
|
||||
sockjs-client "1.4.0"
|
||||
sockjs "^0.3.21"
|
||||
sockjs-client "^1.5.0"
|
||||
spdy "^4.0.2"
|
||||
strip-ansi "^3.0.1"
|
||||
supports-color "^6.1.0"
|
||||
|
@ -7571,14 +7519,7 @@ webpack@^4:
|
|||
watchpack "^1.7.4"
|
||||
webpack-sources "^1.4.1"
|
||||
|
||||
websocket-driver@0.6.5:
|
||||
version "0.6.5"
|
||||
resolved "https://npm.i12e.cha0s.io/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36"
|
||||
integrity sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=
|
||||
dependencies:
|
||||
websocket-extensions ">=0.1.1"
|
||||
|
||||
websocket-driver@>=0.5.1:
|
||||
websocket-driver@>=0.5.1, websocket-driver@^0.7.4:
|
||||
version "0.7.4"
|
||||
resolved "https://npm.i12e.cha0s.io/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760"
|
||||
integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==
|
||||
|
@ -7657,9 +7598,9 @@ ws@^6.2.1:
|
|||
async-limiter "~1.0.0"
|
||||
|
||||
ws@^7.1.2:
|
||||
version "7.4.1"
|
||||
resolved "https://npm.i12e.cha0s.io/ws/-/ws-7.4.1.tgz#a333be02696bd0e54cea0434e21dcc8a9ac294bb"
|
||||
integrity sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==
|
||||
version "7.4.2"
|
||||
resolved "https://npm.i12e.cha0s.io/ws/-/ws-7.4.2.tgz#782100048e54eb36fe9843363ab1c68672b261dd"
|
||||
integrity sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==
|
||||
|
||||
ws@~6.1.0:
|
||||
version "6.1.4"
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
"index.js.map"
|
||||
],
|
||||
"dependencies": {
|
||||
"@latus/core": "^2.0.0",
|
||||
"@latus/socket": "^2.0.0",
|
||||
"@latus/core": "2.0.0",
|
||||
"@latus/socket": "2.0.0",
|
||||
"debug": "4.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
"index.js.map"
|
||||
],
|
||||
"dependencies": {
|
||||
"@avocado/core": "^2.0.0",
|
||||
"@avocado/core": "2.0.0",
|
||||
"@latus/core": "^2.0.0",
|
||||
"d3-quadtree": "^2.0.0",
|
||||
"debug": "4.3.1"
|
||||
},
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import {compose, Property} from '@avocado/core';
|
||||
import {Property} from '@avocado/core';
|
||||
import {compose} from '@latus/core';
|
||||
|
||||
import * as Vector from './vector';
|
||||
|
||||
|
@ -15,7 +16,8 @@ export default function VectorMixin(
|
|||
...meta,
|
||||
};
|
||||
const transformedKey = `$$avocado_property_${vectorKey}`;
|
||||
meta.initialize = () => {
|
||||
// eslint-disable-next-line func-names
|
||||
meta.initialize = function () {
|
||||
this[transformedKey] = Vector.copy(meta.default);
|
||||
};
|
||||
const bypass = `${transformedKey}$bypassChangedEvent`;
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@avocado/core@^2.0.0":
|
||||
"@avocado/core@2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fcore/-/core-2.0.0.tgz#636ea3c3b54a38538c59485080f6a0e48f1798e7"
|
||||
integrity sha512-VW+ygRHaQQwaL5rKZGm0n0DNfvj+H89qQx+67veCUmUuRav3XAeE0iYs8Lgfc3CJLPz/alqt/dVPMXd5QDR+Mg==
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fcore/-/core-2.0.0.tgz#ac7f912135c1cbb433b825c0fd1aa9a14b91ffed"
|
||||
integrity sha512-PX6UVuhcmUaf2yzhTEd+dUle/Z3JRWJXm7NwGN63oL3w5QqUVOEzqUQNkKem2b+mlyJl56UnWzZJYYLixTOzvQ==
|
||||
dependencies:
|
||||
debug "4.3.1"
|
||||
|
||||
|
@ -899,6 +899,16 @@
|
|||
minimatch "^3.0.4"
|
||||
strip-json-comments "^3.1.1"
|
||||
|
||||
"@latus/core@^2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@latus%2fcore/-/core-2.0.0.tgz#4447b4bba265b684035be1dacefd6ba4913a47d4"
|
||||
integrity sha512-OSsbO4wvVJFPZTMRDX5LAXOA+MQY8FOSK7PcTEJKeiRqOMeMIVkZc6q6KNlUIYivE+87rlM7S/CctHoA7uvQvg==
|
||||
dependencies:
|
||||
debug "4.3.1"
|
||||
js-yaml "3.14.0"
|
||||
lodash.capitalize "^4.2.1"
|
||||
lodash.flatten "^4.4.0"
|
||||
|
||||
"@neutrinojs/airbnb-base@^9.4.0":
|
||||
version "9.5.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@neutrinojs%2fairbnb-base/-/airbnb-base-9.5.0.tgz#d47fe0d927aa56814e70e1228af08918c5190808"
|
||||
|
@ -3907,11 +3917,21 @@ locate-path@^6.0.0:
|
|||
dependencies:
|
||||
p-locate "^5.0.0"
|
||||
|
||||
lodash.capitalize@^4.2.1:
|
||||
version "4.2.1"
|
||||
resolved "https://npm.i12e.cha0s.io/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz#f826c9b4e2a8511d84e3aca29db05e1a4f3b72a9"
|
||||
integrity sha1-+CbJtOKoUR2E46yinbBeGk87cqk=
|
||||
|
||||
lodash.clonedeep@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://npm.i12e.cha0s.io/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
|
||||
integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
|
||||
|
||||
lodash.flatten@^4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://npm.i12e.cha0s.io/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
|
||||
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
|
||||
|
||||
lodash.omit@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://npm.i12e.cha0s.io/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60"
|
||||
|
|
1
packages/physics/.eslintrc.js
Normal file
1
packages/physics/.eslintrc.js
Normal file
|
@ -0,0 +1 @@
|
|||
module.exports = require('../../config/.eslintrc');
|
5
packages/physics/.gitignore
vendored
Normal file
5
packages/physics/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
**/*.js
|
||||
**/*.map
|
||||
!/.*
|
||||
!/webpack.config.js
|
||||
!src/**/*.js
|
1
packages/physics/.neutrinorc.js
Normal file
1
packages/physics/.neutrinorc.js
Normal file
|
@ -0,0 +1 @@
|
|||
module.exports = require('../../config/.neutrinorc');
|
54
packages/physics/package.json
Normal file
54
packages/physics/package.json
Normal file
|
@ -0,0 +1,54 @@
|
|||
{
|
||||
"name": "@avocado/package",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"author": "cha0s",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"build": "NODE_PATH=./node_modules webpack --mode production",
|
||||
"clean": "rm -rf yarn.lock node_modules && yarn",
|
||||
"dev": "NODE_PATH=./node_modules webpack --mode development",
|
||||
"forcepub": "npm unpublish --force $(node -e 'const {name, version} = require(`./package.json`); process.stdout.write(`${name}@${version}`)') && npm publish",
|
||||
"link": "node -e \"Object.keys(require('./package.json').dependencies).filter((m) => 0 === m.indexOf('@latus/')).forEach((m) => require('child_process').spawn('yarn', ['link', m]));\"",
|
||||
"lint": "NODE_PATH=./node_modules eslint --format codeframe --ext mjs,js .",
|
||||
"test": "NODE_PATH=./node_modules mocha --config ../../config/.mocharc.js",
|
||||
"unlink": "node -e \"Object.keys(require('./package.json').dependencies).filter((m) => 0 === m.indexOf('@latus/')).forEach((m) => require('child_process').spawn('yarn', ['unlink', m]));\" && yarn install --force",
|
||||
"watch": "NODE_PATH=./node_modules webpack --watch --mode development"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.js.map"
|
||||
],
|
||||
"dependencies": {
|
||||
"@avocado/behavior": "^2.0.0",
|
||||
"@avocado/core": "^2.0.0",
|
||||
"@avocado/entity": "^2.0.0",
|
||||
"@avocado/graphics": "^2.0.0",
|
||||
"@avocado/math": "^2.0.0",
|
||||
"@avocado/s13n": "^2.0.0",
|
||||
"@avocado/timing": "^2.0.0",
|
||||
"@avocado/traits": "^2.0.0",
|
||||
"@latus/core": "^2.0.0",
|
||||
"debug": "4.3.1",
|
||||
"deepmerge": "^4.2.2",
|
||||
"immutable": "^4.0.0-rc.12",
|
||||
"kefir": "^3.8.8",
|
||||
"matter-js": "0.14.2",
|
||||
"poly-decomp": "0.3.0",
|
||||
"proton-js": "^3.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@neutrinojs/airbnb-base": "^9.4.0",
|
||||
"@neutrinojs/copy": "9.4.0",
|
||||
"@neutrinojs/mocha": "^9.4.0",
|
||||
"@neutrinojs/react": "^9.4.0",
|
||||
"chai": "4.2.0",
|
||||
"eslint": "^7",
|
||||
"eslint-import-resolver-webpack": "0.13.0",
|
||||
"mocha": "^8",
|
||||
"neutrino": "^9.4.0",
|
||||
"webpack": "^4",
|
||||
"webpack-cli": "^3",
|
||||
"webpack-node-externals": "2.5.2"
|
||||
}
|
||||
}
|
21
packages/physics/src/abstract/body.js
Normal file
21
packages/physics/src/abstract/body.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
import {virtualize} from '@avocado/core';
|
||||
import {Class, compose} from '@latus/core';
|
||||
|
||||
const decorate = compose(
|
||||
virtualize([
|
||||
'applyForce',
|
||||
'applyImpulse',
|
||||
'vertices',
|
||||
]),
|
||||
);
|
||||
|
||||
export default class AbstractBody extends decorate(Class) {
|
||||
|
||||
constructor(world, shape) {
|
||||
super();
|
||||
this.impulse = [0, 0];
|
||||
this.shape = shape;
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
}
|
66
packages/physics/src/abstract/world.js
Normal file
66
packages/physics/src/abstract/world.js
Normal file
|
@ -0,0 +1,66 @@
|
|||
import {Property, virtualize} from '@avocado/core';
|
||||
import {Class, compose} from '@latus/core';
|
||||
|
||||
const decorate = compose(
|
||||
Property('stepTime', {
|
||||
default: 1 / 60,
|
||||
}),
|
||||
virtualize([
|
||||
'addBody',
|
||||
'createBody',
|
||||
]),
|
||||
);
|
||||
|
||||
export default class AbstractWorld extends decorate(Class) {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.entities = new Map();
|
||||
this.entitiesList = [];
|
||||
}
|
||||
|
||||
associateBodyWithEntity(body, entity) {
|
||||
this.entities.set(body, entity);
|
||||
this.entitiesList.push(entity);
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
body.position = entity.position;
|
||||
}
|
||||
|
||||
removeBody(body) {
|
||||
if (this.entities.has(body)) {
|
||||
const entity = this.entities.get(body);
|
||||
this.entities.delete(body);
|
||||
const index = this.entitiesList.indexOf(entity);
|
||||
if (-1 !== index) {
|
||||
this.entitiesList.splice(index, 1);
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
body.world = null;
|
||||
}
|
||||
|
||||
tick(elapsed) {
|
||||
this.tickPhysics(elapsed);
|
||||
}
|
||||
|
||||
tickPhysics() {
|
||||
// Propagate position updates.
|
||||
const it = this.entities.entries();
|
||||
for (let value = it.next(); value.done !== true; value = it.next()) {
|
||||
const body = value.value[0];
|
||||
const entity = value.value[1];
|
||||
const entityPosition = entity.position;
|
||||
const bodyPosition = body.position;
|
||||
// Hot.
|
||||
if (
|
||||
/* eslint-disable no-bitwise */
|
||||
(entityPosition[0] << 0) !== (bodyPosition[0] << 0)
|
||||
|| (entityPosition[1] << 0) !== (bodyPosition[1] << 0)
|
||||
/* eslint-enable no-bitwise */
|
||||
) {
|
||||
entity.setPosition(body.position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
43
packages/physics/src/body-view.js
Normal file
43
packages/physics/src/body-view.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
import {Color, Primitives, Renderable} from '@avocado/graphics';
|
||||
|
||||
export default class BodyView extends Renderable {
|
||||
|
||||
constructor(body) {
|
||||
super();
|
||||
this.body = body;
|
||||
this.primitives = new Primitives();
|
||||
this.redraw();
|
||||
}
|
||||
|
||||
get internal() {
|
||||
return this.primitives.internal;
|
||||
}
|
||||
|
||||
redraw() {
|
||||
const {primitives} = this;
|
||||
const {vertices} = this.body;
|
||||
primitives.clear();
|
||||
let firstVertice;
|
||||
let lastVertice;
|
||||
for (let i = 0; i < vertices.length; i++) {
|
||||
const vertice = vertices[i];
|
||||
if (!firstVertice) {
|
||||
firstVertice = vertice;
|
||||
}
|
||||
if (lastVertice) {
|
||||
primitives.drawLine(
|
||||
lastVertice,
|
||||
vertice,
|
||||
Primitives.lineStyle(new Color(255, 255, 0), 1),
|
||||
);
|
||||
}
|
||||
lastVertice = vertice;
|
||||
}
|
||||
primitives.drawLine(
|
||||
lastVertice,
|
||||
firstVertice,
|
||||
Primitives.lineStyle(new Color(255, 255, 0), 1),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
36
packages/physics/src/dummy/body.js
Normal file
36
packages/physics/src/dummy/body.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
import * as I from 'immutable';
|
||||
|
||||
import {compose, EventEmitter} from '@avocado/core';
|
||||
import {Rectangle, Vector} from '@avocado/math';
|
||||
|
||||
import AbstractBody from '../abstract/body';
|
||||
|
||||
const decorate = compose(
|
||||
EventEmitter,
|
||||
Vector.Mixin('position', 'x', 'y', {
|
||||
default: [0, 0],
|
||||
track: true,
|
||||
}),
|
||||
);
|
||||
|
||||
export default class Body extends decorate(AbstractBody) {
|
||||
|
||||
constructor(world, shape) {
|
||||
super(world, shape);
|
||||
this.force = [0, 0];
|
||||
this.contacts = I.Set();
|
||||
}
|
||||
|
||||
get aabb() {
|
||||
return Rectangle.translated(this.shape.aabb, this.position);
|
||||
}
|
||||
|
||||
applyForce(vector) {
|
||||
this.force = Vector.add(this.force, vector);
|
||||
}
|
||||
|
||||
applyImpulse(vector) {
|
||||
this.impulse = Vector.add(this.impulse, vector);
|
||||
}
|
||||
|
||||
}
|
190
packages/physics/src/dummy/world.js
Normal file
190
packages/physics/src/dummy/world.js
Normal file
|
@ -0,0 +1,190 @@
|
|||
import * as I from 'immutable';
|
||||
|
||||
import {arrayUnique} from '@avocado/core';
|
||||
import {Rectangle, QuadTree, Vector} from '@avocado/math';
|
||||
|
||||
import Body from './body';
|
||||
import AbstractWorld from '../abstract/world';
|
||||
|
||||
export default class World extends AbstractWorld {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.bodies = [];
|
||||
this.quadTree = new QuadTree();
|
||||
this.quadTreeNodes = new Map();
|
||||
}
|
||||
|
||||
addBody(body) {
|
||||
this.bodies.push(body);
|
||||
// Add to quad tree.
|
||||
this.addQuadTreeNodes(body);
|
||||
body.on('positionChanged', () => {
|
||||
this.removeQuadTreeNodes(body);
|
||||
this.addQuadTreeNodes(body);
|
||||
});
|
||||
}
|
||||
|
||||
addQuadTreeNodes(body) {
|
||||
// 4 points.
|
||||
const {aabb} = body;
|
||||
const points = Rectangle.toPoints(aabb);
|
||||
const nodes = points.map((point) => [...point, body]);
|
||||
this.quadTreeNodes.set(body, nodes);
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
this.quadTree.add(nodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
createBody(shape) {
|
||||
return new Body(this, shape);
|
||||
}
|
||||
|
||||
removeBody(body) {
|
||||
super.removeBody(body);
|
||||
const index = this.bodies.indexOf(body);
|
||||
if (-1 === index) {
|
||||
return;
|
||||
}
|
||||
this.removeQuadTreeNodes(body);
|
||||
this.bodies.splice(index, 1);
|
||||
}
|
||||
|
||||
removeQuadTreeNodes(body) {
|
||||
const nodes = this.quadTreeNodes.get(body);
|
||||
if (!nodes) {
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
this.quadTree.remove(nodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
tick(elapsed) {
|
||||
let entities;
|
||||
// Apply.
|
||||
entities = this.entities.values();
|
||||
for (let i = 0; i < entities.length; i++) {
|
||||
const {body} = entities[i];
|
||||
const translation = Vector.add(
|
||||
Vector.mul(body.impulse, elapsed),
|
||||
body.force,
|
||||
);
|
||||
body.position = Vector.add(body.position, translation);
|
||||
}
|
||||
// Contact checks.
|
||||
const allContacts = new Map();
|
||||
const checkedSoFar = new Map();
|
||||
entities = this.entities.values();
|
||||
for (let i = 0; i < entities.length; i++) {
|
||||
const entity = entities[i];
|
||||
const {body} = entity;
|
||||
// Find bodies in AABB.
|
||||
const {aabb} = body;
|
||||
let otherBodies = this.quadTree.search(aabb).map((node) => node.data[2]);
|
||||
// Not self.
|
||||
otherBodies = otherBodies.filter((otherBody) => otherBody !== body);
|
||||
// Uniques only.
|
||||
otherBodies = arrayUnique(otherBodies);
|
||||
// TODO: full collision check
|
||||
const checkSet = new Set();
|
||||
checkedSoFar.set(entity, checkSet);
|
||||
for (let j = 0; j < otherBodies.length; j++) {
|
||||
const otherBody = otherBodies[j];
|
||||
const otherEntity = this.entities.get(otherBody);
|
||||
if (otherEntity) {
|
||||
// Only one check per pair.
|
||||
const otherCheckSet = checkedSoFar.get(otherEntity);
|
||||
if (otherCheckSet) {
|
||||
if (otherCheckSet.has(entity)) {
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Self contacts.
|
||||
let contacts = allContacts.get(entity);
|
||||
if (!contacts) {
|
||||
contacts = I.Set();
|
||||
}
|
||||
contacts = contacts.add(otherEntity);
|
||||
allContacts.set(entity, contacts);
|
||||
// Other contacts.
|
||||
let otherContacts = allContacts.get(otherEntity);
|
||||
if (!otherContacts) {
|
||||
otherContacts = I.Set();
|
||||
}
|
||||
otherContacts = otherContacts.add(entity);
|
||||
allContacts.set(otherEntity, otherContacts);
|
||||
// Mark as checked.
|
||||
checkSet.add(otherEntity);
|
||||
}
|
||||
}
|
||||
if (!allContacts.get(entity)) {
|
||||
allContacts.set(entity, I.Set());
|
||||
}
|
||||
}
|
||||
// Report collisions.
|
||||
entities = this.entities.values();
|
||||
for (let i = 0; i < entities.length; i++) {
|
||||
const entity = entities[i];
|
||||
const oldContacts = entity.body.contacts;
|
||||
const newContacts = allContacts.get(entity);
|
||||
const newValues = newContacts.values();
|
||||
for (let j = 0; j < newValues.length; j++) {
|
||||
const contact = newValues[j];
|
||||
if (!oldContacts.has(contact)) {
|
||||
entity.emit('collisionStart', contact);
|
||||
}
|
||||
}
|
||||
const oldValues = oldContacts.values();
|
||||
for (let j = 0; j < oldValues.length; j++) {
|
||||
const contact = oldValues[j];
|
||||
if (!oldContacts.has(contact)) {
|
||||
entity.emit('collisionEnd', contact);
|
||||
}
|
||||
}
|
||||
entity.body.contacts = newContacts;
|
||||
}
|
||||
// Super rudimentary resolving.
|
||||
entities = this.entities.values();
|
||||
for (let i = 0; i < entities.length; i++) {
|
||||
const {body} = entities[i];
|
||||
// Contact? Undo impulse.
|
||||
const {contacts} = body;
|
||||
if (contacts.size > 0) {
|
||||
const translation = Vector.add(
|
||||
Vector.mul(body.impulse, elapsed),
|
||||
body.force,
|
||||
);
|
||||
body.position = Vector.sub(body.position, translation);
|
||||
// Check all contacts and see if impulse vector can be fixed.
|
||||
for (let axe = 0; axe < 2; axe++) {
|
||||
let anyContact = false;
|
||||
const potentialTranslation = [0, 0];
|
||||
potentialTranslation[axe] = translation[axe];
|
||||
body.position = Vector.add(body.position, potentialTranslation);
|
||||
for (let j = 0; j < contacts.length; j++) {
|
||||
const contact = contacts[j];
|
||||
const contactBody = contact.body;
|
||||
if (Rectangle.intersects(body.aabb, contactBody.aabb)) {
|
||||
anyContact = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (anyContact) {
|
||||
body.position = Vector.sub(body.position, potentialTranslation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Drop transforms.
|
||||
entities = this.entities.values();
|
||||
for (let i = 0; i < entities.length; i++) {
|
||||
const {body} = entities[i];
|
||||
body.force = [0, 0];
|
||||
body.impulse = [0, 0];
|
||||
}
|
||||
super.tick(elapsed);
|
||||
}
|
||||
|
||||
}
|
8
packages/physics/src/index.js
Normal file
8
packages/physics/src/index.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
export {default as BodyView} from './body-view';
|
||||
export {default as Proton} from './proton';
|
||||
export {default as CircleShape} from './shape/circle';
|
||||
export {default as shapeFromJSON} from './shape/from-json';
|
||||
export {default as ShapeList} from './shape/list';
|
||||
export {default as PolygonShape} from './shape/polygon';
|
||||
export {default as RectangleShape} from './shape/rectangle';
|
||||
export {default as ShapeView} from './shape/view';
|
190
packages/physics/src/matter/body.js
Normal file
190
packages/physics/src/matter/body.js
Normal file
|
@ -0,0 +1,190 @@
|
|||
import {Vector} from '@avocado/math';
|
||||
import {
|
||||
Bodies,
|
||||
Body as MatterBody,
|
||||
Vertices,
|
||||
} from 'matter-js';
|
||||
|
||||
import AbstractBody from '../abstract/body';
|
||||
import ShapeList from '../shape/list';
|
||||
import CircleShape from '../shape/circle';
|
||||
import RectangleShape from '../shape/rectangle';
|
||||
|
||||
// Keep matter from grasping for decomp.
|
||||
let g;
|
||||
if ('undefined' !== typeof window) {
|
||||
g = window;
|
||||
}
|
||||
else if ('undefined' !== typeof global) {
|
||||
g = global;
|
||||
}
|
||||
if (g) {
|
||||
// eslint-disable-next-line global-require
|
||||
g.decomp = require('poly-decomp');
|
||||
}
|
||||
// Translate "real" coordinates to physics coordinates.
|
||||
const SCALE = 1;
|
||||
|
||||
export default class Body extends AbstractBody {
|
||||
|
||||
static collisionCategory(group) {
|
||||
if (!('filterCategoryBit' in this)) {
|
||||
this.filterCategoryBit = 0;
|
||||
}
|
||||
if (!('filterCategories' in this)) {
|
||||
this.filterCategories = {};
|
||||
}
|
||||
if (!this.filterCategories[group]) {
|
||||
// eslint-disable-next-line no-bitwise
|
||||
this.filterCategories[group] = 1 << this.filterCategoryBit;
|
||||
this.filterCategoryBit += 1;
|
||||
}
|
||||
return this.filterCategories[group];
|
||||
}
|
||||
|
||||
static lookupBody(matterBody) {
|
||||
return this.bodies
|
||||
? this.bodies.get(matterBody)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
static associateBody(matterBody, avocadoBody) {
|
||||
if (!this.bodies) {
|
||||
this.bodies = new WeakMap();
|
||||
}
|
||||
this.bodies.set(matterBody, avocadoBody);
|
||||
}
|
||||
|
||||
constructor(world, shape) {
|
||||
super(world, shape);
|
||||
const [body, position, origin] = this.constructor.bodyFromShape(shape);
|
||||
// Set body first, then origin, then position. Order important.
|
||||
this.matterBody = body;
|
||||
this.origin = origin;
|
||||
this.position = Vector.scale(position, SCALE);
|
||||
this.constructor.associateBody(this.matterBody, this);
|
||||
}
|
||||
|
||||
get aabb() {
|
||||
const {bounds} = this.matterBody;
|
||||
return [
|
||||
bounds.min.x,
|
||||
bounds.min.y,
|
||||
bounds.max.x - bounds.min.x,
|
||||
bounds.max.y - bounds.min.y,
|
||||
].map((p) => p * SCALE);
|
||||
}
|
||||
|
||||
applyForce(force) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
force = Vector.scale(force, 1 / SCALE);
|
||||
const [x, y] = force;
|
||||
MatterBody.applyForce(this.matterBody, this.matterBody.position, {x, y});
|
||||
}
|
||||
|
||||
applyImpulse(impulse) {
|
||||
this.impulse = Vector.add(this.impulse, Vector.scale(impulse, 1 / SCALE));
|
||||
}
|
||||
|
||||
static bodyFromShape(shape) {
|
||||
const shapePosition = Vector.scale(shape.position, 1 / SCALE);
|
||||
if (shape instanceof ShapeList) {
|
||||
const children = [];
|
||||
for (let i = 0; i < shape.children.length; i++) {
|
||||
const child = shape.children[i];
|
||||
const [body, position, origin] = this.bodyFromShape(child);
|
||||
const [x, y] = Vector.add(position, origin);
|
||||
MatterBody.setPosition(body, {x, y});
|
||||
children.push(body);
|
||||
}
|
||||
let body = MatterBody.create({parts: children});
|
||||
const {vertices} = body;
|
||||
body = Bodies.fromVertices(0, 0, vertices);
|
||||
MatterBody.setPosition(body, Vertices.centre(vertices));
|
||||
const {x, y} = body.position;
|
||||
return [body, shapePosition, [x, y]];
|
||||
}
|
||||
if (shape instanceof RectangleShape) {
|
||||
const [width, height] = Vector.scale(shape.size, 1 / SCALE);
|
||||
const body = Bodies.rectangle(0, 0, width, height);
|
||||
return [body, shapePosition, [0, 0]];
|
||||
}
|
||||
if (shape instanceof CircleShape) {
|
||||
const body = Bodies.circle(0, 0, shape.radius / SCALE);
|
||||
return [body, shapePosition, [0, 0]];
|
||||
}
|
||||
const vectors = [];
|
||||
for (let i = 0; i < shape._translatedVertices.length; i++) {
|
||||
const vertice = shape._translatedVertices[i];
|
||||
const [x, y] = Vector.scale(vertice, 1 / SCALE);
|
||||
vectors.push({x, y});
|
||||
}
|
||||
const {x, y} = Vertices.centre(vectors);
|
||||
const body = Bodies.fromVertices(0, 0, vectors);
|
||||
return [body, shapePosition, [x, y]];
|
||||
}
|
||||
|
||||
get position() {
|
||||
const {x, y} = this.matterBody.position;
|
||||
return Vector.sub(Vector.scale([x, y], SCALE), this.origin);
|
||||
}
|
||||
|
||||
set position(position) {
|
||||
/* eslint-disable no-param-reassign */
|
||||
position = Vector.scale(position, 1 / SCALE);
|
||||
position = Vector.add(position, this.origin);
|
||||
/* eslint-enable no-param-reassign */
|
||||
if (Vector.equalsClose(this.position, position)) {
|
||||
return;
|
||||
}
|
||||
const [x, y] = position;
|
||||
MatterBody.setPosition(this.matterBody, {x, y});
|
||||
}
|
||||
|
||||
setCollision(category, mask, group = 0) {
|
||||
MatterBody.set(this.matterBody, 'collisionFilter', {
|
||||
category,
|
||||
group,
|
||||
mask,
|
||||
});
|
||||
}
|
||||
|
||||
setCollisionForEntity(entity) {
|
||||
if (entity.is('collider')) {
|
||||
const ctor = this.constructor;
|
||||
const category = ctor.collisionCategory(entity.collisionGroup);
|
||||
let mask = 0;
|
||||
const collidesWithGroups = {entity};
|
||||
for (let i = 0; i < collidesWithGroups.length; i++) {
|
||||
const group = collidesWithGroups[i];
|
||||
// eslint-disable-next-line no-bitwise
|
||||
mask |= ctor.collisionCategory(group);
|
||||
}
|
||||
this.setCollision(category, mask);
|
||||
if (entity.isSensor) {
|
||||
MatterBody.set(this.matterBody, 'isSensor', true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.setCollision(0, 0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
get static() {
|
||||
return this.matterBody.isStatic;
|
||||
}
|
||||
|
||||
set static(isStatic) {
|
||||
MatterBody.setStatic(this.matterBody, isStatic);
|
||||
}
|
||||
|
||||
get vertices() {
|
||||
const vertices = [];
|
||||
for (let i = 0; i < this.matterBody.vertices.length; i++) {
|
||||
const {x, y} = this.matterBody.vertices[i];
|
||||
vertices.push(Vector.scale([x, y], SCALE));
|
||||
}
|
||||
return vertices;
|
||||
}
|
||||
|
||||
}
|
94
packages/physics/src/matter/world.js
Normal file
94
packages/physics/src/matter/world.js
Normal file
|
@ -0,0 +1,94 @@
|
|||
import {
|
||||
Body as MatterBody,
|
||||
Engine,
|
||||
Events,
|
||||
World as MatterWorld,
|
||||
} from 'matter-js';
|
||||
|
||||
import {Vector} from '@avocado/math';
|
||||
|
||||
import Body from './body';
|
||||
import AbstractWorld from '../abstract/world';
|
||||
|
||||
export default class World extends AbstractWorld {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const world = MatterWorld.create({
|
||||
gravity: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
scale: 0,
|
||||
},
|
||||
});
|
||||
this.engine = Engine.create({
|
||||
world,
|
||||
});
|
||||
this.handleCollisions('collisionStart');
|
||||
this.handleCollisions('collisionEnd');
|
||||
this.elapsedRemainder = 0;
|
||||
}
|
||||
|
||||
addBody(body) {
|
||||
MatterWorld.add(this.engine.world, body.matterBody);
|
||||
}
|
||||
|
||||
createBody(shape) {
|
||||
return new Body(this, shape);
|
||||
}
|
||||
|
||||
handleCollisions(eventName) {
|
||||
Events.on(this.engine, eventName, (event) => {
|
||||
event.pairs.forEach((pair) => {
|
||||
const {bodyA, bodyB} = pair;
|
||||
const entityA = this.entities.get(Body.lookupBody(bodyA));
|
||||
const entityB = this.entities.get(Body.lookupBody(bodyB));
|
||||
if (
|
||||
entityA && entityA.is('collider')
|
||||
&& entityB && entityB.is('collider')
|
||||
) {
|
||||
if (entityA.collidesWith(entityB)) {
|
||||
entityA.emit(eventName, entityB);
|
||||
}
|
||||
if (entityB.collidesWith(entityA)) {
|
||||
entityB.emit(eventName, entityA);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
removeBody(body) {
|
||||
super.removeBody(body);
|
||||
MatterWorld.remove(this.engine.world, body.matterBody);
|
||||
}
|
||||
|
||||
tick(elapsed) {
|
||||
// Update simulation.
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
elapsed += this.elapsedRemainder;
|
||||
const {stepTime} = this;
|
||||
const stepTimeInMs = stepTime * 1000;
|
||||
while (elapsed >= stepTime) {
|
||||
// Apply impulses.
|
||||
const it = this.entities.entries();
|
||||
for (let value = it.next(); value.done !== true; value = it.next()) {
|
||||
const body = value.value[0];
|
||||
const [x, y] = Vector.scale(body.impulse, stepTime);
|
||||
MatterBody.translate(body.matterBody, {x, y});
|
||||
}
|
||||
Engine.update(this.engine, stepTimeInMs);
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
elapsed -= stepTime;
|
||||
}
|
||||
this.elapsedRemainder = elapsed;
|
||||
// Reset impulses.
|
||||
const it = this.entities.entries();
|
||||
for (let value = it.next(); value.done !== true; value = it.next()) {
|
||||
value.value[0].impulse = [0, 0];
|
||||
}
|
||||
// Propagate.
|
||||
super.tick(elapsed);
|
||||
}
|
||||
|
||||
}
|
1
packages/physics/src/proton/index.js
Normal file
1
packages/physics/src/proton/index.js
Normal file
|
@ -0,0 +1 @@
|
|||
export {default} from './proton';
|
9
packages/physics/src/proton/proton.js
Normal file
9
packages/physics/src/proton/proton.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
import Proton_ from 'proton-js';
|
||||
|
||||
export default class Proton extends Proton_ {
|
||||
|
||||
tick(elapsed) {
|
||||
this.update(elapsed);
|
||||
}
|
||||
|
||||
}
|
41
packages/physics/src/shape/circle.js
Normal file
41
packages/physics/src/shape/circle.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
import {compose, Property} from '@avocado/core';
|
||||
|
||||
import Shape from './shape';
|
||||
|
||||
const decorate = compose(
|
||||
Property('radius', {
|
||||
track: true,
|
||||
}),
|
||||
);
|
||||
|
||||
export default class CircleShape extends decorate(Shape) {
|
||||
|
||||
constructor(shape) {
|
||||
super(shape);
|
||||
if (shape.radius) {
|
||||
this.radius = shape.radius;
|
||||
}
|
||||
this.on('radiusChanged', this.onAabbChanged, this);
|
||||
}
|
||||
|
||||
get aabb() {
|
||||
const [x, y] = this.position;
|
||||
const halfRadius = this.radius / 2;
|
||||
return [
|
||||
x - halfRadius,
|
||||
y - halfRadius,
|
||||
x + halfRadius,
|
||||
y + halfRadius,
|
||||
];
|
||||
}
|
||||
|
||||
destroy() {
|
||||
super.destroy();
|
||||
this.off('radiusChanged', this.onAabbChanged);
|
||||
}
|
||||
|
||||
onAabbChanged() {
|
||||
this.emit('aabbChanged');
|
||||
}
|
||||
|
||||
}
|
17
packages/physics/src/shape/from-json.js
Normal file
17
packages/physics/src/shape/from-json.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import PolygonShape from './polygon';
|
||||
import CircleShape from './circle';
|
||||
import RectangleShape from './rectangle';
|
||||
import ShapeList from './list';
|
||||
|
||||
export default function shapeFromJSON(json) {
|
||||
switch (json.type) {
|
||||
case 'circle':
|
||||
return new CircleShape(json);
|
||||
case 'list':
|
||||
return new ShapeList(json);
|
||||
default:
|
||||
return new PolygonShape(json);
|
||||
case 'rectangle':
|
||||
return new RectangleShape(json);
|
||||
}
|
||||
}
|
130
packages/physics/src/shape/list.js
Normal file
130
packages/physics/src/shape/list.js
Normal file
|
@ -0,0 +1,130 @@
|
|||
import {Rectangle} from '@avocado/math';
|
||||
|
||||
import PolygonShape from './polygon';
|
||||
import CircleShape from './circle';
|
||||
import RectangleShape from './rectangle';
|
||||
import Shape from './shape';
|
||||
|
||||
export default class ShapeList extends Shape {
|
||||
|
||||
constructor({children} = {}) {
|
||||
super();
|
||||
this.on('childrenChanged', this.onChildrenChanged, this);
|
||||
this.on('originChanged', this.onOriginChanged, this);
|
||||
this.on('rotationChanged', this.onRotationChanged, this);
|
||||
this.on('scaleChanged', this.onScaleChanged, this);
|
||||
const _children = [];
|
||||
if (children) {
|
||||
_children.push(...children.map((shape) => {
|
||||
switch (shape.type) {
|
||||
case 'circle':
|
||||
return new CircleShape(shape);
|
||||
case 'list':
|
||||
return new ShapeList(shape);
|
||||
default:
|
||||
return new PolygonShape(shape);
|
||||
case 'rectangle':
|
||||
return new RectangleShape(shape);
|
||||
}
|
||||
}));
|
||||
const oldShapes = this.children;
|
||||
this.children = _children;
|
||||
this.emit('childrenChanged', oldShapes, this.children);
|
||||
}
|
||||
else {
|
||||
this.children = [];
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
super.destroy();
|
||||
this.off('childrenChanged', this.onChildrenChanged);
|
||||
this.off('originChanged', this.onOriginChanged);
|
||||
this.off('rotationChanged', this.onRotationChanged);
|
||||
this.off('scaleChanged', this.onScaleChanged);
|
||||
for (let i = 0; i < this.children.length; i++) {
|
||||
const shape = this.children[i];
|
||||
shape.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
get aabb() {
|
||||
if (0 === this.children.length) {
|
||||
return [0, 0, 0, 0];
|
||||
}
|
||||
const min = [Infinity, Infinity];
|
||||
const max = [-Infinity, -Infinity];
|
||||
for (let i = 0; i < this.children.length; i++) {
|
||||
const {aabb} = this.children[i];
|
||||
min[0] = aabb[0] < min[0] ? aabb[0] : min[0];
|
||||
min[1] = aabb[1] < min[1] ? aabb[1] : min[1];
|
||||
max[0] = aabb[0] > max[0] ? aabb[0] : max[0];
|
||||
max[1] = aabb[1] > max[1] ? aabb[1] : max[1];
|
||||
}
|
||||
return Rectangle.translated(
|
||||
[min[0], min[1], max[0] - min[0], max[1] - min[1]],
|
||||
this.position,
|
||||
);
|
||||
}
|
||||
|
||||
addChild(shape) {
|
||||
const oldShapes = [...this.children];
|
||||
this.children.push(shape);
|
||||
this.emit('childrenChanged', oldShapes, this.children);
|
||||
}
|
||||
|
||||
intersects(list) {
|
||||
if (0 === this.children.length) {
|
||||
return false;
|
||||
}
|
||||
if (!Rectangle.intersects(this.aabb, list.aabb)) {
|
||||
return false;
|
||||
}
|
||||
// TODO: Quadtrees?
|
||||
for (let i = 0; i < this.children.length; i++) {
|
||||
const lchild = this.children[i];
|
||||
for (let j = 0; j < this.children.length; j++) {
|
||||
const rchild = list.children[j];
|
||||
if (Rectangle.intersects(
|
||||
Rectangle.translated(lchild.aabb, this.position),
|
||||
Rectangle.translated(rchild.aabb, list.position),
|
||||
)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
onChildAabbChanged() {
|
||||
this.emit('aabbChanged');
|
||||
}
|
||||
|
||||
onOriginChanged(oldOrigin) {
|
||||
this.children.forEach((shape) => {
|
||||
shape.emit('parentOriginChanged', oldOrigin, this.origin);
|
||||
});
|
||||
}
|
||||
|
||||
onRotationChanged(oldRotation) {
|
||||
this.children.forEach((shape) => {
|
||||
shape.emit('parentRotationChanged', oldRotation, this.rotation);
|
||||
});
|
||||
}
|
||||
|
||||
onScaleChanged(oldScale) {
|
||||
this.children.forEach((shape) => {
|
||||
shape.emit('parentScaleChanged', oldScale, this.scale);
|
||||
});
|
||||
}
|
||||
|
||||
onChildrenChanged(oldShapes) {
|
||||
oldShapes.forEach((shape) => {
|
||||
shape.off('aabbChanged');
|
||||
});
|
||||
this.children.forEach((shape) => {
|
||||
shape.on('aabbChanged', this.onChildAabbChanged, this);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
79
packages/physics/src/shape/polygon.js
Normal file
79
packages/physics/src/shape/polygon.js
Normal file
|
@ -0,0 +1,79 @@
|
|||
import {Rectangle, Vector, Vertice} from '@avocado/math';
|
||||
|
||||
import Shape from './shape';
|
||||
|
||||
export default class PolygonShape extends Shape {
|
||||
|
||||
constructor(shape) {
|
||||
super(shape);
|
||||
this._translatedVertices = [];
|
||||
this._vertices = [];
|
||||
this.on([
|
||||
'parentOriginChanged',
|
||||
'parentRotationChanged',
|
||||
'parentScaleChanged',
|
||||
'originChanged',
|
||||
'rotationChanged',
|
||||
'scaleChanged',
|
||||
'verticesChanged',
|
||||
], this.onRecalculateVertices, this);
|
||||
if (shape.vertices) {
|
||||
this.vertices = shape.vertices;
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
super.destroy();
|
||||
this.off([
|
||||
'parentOriginChanged',
|
||||
'parentRotationChanged',
|
||||
'parentScaleChanged',
|
||||
'originChanged',
|
||||
'rotationChanged',
|
||||
'scaleChanged',
|
||||
'verticesChanged',
|
||||
], this.onRecalculateVertices);
|
||||
}
|
||||
|
||||
get aabb() {
|
||||
if (0 === this._vertices.length) {
|
||||
return [0, 0, 0, 0];
|
||||
}
|
||||
const min = [Infinity, Infinity];
|
||||
const max = [-Infinity, -Infinity];
|
||||
for (let i = 0; i < this._translatedVertices.length; i++) {
|
||||
const vertice = this._translatedVertices[i];
|
||||
min[0] = vertice[0] < min[0] ? vertice[0] : min[0];
|
||||
min[1] = vertice[1] < min[1] ? vertice[1] : min[1];
|
||||
max[0] = vertice[0] > max[0] ? vertice[0] : max[0];
|
||||
max[1] = vertice[1] > max[1] ? vertice[1] : max[1];
|
||||
}
|
||||
return Rectangle.translated(
|
||||
[min[0], min[1], max[0] - min[0], max[1] - min[1]],
|
||||
this.position,
|
||||
);
|
||||
}
|
||||
|
||||
onRecalculateVertices() {
|
||||
const parentOrigin = this.parent ? this.parent.origin : [0, 0];
|
||||
const origin = Vector.add(this.origin, parentOrigin);
|
||||
const parentRotation = this.parent ? this.parent.rotation : 0;
|
||||
const rotation = this.rotation + parentRotation;
|
||||
const parentScale = this.parent ? this.parent.scale : 1;
|
||||
const scale = this.scale * parentScale;
|
||||
this._translatedVertices = this._vertices.map((vertice) => (
|
||||
Vertice.translate(vertice, origin, rotation, scale)
|
||||
));
|
||||
this.emit('aabbChanged');
|
||||
}
|
||||
|
||||
get vertices() {
|
||||
return this._vertices;
|
||||
}
|
||||
|
||||
set vertices(vertices) {
|
||||
this._vertices = [...vertices];
|
||||
this.emit('verticesChanged');
|
||||
}
|
||||
|
||||
}
|
41
packages/physics/src/shape/rectangle.js
Normal file
41
packages/physics/src/shape/rectangle.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
import {compose} from '@avocado/core';
|
||||
import {Vector} from '@avocado/math';
|
||||
|
||||
import PolygonShape from './polygon';
|
||||
|
||||
const decorate = compose(
|
||||
Vector.Mixin('size', 'width', 'height', {
|
||||
default: [0, 0],
|
||||
track: true,
|
||||
}),
|
||||
);
|
||||
|
||||
export default class RectangleShape extends decorate(PolygonShape) {
|
||||
|
||||
constructor(shape) {
|
||||
super(shape);
|
||||
this.on(['positionChanged', 'sizeChanged'], this.onVerticesChanged, this);
|
||||
if (shape.size) {
|
||||
this.size = shape.size;
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
super.destroy();
|
||||
this.off(['positionChanged', 'sizeChanged'], this.onVerticesChanged);
|
||||
}
|
||||
|
||||
onVerticesChanged() {
|
||||
const halfSize = Vector.scale(this.size, 0.5);
|
||||
const width = this.width - 0.001;
|
||||
const height = this.height - 0.001;
|
||||
const position = Vector.add(this.position, Vector.scale(halfSize, -1));
|
||||
this.vertices = [
|
||||
position,
|
||||
Vector.add(position, [width, 0]),
|
||||
Vector.add(position, [width, height]),
|
||||
Vector.add(position, [0, height]),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
71
packages/physics/src/shape/shape.js
Normal file
71
packages/physics/src/shape/shape.js
Normal file
|
@ -0,0 +1,71 @@
|
|||
import {Property} from '@avocado/core';
|
||||
import {Vector} from '@avocado/math';
|
||||
import {Class, compose, EventEmitter} from '@latus/core';
|
||||
|
||||
const decorate = compose(
|
||||
EventEmitter,
|
||||
Property('parent'),
|
||||
Property('rotation', {
|
||||
default: 0,
|
||||
track: true,
|
||||
}),
|
||||
Property('scale', {
|
||||
default: 1,
|
||||
track: true,
|
||||
}),
|
||||
Vector.Mixin('origin', 'originX', 'originY', {
|
||||
default: [0, 0],
|
||||
track: true,
|
||||
}),
|
||||
Vector.Mixin('position', 'x', 'y', {
|
||||
default: [0, 0],
|
||||
track: true,
|
||||
}),
|
||||
);
|
||||
|
||||
export default class Shape extends decorate(Class) {
|
||||
|
||||
constructor({
|
||||
origin,
|
||||
position,
|
||||
rotation,
|
||||
scale,
|
||||
} = {}) {
|
||||
super();
|
||||
this.on([
|
||||
'originChanged',
|
||||
'rotationChanged',
|
||||
'scaleChanged',
|
||||
], this.onAabbChanged, this);
|
||||
if (origin) {
|
||||
this.origin = origin;
|
||||
}
|
||||
if (position) {
|
||||
this.position = position;
|
||||
}
|
||||
if (rotation) {
|
||||
this.rotation = rotation;
|
||||
}
|
||||
if (scale) {
|
||||
this.scale = scale;
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
get aabb() {
|
||||
return [0, 0, 0, 0];
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.off([
|
||||
'originChanged',
|
||||
'rotationChanged',
|
||||
'scaleChanged',
|
||||
], this.onAabbChanged);
|
||||
}
|
||||
|
||||
onAabbChanged() {
|
||||
this.emit('aabbChanged');
|
||||
}
|
||||
|
||||
}
|
102
packages/physics/src/shape/view.js
Normal file
102
packages/physics/src/shape/view.js
Normal file
|
@ -0,0 +1,102 @@
|
|||
import {
|
||||
Color,
|
||||
Container,
|
||||
Primitives,
|
||||
Renderable,
|
||||
} from '@avocado/graphics';
|
||||
|
||||
import ShapeList from './list';
|
||||
import CircleShape from './circle';
|
||||
import PolygonShape from './polygon';
|
||||
|
||||
export default class ShapeView extends Renderable {
|
||||
|
||||
constructor(shape) {
|
||||
super();
|
||||
this.container = new Container();
|
||||
this.shape = shape;
|
||||
if (shape instanceof PolygonShape) {
|
||||
this.redrawPolygonLines();
|
||||
shape.on('aabbChanged', this.onPolygonShapeAabbChanged, this);
|
||||
}
|
||||
if (shape instanceof CircleShape) {
|
||||
this.redrawCircle();
|
||||
shape.on('aabbChanged', this.onCircleShapeAabbChanged, this);
|
||||
}
|
||||
if (shape instanceof ShapeList) {
|
||||
for (let i = 0; i < shape.children.length; i++) {
|
||||
const child = shape.children[i];
|
||||
const childShapeView = new ShapeView(child);
|
||||
this.container.addChild(childShapeView);
|
||||
}
|
||||
}
|
||||
this.container.position = shape.position;
|
||||
shape.on('positionChanged', this.onShapePositionChanged, this);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
super.destroy();
|
||||
if (this.shape instanceof PolygonShape) {
|
||||
this.shape.off('aabbChanged', this.onPolygonShapeAabbChanged);
|
||||
}
|
||||
if (this.shape instanceof CircleShape) {
|
||||
this.shape.off('aabbChanged', this.onCircleShapeAabbChanged);
|
||||
}
|
||||
this.shape.off('aabbChanged', this.onShapePositionChanged);
|
||||
}
|
||||
|
||||
get internal() {
|
||||
return this.container.internal;
|
||||
}
|
||||
|
||||
onPolygonShapeAabbChanged() {
|
||||
this.redrawPolygonLines();
|
||||
}
|
||||
|
||||
onCircleShapeAabbChanged() {
|
||||
this.redrawCircle();
|
||||
}
|
||||
|
||||
onShapePositionChanged() {
|
||||
this.container.position = this.shape.position;
|
||||
}
|
||||
|
||||
redrawCircle() {
|
||||
const primitives = new Primitives();
|
||||
primitives.drawCircle(
|
||||
this.shape.position,
|
||||
this.shape.radius,
|
||||
Primitives.lineStyle(new Color(255, 0, 255), 1),
|
||||
);
|
||||
this.container.removeAllChildren();
|
||||
this.container.addChild(primitives);
|
||||
}
|
||||
|
||||
redrawPolygonLines() {
|
||||
const primitives = new Primitives();
|
||||
let firstVertice;
|
||||
let lastVertice;
|
||||
for (let i = 0; i < this.shape._translatedVertices.length; i++) {
|
||||
const vertice = this.shape._translatedVertices[i];
|
||||
if (!firstVertice) {
|
||||
firstVertice = vertice;
|
||||
}
|
||||
if (lastVertice) {
|
||||
primitives.drawLine(
|
||||
lastVertice,
|
||||
vertice,
|
||||
Primitives.lineStyle(new Color(255, 0, 255), 1),
|
||||
);
|
||||
}
|
||||
lastVertice = vertice;
|
||||
}
|
||||
primitives.drawLine(
|
||||
lastVertice,
|
||||
firstVertice,
|
||||
Primitives.lineStyle(new Color(255, 0, 255), 1),
|
||||
);
|
||||
this.container.removeAllChildren();
|
||||
this.container.addChild(primitives);
|
||||
}
|
||||
|
||||
}
|
313
packages/physics/src/traits/collider.trait.js
Normal file
313
packages/physics/src/traits/collider.trait.js
Normal file
|
@ -0,0 +1,313 @@
|
|||
import {Actions, compile, Context} from '@avocado/behavior';
|
||||
import {StateProperty, Trait} from '@avocado/entity';
|
||||
import {Rectangle, Vector} from '@avocado/math';
|
||||
import {compose} from '@latus/core';
|
||||
|
||||
const decorate = compose(
|
||||
StateProperty('isCheckingCollisions'),
|
||||
StateProperty('isColliding'),
|
||||
);
|
||||
|
||||
export default class Collider extends decorate(Trait) {
|
||||
|
||||
static behaviorTypes() {
|
||||
return {
|
||||
collidesWith: {
|
||||
advanced: true,
|
||||
type: 'bool',
|
||||
label: 'I would collide with $1.',
|
||||
args: [
|
||||
['other', {
|
||||
type: 'entity',
|
||||
}],
|
||||
],
|
||||
},
|
||||
doesNotCollideWith: {
|
||||
advanced: true,
|
||||
type: 'bool',
|
||||
label: 'I would not collide with $1.',
|
||||
args: [
|
||||
['other', {
|
||||
type: 'entity',
|
||||
}],
|
||||
],
|
||||
},
|
||||
setDoesCollideWith: {
|
||||
advanced: true,
|
||||
type: 'void',
|
||||
label: 'Set $1 as colliding with myself.',
|
||||
args: [
|
||||
['other', {
|
||||
type: 'entity',
|
||||
}],
|
||||
],
|
||||
},
|
||||
setDoesNotCollideWith: {
|
||||
advanced: true,
|
||||
type: 'void',
|
||||
label: 'Set $1 as not colliding with myself.',
|
||||
args: [
|
||||
['other', {
|
||||
type: 'entity',
|
||||
}],
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static defaultParams() {
|
||||
return {
|
||||
activeCollision: false,
|
||||
collidesWithGroups: [
|
||||
'default',
|
||||
],
|
||||
collisionEndActions: {
|
||||
type: 'expressions',
|
||||
expressions: [],
|
||||
},
|
||||
collisionStartActions: {
|
||||
type: 'expressions',
|
||||
expressions: [],
|
||||
},
|
||||
collisionGroup: 'default',
|
||||
isSensor: false,
|
||||
};
|
||||
}
|
||||
|
||||
static defaultState() {
|
||||
return {
|
||||
isCheckingCollisions: true,
|
||||
isColliding: true,
|
||||
};
|
||||
}
|
||||
|
||||
static describeParams() {
|
||||
return {
|
||||
activeCollision: {
|
||||
type: 'bool',
|
||||
label: 'Actively check collisions',
|
||||
},
|
||||
collidesWithGroups: {
|
||||
type: 'object',
|
||||
label: 'Collides with groups',
|
||||
},
|
||||
collisionEndActions: {
|
||||
type: 'expressions',
|
||||
label: 'Collision ending actions',
|
||||
},
|
||||
collisionStartActions: {
|
||||
type: 'expressions',
|
||||
label: 'Collision starting actions',
|
||||
},
|
||||
collisionGroup: {
|
||||
type: 'string',
|
||||
label: 'Collision group',
|
||||
},
|
||||
isSensor: {
|
||||
type: 'bool',
|
||||
label: 'Is sensor',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static describeState() {
|
||||
return {
|
||||
isCheckingCollisions: {
|
||||
type: 'bool',
|
||||
label: 'Is checking collisions',
|
||||
},
|
||||
isColliding: {
|
||||
type: 'bool',
|
||||
label: 'Is able to collide',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static type() {
|
||||
return 'collider';
|
||||
}
|
||||
|
||||
constructor(entity, params, state) {
|
||||
super(entity, params, state);
|
||||
const {
|
||||
collidesWithGroups,
|
||||
collisionEndActions,
|
||||
collisionGroup,
|
||||
collisionStartActions,
|
||||
isSensor,
|
||||
} = this.params;
|
||||
this._collidesWithGroups = collidesWithGroups;
|
||||
this._collisionEndActions = collisionEndActions.length > 0
|
||||
? new Actions(compile(collisionEndActions))
|
||||
: undefined;
|
||||
this._collisionStartActions = collisionStartActions.length > 0
|
||||
? new Actions(compile(collisionStartActions))
|
||||
: undefined;
|
||||
this._collisionGroup = collisionGroup;
|
||||
this._doesNotCollideWith = [];
|
||||
this._isCollidingWith = [];
|
||||
this._isSensor = isSensor;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.releaseAllCollisions();
|
||||
}
|
||||
|
||||
checkActiveCollision() {
|
||||
if (!this.params.activeCollision) {
|
||||
return;
|
||||
}
|
||||
const {layer} = this.entity;
|
||||
if (!layer) {
|
||||
return;
|
||||
}
|
||||
const query = Rectangle.compose(
|
||||
Vector.sub(this.entity.position, [32, 32]),
|
||||
[64, 64],
|
||||
);
|
||||
const thisAabb = Rectangle.translated(
|
||||
this.entity.shape.aabb,
|
||||
this.entity.position,
|
||||
);
|
||||
const entities = layer.visibleEntities(query);
|
||||
for (let i = 0; i < entities.length; ++i) {
|
||||
const entity = entities[i];
|
||||
if (
|
||||
entity === this.entity
|
||||
|| !entity.is('collider')
|
||||
|| !entity.is('shaped')
|
||||
|| entity.is('physical')
|
||||
) {
|
||||
// eslint-disable-next-line no-continue
|
||||
continue;
|
||||
}
|
||||
const otherAabb = Rectangle.translated(
|
||||
entity.shape.aabb,
|
||||
entity.position,
|
||||
);
|
||||
if (Rectangle.intersects(thisAabb, otherAabb)) {
|
||||
if (!this.isCollidingWithEntity(entity)) {
|
||||
this.entity.emit('collisionStart', entity);
|
||||
entity.emit('collisionStart', this.entity);
|
||||
}
|
||||
}
|
||||
else if (this.isCollidingWithEntity(entity)) {
|
||||
this.entity.emit('collisionEnd', entity);
|
||||
entity.emit('collisionEnd', this.entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get collisionGroup() {
|
||||
return this._collisionGroup;
|
||||
}
|
||||
|
||||
get collidesWithGroups() {
|
||||
return this._collidesWithGroups;
|
||||
}
|
||||
|
||||
get isCollidingWith() {
|
||||
return this._isCollidingWith;
|
||||
}
|
||||
|
||||
isCollidingWithEntity(entity) {
|
||||
return -1 !== this._isCollidingWith.indexOf(entity);
|
||||
}
|
||||
|
||||
get isSensor() {
|
||||
return this._isSensor;
|
||||
}
|
||||
|
||||
pushCollisionTickingPromise(actions, other) {
|
||||
const context = new Context({
|
||||
entity: [this.entity, 'entity'],
|
||||
other: [other, 'entity'],
|
||||
});
|
||||
this.entity.addTickingPromise(actions.tickingPromise(context));
|
||||
}
|
||||
|
||||
releaseAllCollisions() {
|
||||
for (let i = 0; i < this._isCollidingWith.length; i++) {
|
||||
const entity = this._isCollidingWith[i];
|
||||
entity.emit('collisionEnd', this.entity);
|
||||
}
|
||||
this._isCollidingWith = [];
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
hooks() {
|
||||
return {
|
||||
|
||||
contextTypeHints: () => [['other', 'entity']],
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
listeners() {
|
||||
return {
|
||||
|
||||
collisionEnd: (other) => {
|
||||
const index = this._isCollidingWith.indexOf(other);
|
||||
if (-1 !== index) {
|
||||
this._isCollidingWith.splice(index, 1);
|
||||
if (this._collisionEndActions) {
|
||||
this.pushCollisionTickingPromise(this._collisionEndActions, other);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
collisionStart: (other) => {
|
||||
const index = this._isCollidingWith.indexOf(other);
|
||||
if (-1 === index) {
|
||||
this._isCollidingWith.push(other);
|
||||
if (this._collisionStartActions) {
|
||||
this.pushCollisionTickingPromise(this._collisionStartActions, other);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
removedFromRoom: () => {
|
||||
this.releaseAllCollisions();
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
methods() {
|
||||
return {
|
||||
|
||||
collidesWith: (entity) => {
|
||||
if (!this.entity.isColliding || !entity.isColliding) {
|
||||
return false;
|
||||
}
|
||||
if (-1 !== this._doesNotCollideWith.indexOf(entity)) {
|
||||
return false;
|
||||
}
|
||||
const {collisionGroup} = entity;
|
||||
return -1 !== this._collidesWithGroups.indexOf(collisionGroup);
|
||||
},
|
||||
|
||||
doesNotCollideWith: (entity) => !this.entity.collidesWith(entity),
|
||||
|
||||
setDoesCollideWith: (entity) => {
|
||||
const index = this._doesNotCollideWith.indexOf(entity);
|
||||
if (-1 !== index) {
|
||||
this._doesNotCollideWith.splice(index, 1);
|
||||
}
|
||||
},
|
||||
|
||||
setDoesNotCollideWith: (entity) => {
|
||||
if (-1 === this._doesNotCollideWith.indexOf(entity)) {
|
||||
this._doesNotCollideWith.push(entity);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
tick() {
|
||||
if (AVOCADO_SERVER) {
|
||||
this.checkActiveCollision();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
154
packages/physics/src/traits/emitted.trait.js
Normal file
154
packages/physics/src/traits/emitted.trait.js
Normal file
|
@ -0,0 +1,154 @@
|
|||
import {Range, Vector} from '@avocado/math';
|
||||
import {Trait} from '@avocado/traits';
|
||||
import {compose} from '@latus/core';
|
||||
|
||||
const decorate = compose(
|
||||
);
|
||||
|
||||
export default class Emitted extends decorate(Trait) {
|
||||
|
||||
static behaviorTypes() {
|
||||
return {
|
||||
particle: {
|
||||
type: 'particle',
|
||||
label: 'Create particle.',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static defaultParams() {
|
||||
return {
|
||||
alpha: {
|
||||
start: 1,
|
||||
end: 1,
|
||||
},
|
||||
force: [0, 0],
|
||||
listed: true,
|
||||
mass: 1,
|
||||
position: null,
|
||||
rotation: {
|
||||
start: 0,
|
||||
add: 0,
|
||||
},
|
||||
scale: {
|
||||
start: 1,
|
||||
end: 1,
|
||||
},
|
||||
transient: true,
|
||||
ttl: 2,
|
||||
velocity: {
|
||||
angle: 0,
|
||||
magnitude: 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static describeParams() {
|
||||
return {
|
||||
alpha: {
|
||||
type: 'object',
|
||||
label: 'Alpha',
|
||||
},
|
||||
force: {
|
||||
type: 'vector',
|
||||
label: 'Force',
|
||||
},
|
||||
listed: {
|
||||
type: 'bool',
|
||||
label: 'Is listed',
|
||||
},
|
||||
mass: {
|
||||
type: 'number',
|
||||
label: 'Mass',
|
||||
},
|
||||
position: {
|
||||
type: 'vector',
|
||||
label: 'Position',
|
||||
},
|
||||
rotation: {
|
||||
type: 'object',
|
||||
label: 'Rotation',
|
||||
},
|
||||
scale: {
|
||||
type: 'object',
|
||||
label: 'Scale',
|
||||
},
|
||||
transient: {
|
||||
type: 'bool',
|
||||
label: 'Kill entity after particle finishes',
|
||||
},
|
||||
ttl: {
|
||||
type: 'number',
|
||||
label: 'Time to live in seconds',
|
||||
},
|
||||
velocity: {
|
||||
type: 'object',
|
||||
label: 'Velocity',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static type() {
|
||||
return 'emitted';
|
||||
}
|
||||
|
||||
constructor(entity, params, state) {
|
||||
super(entity, params, state);
|
||||
this.alphaStart = new Range(this.params.alpha.start);
|
||||
this.alphaEnd = new Range(this.params.alpha.end);
|
||||
this.force = new Vector.Range(this.params.force);
|
||||
this.mass = this.params.mass;
|
||||
if (null !== this.params.position) {
|
||||
this.position = new Vector.Range(this.params.position);
|
||||
}
|
||||
else {
|
||||
this.position = null;
|
||||
}
|
||||
this.rotationStart = new Range(this.params.rotation.start);
|
||||
this.rotationAdd = new Range(this.params.rotation.add);
|
||||
this.scaleStart = new Range(this.params.scale.start);
|
||||
this.scaleEnd = new Range(this.params.scale.end);
|
||||
this.ttl = this.params.ttl;
|
||||
this.velocityAngle = new Range(this.params.velocity.angle);
|
||||
this.velocityMagnitude = new Range(this.params.velocity.magnitude);
|
||||
}
|
||||
|
||||
get isTransientParticle() {
|
||||
return !!this.params.transient;
|
||||
}
|
||||
|
||||
methods() {
|
||||
return {
|
||||
|
||||
particle: () => {
|
||||
const position = null === this.position ? null : this.position.value();
|
||||
const force = this.force.value();
|
||||
return {
|
||||
alpha: {
|
||||
start: this.alphaStart.value(),
|
||||
end: this.alphaEnd.value(),
|
||||
},
|
||||
force,
|
||||
listed: this.params.listed,
|
||||
mass: this.mass,
|
||||
position,
|
||||
rotation: {
|
||||
start: this.rotationStart.value(),
|
||||
add: this.rotationAdd.value(),
|
||||
},
|
||||
scale: {
|
||||
start: this.scaleStart.value(),
|
||||
end: this.scaleEnd.value(),
|
||||
},
|
||||
ttl: this.ttl,
|
||||
velocity: {
|
||||
angle: this.velocityAngle.value(),
|
||||
magnitude: this.velocityMagnitude.value(),
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
272
packages/physics/src/traits/emitter.trait.js
Normal file
272
packages/physics/src/traits/emitter.trait.js
Normal file
|
@ -0,0 +1,272 @@
|
|||
import {PI_180} from '@avocado/math';
|
||||
import {synchronized} from '@avocado/s13n';
|
||||
import {Ticker} from '@avocado/timing';
|
||||
import {Trait} from '@avocado/traits';
|
||||
import {compose} from '@latus/core';
|
||||
import merge from 'deepmerge';
|
||||
import K from 'kefir';
|
||||
|
||||
import Proton from '../proton';
|
||||
|
||||
const decorate = compose(
|
||||
);
|
||||
|
||||
export default (latus) => class Emitter extends decorate(Trait) {
|
||||
|
||||
static behaviorTypes() {
|
||||
return {
|
||||
emitParticleEntity: {
|
||||
cycle: true,
|
||||
type: 'entity',
|
||||
label: 'Create particle.',
|
||||
args: [
|
||||
['entity', {
|
||||
type: 'entity',
|
||||
}],
|
||||
],
|
||||
},
|
||||
emitParticleJson: {
|
||||
type: 'stream',
|
||||
label: 'Create particle.',
|
||||
args: [
|
||||
['json', {
|
||||
type: 'object',
|
||||
}],
|
||||
],
|
||||
},
|
||||
emitParticle: {
|
||||
type: 'stream',
|
||||
label: 'Create particle.',
|
||||
args: [
|
||||
['key', {
|
||||
type: 'string',
|
||||
options: (entity) => (
|
||||
Object.keys(entity.traitInstance('emitter').particles)
|
||||
.reduce((r, key) => ({...r, [key]: key}), {})
|
||||
),
|
||||
}],
|
||||
['json', {
|
||||
type: 'object',
|
||||
}],
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static defaultParams() {
|
||||
return {
|
||||
particles: {},
|
||||
};
|
||||
}
|
||||
|
||||
static describeParams() {
|
||||
return {
|
||||
particles: {
|
||||
type: 'object',
|
||||
label: 'Particles',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static type() {
|
||||
return 'emitter';
|
||||
}
|
||||
|
||||
constructor(entity, params, state) {
|
||||
super(entity, params, state);
|
||||
this.emissions = [];
|
||||
this.emitter = new Proton.Emitter();
|
||||
this.particles = {};
|
||||
this.proton = new Proton();
|
||||
this.proton.addEmitter(this.emitter);
|
||||
this.onParticleDead = this.onParticleDead.bind(this);
|
||||
this.onParticleUpdate = this.onParticleUpdate.bind(this);
|
||||
this.emitter.bindEvent = true;
|
||||
this.emitter.addEventListener('PARTICLE_DEAD', this.onParticleDead);
|
||||
this.emitter.addEventListener('PARTICLE_UPDATE', this.onParticleUpdate);
|
||||
}
|
||||
|
||||
gatherParticles() {
|
||||
const particles = {};
|
||||
const hookParticles = this.entity.invokeHookFlat('particles');
|
||||
for (let i = 0; i < hookParticles.length; i++) {
|
||||
const traitParticles = Object.entries(hookParticles[i]);
|
||||
for (let j = 0; j < traitParticles.length; j++) {
|
||||
const [key, particle] = traitParticles[j];
|
||||
particles[key] = particle;
|
||||
}
|
||||
}
|
||||
const paramParticles = Object.entries(this.params.particles);
|
||||
for (let i = 0; i < paramParticles.length; i++) {
|
||||
const [key, particle] = paramParticles[i];
|
||||
particles[key] = merge(particles[key] || {}, particle);
|
||||
}
|
||||
this.particles = particles;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
onParticleDead(particle) {
|
||||
if (particle.body.isTransientParticle) {
|
||||
particle.body.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
onParticleUpdate(particle) {
|
||||
particle.body.setPosition([particle.p.x, particle.p.y]);
|
||||
/* eslint-disable no-param-reassign */
|
||||
particle.body.opacity = particle.alpha;
|
||||
particle.body.visibleScale = [particle.scale, particle.scale];
|
||||
particle.body.rotation = particle.rotation * PI_180;
|
||||
/* eslint-enable no-param-reassign */
|
||||
}
|
||||
|
||||
hooks() {
|
||||
const hooks = {};
|
||||
hooks.afterDestructionTickers = () => (elapsed) => {
|
||||
this.tick(elapsed);
|
||||
if (0 === this.emitter.particles.length) {
|
||||
this.emitter.destroy();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
return hooks;
|
||||
}
|
||||
|
||||
emitParticleJson(json, emitter) {
|
||||
const {fromName: {Entity}} = synchronized(latus);
|
||||
Entity.loadOrInstance(json).then((particle) => {
|
||||
this.entity.emitParticleEntity(particle);
|
||||
emitter.emit(particle);
|
||||
});
|
||||
}
|
||||
|
||||
listeners() {
|
||||
return {
|
||||
|
||||
traitAdded: () => {
|
||||
this.gatherParticles();
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
methods() {
|
||||
return {
|
||||
|
||||
emitParticleEntity: (entity) => {
|
||||
const particle = entity.particle();
|
||||
const position = particle.position
|
||||
? particle.position
|
||||
: this.entity.position;
|
||||
const initializers = [
|
||||
new Proton.Body(entity),
|
||||
new Proton.Position(new Proton.PointZone(
|
||||
position[0],
|
||||
position[1],
|
||||
)),
|
||||
new Proton.Mass(particle.mass),
|
||||
new Proton.Life(particle.ttl),
|
||||
new Proton.Velocity(
|
||||
particle.velocity.magnitude,
|
||||
particle.velocity.angle,
|
||||
'polar',
|
||||
),
|
||||
];
|
||||
const behaviors = [
|
||||
new Proton.Alpha(
|
||||
particle.alpha.start,
|
||||
particle.alpha.end,
|
||||
),
|
||||
new Proton.Force(
|
||||
particle.force[0],
|
||||
particle.force[1],
|
||||
),
|
||||
new Proton.Rotate(
|
||||
particle.rotation.start,
|
||||
particle.rotation.add,
|
||||
'add',
|
||||
),
|
||||
new Proton.Scale(
|
||||
particle.scale.start,
|
||||
particle.scale.end,
|
||||
),
|
||||
];
|
||||
const protonParticle = this.emitter.createParticle(
|
||||
initializers,
|
||||
behaviors,
|
||||
);
|
||||
entity.on('destroy', () => {
|
||||
this.emitter.removeParticle(protonParticle);
|
||||
});
|
||||
if (particle.listed) {
|
||||
this.entity.list.addEntity(entity);
|
||||
}
|
||||
// Prime.
|
||||
this.onParticleUpdate(protonParticle);
|
||||
return entity;
|
||||
},
|
||||
|
||||
emitParticleJson: (json) => {
|
||||
let {
|
||||
count = 1,
|
||||
// eslint-disable-next-line prefer-const
|
||||
rate = 0,
|
||||
} = json;
|
||||
const stream = K.stream((emitter) => {
|
||||
if (0 === rate) {
|
||||
for (let i = 0; i < count; ++i) {
|
||||
this.emitParticleJson(json, emitter);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const ticker = new Ticker(rate);
|
||||
this.emitParticleJson(json, emitter);
|
||||
count -= 1;
|
||||
if (count > 0) {
|
||||
const removeEmission = () => {
|
||||
const index = this.emissions.indexOf(ticker);
|
||||
if (-1 !== index) {
|
||||
this.emissions.splice(index, 1);
|
||||
}
|
||||
emitter.end();
|
||||
};
|
||||
this.entity.on('destroy', removeEmission);
|
||||
ticker.on('tick', () => {
|
||||
this.emitParticleJson(json, emitter);
|
||||
if (0 >= --count) {
|
||||
removeEmission();
|
||||
}
|
||||
});
|
||||
this.emissions.push(ticker);
|
||||
return;
|
||||
}
|
||||
}
|
||||
emitter.end();
|
||||
});
|
||||
// Always make sure something listens...
|
||||
stream.onEnd(() => {});
|
||||
return stream;
|
||||
},
|
||||
|
||||
emitParticle: (key, json = {}) => {
|
||||
const particleJson = this.particles[key];
|
||||
if (!particleJson) {
|
||||
return undefined;
|
||||
}
|
||||
const mergedJson = merge({}, particleJson, json);
|
||||
return this.entity.emitParticleJson(mergedJson);
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
tick(elapsed) {
|
||||
this.emitter.update(elapsed);
|
||||
for (let i = 0; i < this.emissions.length; i++) {
|
||||
this.emissions[i].tick(elapsed);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
169
packages/physics/src/traits/physical.trait.js
Normal file
169
packages/physics/src/traits/physical.trait.js
Normal file
|
@ -0,0 +1,169 @@
|
|||
import {StateProperty} from '@avocado/entity';
|
||||
import {Vector} from '@avocado/math';
|
||||
import {Trait} from '@avocado/traits';
|
||||
import {compose} from '@latus/core';
|
||||
|
||||
import {BodyView} from '../body-view';
|
||||
|
||||
const decorate = compose(
|
||||
StateProperty('addedToPhysics', {
|
||||
track: true,
|
||||
}),
|
||||
);
|
||||
|
||||
export default class Physical extends decorate(Trait) {
|
||||
|
||||
static behaviorTypes() {
|
||||
return {
|
||||
applyForce: {
|
||||
type: 'void',
|
||||
label: 'Apply force.',
|
||||
args: [
|
||||
['force', {
|
||||
type: 'vector',
|
||||
}],
|
||||
],
|
||||
},
|
||||
applyImpulse: {
|
||||
type: 'void',
|
||||
label: 'Apply impulse.',
|
||||
args: [
|
||||
['impulse', {
|
||||
type: 'vector',
|
||||
}],
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static defaultState() {
|
||||
return {
|
||||
addedToPhysics: true,
|
||||
};
|
||||
}
|
||||
|
||||
static describeState() {
|
||||
return {
|
||||
addedToPhysics: {
|
||||
type: 'bool',
|
||||
label: 'Added to physics',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static type() {
|
||||
return 'physical';
|
||||
}
|
||||
|
||||
constructor(entity, params, state) {
|
||||
super(entity, params, state);
|
||||
this._body = undefined;
|
||||
this.bodyView = undefined;
|
||||
this._world = undefined;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.world = undefined;
|
||||
}
|
||||
|
||||
addToWorld() {
|
||||
const world = this._world;
|
||||
if (world) {
|
||||
const body = world.createBody(this.entity.shape);
|
||||
world.associateBodyWithEntity(body, this.entity);
|
||||
body.setCollisionForEntity(this.entity);
|
||||
world.addBody(body);
|
||||
this._body = body;
|
||||
if (AVOCADO_CLIENT) {
|
||||
if (this.entity.is('visible') && this.entity.is('debuggable')) {
|
||||
this.bodyView = new BodyView(body);
|
||||
this.bodyView.position = Vector.scale(this.entity.position, -1);
|
||||
this.bodyView.visible = this.entity.isDebugging;
|
||||
this.bodyView.zIndex = 101;
|
||||
this.entity.container.addChild(this.bodyView);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get body() {
|
||||
return this._body;
|
||||
}
|
||||
|
||||
removeFromWorld() {
|
||||
if (this._world && this._body) {
|
||||
this._world.removeBody(this._body);
|
||||
}
|
||||
this._body = undefined;
|
||||
if (this.bodyView) {
|
||||
if (this.entity.is('visible')) {
|
||||
this.entity.container.removeChild(this.bodyView);
|
||||
}
|
||||
this.bodyView.destroy();
|
||||
}
|
||||
this.bodyView = undefined;
|
||||
}
|
||||
|
||||
set world(world) {
|
||||
this.removeFromWorld();
|
||||
this._world = world;
|
||||
this.addToWorld();
|
||||
}
|
||||
|
||||
listeners() {
|
||||
return {
|
||||
|
||||
addedToRoom: () => {
|
||||
this.entity.world = this.entity.room.world;
|
||||
},
|
||||
|
||||
addedToPhysicsChanged: () => {
|
||||
if (this.entity.addedToPhysics) {
|
||||
if (!this._body) {
|
||||
this.addToWorld();
|
||||
}
|
||||
}
|
||||
else if (this._body) {
|
||||
this.removeFromWorld();
|
||||
}
|
||||
},
|
||||
|
||||
isDyingChanged: (_, isDying) => {
|
||||
this.entity.addedToPhysics = !isDying;
|
||||
},
|
||||
|
||||
positionChanged: () => {
|
||||
if (this._body) {
|
||||
const {position} = this.entity;
|
||||
this._body.position = position;
|
||||
}
|
||||
},
|
||||
|
||||
removedFromRoom: () => {
|
||||
if (this._body) {
|
||||
this.removeFromWorld();
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
methods() {
|
||||
return {
|
||||
|
||||
applyForce: (force) => {
|
||||
if (this._world && this._body) {
|
||||
this._body.applyForce(force);
|
||||
}
|
||||
},
|
||||
|
||||
applyImpulse: (impulse) => {
|
||||
if (this._world && this._body) {
|
||||
this._body.applyImpulse(impulse);
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
68
packages/physics/src/traits/shaped.trait.js
Normal file
68
packages/physics/src/traits/shaped.trait.js
Normal file
|
@ -0,0 +1,68 @@
|
|||
import {compose} from '@avocado/core';
|
||||
import {Trait} from '@avocado/entity';
|
||||
|
||||
import shapeFromJSON from '../shape/from-json';
|
||||
import ShapeView from '../shape/view';
|
||||
|
||||
const decorate = compose(
|
||||
);
|
||||
|
||||
export default class Shaped extends decorate(Trait) {
|
||||
|
||||
static defaultParams() {
|
||||
return {
|
||||
shape: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
static describeParams() {
|
||||
return {
|
||||
shape: {
|
||||
type: 'object',
|
||||
label: 'Shape',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static type() {
|
||||
return 'shaped';
|
||||
}
|
||||
|
||||
constructor(entity, params, state) {
|
||||
super(entity, params, state);
|
||||
this._shape = shapeFromJSON(this.params.shape);
|
||||
this.shapeView = undefined;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this._shape.destroy();
|
||||
if (this.shapeView) {
|
||||
this.shapeView.destroy();
|
||||
this.shapeView = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
get shape() {
|
||||
return this._shape;
|
||||
}
|
||||
|
||||
listeners() {
|
||||
return {
|
||||
|
||||
traitAdded: () => {
|
||||
if (AVOCADO_CLIENT) {
|
||||
if (this.entity.is('visible') && this.entity.is('debuggable')) {
|
||||
if (!this.shapeView) {
|
||||
this.shapeView = new ShapeView(this.entity.shape);
|
||||
this.shapeView.visible = this.entity.isDebugging;
|
||||
this.shapeView.zIndex = 100;
|
||||
this.entity.container.addChild(this.shapeView);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
3
packages/physics/webpack.config.js
Normal file
3
packages/physics/webpack.config.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
const neutrino = require('neutrino');
|
||||
|
||||
module.exports = neutrino(require(`${__dirname}/.neutrinorc`)).webpack();
|
7788
packages/physics/yarn.lock
Normal file
7788
packages/physics/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -20,8 +20,8 @@
|
|||
"index.js.map"
|
||||
],
|
||||
"dependencies": {
|
||||
"@avocado/core": "^2.0.0",
|
||||
"@latus/core": "^2.0.0",
|
||||
"@avocado/core": "2.0.0",
|
||||
"@latus/core": "2.0.0",
|
||||
"debug": "4.3.1",
|
||||
"deepmerge": "^4.2.2",
|
||||
"uuid": "^8.3.2"
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
export {default} from './resource';
|
||||
export {default as Resource} from './resource';
|
||||
export {default as JsonResource} from './json-resource';
|
||||
|
|
57
packages/resource/src/json-resource.js
Normal file
57
packages/resource/src/json-resource.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
import merge from 'deepmerge';
|
||||
|
||||
import Resource from './resource';
|
||||
|
||||
const {
|
||||
SIDE,
|
||||
} = process.env;
|
||||
|
||||
export default class JsonResource extends Resource {
|
||||
|
||||
static async extendJson(json) {
|
||||
if (json.extends) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
json.extends = await this.read(json.extends);
|
||||
}
|
||||
return this.mergeJson(json);
|
||||
}
|
||||
|
||||
static async load(json) {
|
||||
const {extends: uri} = json;
|
||||
const resource = new this(await this.extendJson(json));
|
||||
resource.uri = uri;
|
||||
return resource;
|
||||
}
|
||||
|
||||
static mergeJson(json) {
|
||||
let result = JSON.parse(JSON.stringify(json));
|
||||
if (result.extends) {
|
||||
const {extends: xtends, ...rest} = result;
|
||||
result = merge(
|
||||
this.mergeJson(xtends),
|
||||
rest,
|
||||
{
|
||||
arrayMerge: (l, r) => r,
|
||||
},
|
||||
);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static async read(uri) {
|
||||
const buffer = await super.read(uri);
|
||||
let string;
|
||||
if ('client' === SIDE) {
|
||||
const decoder = new TextDecoder();
|
||||
string = decoder.decode(buffer);
|
||||
}
|
||||
else {
|
||||
// eslint-disable-next-line global-require
|
||||
const {StringDecoder} = require('string_decoder');
|
||||
const decoder = new StringDecoder();
|
||||
string = decoder.end(buffer);
|
||||
}
|
||||
return this.extendJson(JSON.parse(string));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
import merge from 'deepmerge';
|
||||
import {v4 as uuid} from 'uuid';
|
||||
|
||||
import {Property} from '@avocado/core';
|
||||
|
@ -20,59 +19,31 @@ export default class Resource extends decorate(Class) {
|
|||
this.instanceUuid = uuid();
|
||||
}
|
||||
|
||||
static baseUri = 'resource';
|
||||
|
||||
fromJSON({uri}) {
|
||||
if (uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
static load(uri) {
|
||||
return this.read(uri).then((json) => new this({uri, ...json}));
|
||||
}
|
||||
|
||||
static async loadOrInstance(json) {
|
||||
if (json.uri) {
|
||||
const loaded = await this.read(json.uri);
|
||||
return new this(loaded, json);
|
||||
}
|
||||
return new this(json);
|
||||
static async load(uri) {
|
||||
const buffer = await this.read(uri);
|
||||
const resource = new this(buffer);
|
||||
resource.uri = uri;
|
||||
return resource;
|
||||
}
|
||||
|
||||
static async read(uri) {
|
||||
if (!this.readCache) {
|
||||
this.readCache = {};
|
||||
}
|
||||
if (this.readCache[uri]) {
|
||||
return JSON.parse(JSON.stringify(await this.readCache[uri]));
|
||||
}
|
||||
if ('client' === SIDE) {
|
||||
const response = await fetch(uri);
|
||||
this.readCache[uri] = response.json();
|
||||
return response.arrayBuffer();
|
||||
}
|
||||
else {
|
||||
this.readCache[uri] = new Promise((resolve, reject) => {
|
||||
// eslint-disable-next-line global-require
|
||||
const [fs, path] = [require('fs'), require('path')];
|
||||
fs.readFile(path.join(process.cwd(), this.baseUri, uri), (error, buffer) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve(JSON.parse(buffer.toString('utf8')));
|
||||
});
|
||||
return new Promise((resolve, reject) => {
|
||||
// eslint-disable-next-line global-require
|
||||
const [fs, path] = [require('fs'), require('path')];
|
||||
fs.readFile(path.join(process.cwd(), this.root, uri), (error, buffer) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve(buffer);
|
||||
});
|
||||
}
|
||||
const json = await this.readCache[uri];
|
||||
return json.extends ? merge(await this.read(json.extends), json) : json;
|
||||
});
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
uri: this.uri,
|
||||
};
|
||||
}
|
||||
static root = 'resource';
|
||||
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@avocado/core@^2.0.0":
|
||||
"@avocado/core@2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fcore/-/core-2.0.0.tgz#636ea3c3b54a38538c59485080f6a0e48f1798e7"
|
||||
integrity sha512-VW+ygRHaQQwaL5rKZGm0n0DNfvj+H89qQx+67veCUmUuRav3XAeE0iYs8Lgfc3CJLPz/alqt/dVPMXd5QDR+Mg==
|
||||
resolved "https://npm.i12e.cha0s.io/@avocado%2fcore/-/core-2.0.0.tgz#ac7f912135c1cbb433b825c0fd1aa9a14b91ffed"
|
||||
integrity sha512-PX6UVuhcmUaf2yzhTEd+dUle/Z3JRWJXm7NwGN63oL3w5QqUVOEzqUQNkKem2b+mlyJl56UnWzZJYYLixTOzvQ==
|
||||
dependencies:
|
||||
debug "4.3.1"
|
||||
|
||||
|
@ -899,7 +899,7 @@
|
|||
minimatch "^3.0.4"
|
||||
strip-json-comments "^3.1.1"
|
||||
|
||||
"@latus/core@^2.0.0":
|
||||
"@latus/core@2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://npm.i12e.cha0s.io/@latus%2fcore/-/core-2.0.0.tgz#4447b4bba265b684035be1dacefd6ba4913a47d4"
|
||||
integrity sha512-OSsbO4wvVJFPZTMRDX5LAXOA+MQY8FOSK7PcTEJKeiRqOMeMIVkZc6q6KNlUIYivE+87rlM7S/CctHoA7uvQvg==
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
"index.js.map"
|
||||
],
|
||||
"dependencies": {
|
||||
"@latus/core": "^2.0.0",
|
||||
"@latus/socket": "^2.0.0",
|
||||
"@latus/core": "2.0.0",
|
||||
"@latus/socket": "2.0.0",
|
||||
"debug": "4.3.1",
|
||||
"msgpack-lite": "^0.1.26"
|
||||
},
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {gather} from '@latus/core';
|
||||
|
||||
export {default as normalize} from './normalize';
|
||||
export * from './packets';
|
||||
export {default as Synchronized} from './synchronized';
|
||||
|
||||
|
|
23
packages/s13n/src/normalize.js
Normal file
23
packages/s13n/src/normalize.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import {normalize, Packet} from '@latus/socket';
|
||||
|
||||
export default (latus, packets) => {
|
||||
if (!packets) {
|
||||
return [];
|
||||
}
|
||||
// Packet
|
||||
if (!Array.isArray(packets)) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
packets = [packets];
|
||||
}
|
||||
if (
|
||||
// [Packet, ...]
|
||||
!(packets[0] instanceof Packet)
|
||||
// [name, data]
|
||||
&& !Array.isArray(packets[0])
|
||||
) {
|
||||
// [[name, data...], ...]
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
packets = [packets];
|
||||
}
|
||||
return packets.map((packet) => normalize(latus, packet));
|
||||
};
|
|
@ -1,5 +1,4 @@
|
|||
import {normalize, Packet} from '@latus/socket';
|
||||
|
||||
import normalize from './normalize';
|
||||
import SynchronizedCreatePacket from './packets/synchronized-create';
|
||||
import SynchronizedDestroyPacket from './packets/synchronized-destroy';
|
||||
|
||||
|
@ -58,36 +57,19 @@ export default function SynchronizedMixin(Superclass) {
|
|||
if (this._idempotentPackets.length > 0) {
|
||||
return this._idempotentPackets;
|
||||
}
|
||||
let packets = this.packets(informed);
|
||||
if (!packets) {
|
||||
return [];
|
||||
}
|
||||
// Packet
|
||||
if (!Array.isArray(packets)) {
|
||||
packets = [packets];
|
||||
}
|
||||
if (
|
||||
// [Packet, ...]
|
||||
!(packets[0] instanceof Packet)
|
||||
// [name, data]
|
||||
&& !Array.isArray(packets[0])
|
||||
) {
|
||||
// [[name, data...], ...]
|
||||
packets = [packets];
|
||||
}
|
||||
const normalized = packets.map((packet) => normalize(latus, packet));
|
||||
const packets = normalize(latus, this.packets(informed));
|
||||
// Embed synchronization info.
|
||||
const id = this.synchronizationId();
|
||||
for (let i = 0; i < normalized.length; i++) {
|
||||
normalized[i].data.synchronized = {
|
||||
for (let i = 0; i < packets.length; i++) {
|
||||
packets[i].data.synchronized = {
|
||||
id,
|
||||
type: this.constructor.s13nType,
|
||||
};
|
||||
}
|
||||
if (this.packetsAreIdempotent()) {
|
||||
this._idempotentPackets = normalized;
|
||||
this._idempotentPackets = packets;
|
||||
}
|
||||
return normalized;
|
||||
return packets;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
|
|
1
packages/sound/.eslintrc.js
Normal file
1
packages/sound/.eslintrc.js
Normal file
|
@ -0,0 +1 @@
|
|||
module.exports = require('../../config/.eslintrc');
|
5
packages/sound/.gitignore
vendored
Normal file
5
packages/sound/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
**/*.js
|
||||
**/*.map
|
||||
!/.*
|
||||
!/webpack.config.js
|
||||
!src/**/*.js
|
1
packages/sound/.neutrinorc.js
Normal file
1
packages/sound/.neutrinorc.js
Normal file
|
@ -0,0 +1 @@
|
|||
module.exports = require('../../config/.neutrinorc');
|
42
packages/sound/package.json
Normal file
42
packages/sound/package.json
Normal file
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"name": "@avocado/package",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"author": "cha0s",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"build": "NODE_PATH=./node_modules webpack --mode production",
|
||||
"clean": "rm -rf yarn.lock node_modules && yarn",
|
||||
"dev": "NODE_PATH=./node_modules webpack --mode development",
|
||||
"forcepub": "npm unpublish --force $(node -e 'const {name, version} = require(`./package.json`); process.stdout.write(`${name}@${version}`)') && npm publish",
|
||||
"link": "node -e \"Object.keys(require('./package.json').dependencies).filter((m) => 0 === m.indexOf('@latus/')).forEach((m) => require('child_process').spawn('yarn', ['link', m]));\"",
|
||||
"lint": "NODE_PATH=./node_modules eslint --format codeframe --ext mjs,js .",
|
||||
"test": "NODE_PATH=./node_modules mocha --config ../../config/.mocharc.js",
|
||||
"unlink": "node -e \"Object.keys(require('./package.json').dependencies).filter((m) => 0 === m.indexOf('@latus/')).forEach((m) => require('child_process').spawn('yarn', ['unlink', m]));\" && yarn install --force",
|
||||
"watch": "NODE_PATH=./node_modules webpack --watch --mode development"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.js.map"
|
||||
],
|
||||
"dependencies": {
|
||||
"@avocado/resource": "^2.0.0",
|
||||
"@avocado/traits": "^2.0.0",
|
||||
"debug": "4.3.1",
|
||||
"howler": "2.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@neutrinojs/airbnb-base": "^9.4.0",
|
||||
"@neutrinojs/copy": "9.4.0",
|
||||
"@neutrinojs/mocha": "^9.4.0",
|
||||
"@neutrinojs/react": "^9.4.0",
|
||||
"chai": "4.2.0",
|
||||
"eslint": "^7",
|
||||
"eslint-import-resolver-webpack": "0.13.0",
|
||||
"mocha": "^8",
|
||||
"neutrino": "^9.4.0",
|
||||
"webpack": "^4",
|
||||
"webpack-cli": "^3",
|
||||
"webpack-node-externals": "2.5.2"
|
||||
}
|
||||
}
|
1
packages/sound/src/index.js
Normal file
1
packages/sound/src/index.js
Normal file
|
@ -0,0 +1 @@
|
|||
export {default} from './sound';
|
48
packages/sound/src/sound.js
Normal file
48
packages/sound/src/sound.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
import {Howl} from 'howler';
|
||||
|
||||
import {JsonResource} from '@avocado/resource';
|
||||
|
||||
export default class Sound extends JsonResource {
|
||||
|
||||
constructor({interval = 0, volume = 1, sound} = {}) {
|
||||
super();
|
||||
this.handle = undefined;
|
||||
this.interval = interval;
|
||||
this.originalVolume = volume;
|
||||
this.sound = sound;
|
||||
this.timestamp = 0;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
if (this.sound) {
|
||||
this.sound.unload();
|
||||
}
|
||||
}
|
||||
|
||||
static async extendJson(json) {
|
||||
const extended = await super.extendJson(json);
|
||||
extended.sound = new Howl(json);
|
||||
await new Promise((resolve) => {
|
||||
extended.sound.once('load', resolve);
|
||||
});
|
||||
return extended;
|
||||
}
|
||||
|
||||
play() {
|
||||
if (this.interval > 0 && this.timestamp > 0) {
|
||||
if ((Date.now() - this.timestamp) < this.interval) {
|
||||
const volume = this.sound.volume(this.handle);
|
||||
this.sound.volume(
|
||||
Math.min(1, Math.min(volume, this.originalVolume * 20)),
|
||||
this.handle,
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.handle = this.sound.play();
|
||||
if (this.interval > 0) {
|
||||
this.timestamp = Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
108
packages/sound/src/traits/audible.trait.js
Normal file
108
packages/sound/src/traits/audible.trait.js
Normal file
|
@ -0,0 +1,108 @@
|
|||
import {Trait} from '@avocado/traits';
|
||||
|
||||
import Sound from '../sound';
|
||||
|
||||
export default class Audible extends Trait {
|
||||
|
||||
static behaviorTypes() {
|
||||
return {
|
||||
hasSound: {
|
||||
type: 'bool',
|
||||
label: 'Has $1 sound',
|
||||
args: [
|
||||
['key', {
|
||||
type: 'string',
|
||||
}],
|
||||
],
|
||||
},
|
||||
playSound: {
|
||||
type: 'void',
|
||||
label: 'Play the $1 sound.',
|
||||
args: [
|
||||
['key', {
|
||||
type: 'string',
|
||||
options: (entity) => this.optionsForSounds(entity),
|
||||
}],
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static defaultParams() {
|
||||
return {
|
||||
sounds: {},
|
||||
};
|
||||
}
|
||||
|
||||
static describeParams() {
|
||||
return {
|
||||
sounds: {
|
||||
type: 'object',
|
||||
label: 'Sounds',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static type() {
|
||||
return 'audible';
|
||||
}
|
||||
|
||||
hydrate() {
|
||||
if (AVOCADO_CLIENT) {
|
||||
this.loadSounds();
|
||||
}
|
||||
}
|
||||
|
||||
constructor(entity, params, state) {
|
||||
super(entity, params, state);
|
||||
this._sounds = this.params.sounds;
|
||||
this.sounds = {};
|
||||
}
|
||||
|
||||
destroy() {
|
||||
const sounds = Object.values(this.sounds);
|
||||
for (let i = 0; i < sounds.length; i++) {
|
||||
sounds[i].destroy();
|
||||
}
|
||||
}
|
||||
|
||||
loadSounds() {
|
||||
const keys = Object.keys(this._sounds);
|
||||
const soundPromises = [];
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
const soundJSON = this._sounds[key];
|
||||
soundPromises.push(Sound.load(soundJSON.uri));
|
||||
}
|
||||
const soundsPromise = Promise.all(soundPromises);
|
||||
soundsPromise.then((sounds) => {
|
||||
for (let i = 0; i < sounds.length; i++) {
|
||||
const key = keys[i];
|
||||
const sound = sounds[i];
|
||||
this.sounds[key] = sound;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
methods() {
|
||||
return {
|
||||
|
||||
hasSound: (key) => !!this.sounds[key],
|
||||
|
||||
playSound: (key) => {
|
||||
const sound = this.sounds[key];
|
||||
if (!sound) {
|
||||
return;
|
||||
}
|
||||
sound.play();
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
static optionsForSounds(entity) {
|
||||
return Object.keys(entity.traitInstance('audible').params.sounds)
|
||||
.reduce((r, key) => ({...r, [key]: key}), {});
|
||||
}
|
||||
|
||||
}
|
3
packages/sound/webpack.config.js
Normal file
3
packages/sound/webpack.config.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
const neutrino = require('neutrino');
|
||||
|
||||
module.exports = neutrino(require(`${__dirname}/.neutrinorc`)).webpack();
|
7522
packages/sound/yarn.lock
Normal file
7522
packages/sound/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -20,13 +20,13 @@
|
|||
"index.js.map"
|
||||
],
|
||||
"dependencies": {
|
||||
"@avocado/core": "^2.0.0",
|
||||
"@avocado/entity": "^2.0.0",
|
||||
"@avocado/graphics": "^2.0.0",
|
||||
"@avocado/math": "^2.0.0",
|
||||
"@avocado/resource": "^2.0.0",
|
||||
"@latus/core": "^2.0.0",
|
||||
"@latus/socket": "^2.0.0",
|
||||
"@avocado/core": "2.0.0",
|
||||
"@avocado/graphics": "2.0.0",
|
||||
"@avocado/math": "2.0.0",
|
||||
"@avocado/resource": "2.0.0",
|
||||
"@avocado/traits": "^2.0.0",
|
||||
"@latus/core": "2.0.0",
|
||||
"@latus/socket": "2.0.0",
|
||||
"debug": "4.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import {compose, EventEmitter, Property} from '@avocado/core';
|
||||
import {Property} from '@avocado/core';
|
||||
import {Rectangle, Vector} from '@avocado/math';
|
||||
import {Resource} from '@avocado/resource';
|
||||
import {compose, EventEmitter} from '@latus/core';
|
||||
|
||||
import TimedIndex from './timed-index';
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user