@combos-fun/engine 0.0.53 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-skill.md +1 -1
- package/combos-plugin.json +0 -1
- package/dist/engine.cjs.js +87 -198
- package/dist/engine.cjs.js.map +1 -1
- package/dist/engine.cjs.prod.js +1 -1
- package/dist/engine.d.ts +20 -115
- package/dist/engine.esm.js +88 -198
- package/dist/engine.esm.js.map +1 -1
- package/package.json +3 -3
- package/references/public-api.md +2 -2
package/dist/engine.esm.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import EventEmitter from 'eventemitter3';
|
|
2
2
|
import { isEqual, isObject } from 'lodash-es';
|
|
3
|
-
import { __decorate } from 'tslib';
|
|
4
|
-
import { Field } from '@combos-fun/inspector-decorator';
|
|
5
3
|
import { ResourceState, ResourceType, Resource as Resource$1, Loader, XhrLoadStrategy, VideoLoadStrategy, MediaElementLoadStrategy, XhrResponseType, ImageLoadStrategy, AudioLoadStrategy, AbstractLoadStrategy } from 'resource-loader';
|
|
6
4
|
|
|
7
5
|
/**
|
|
@@ -10,10 +8,10 @@ import { ResourceState, ResourceType, Resource as Resource$1, Loader, XhrLoadStr
|
|
|
10
8
|
* @returns component' name
|
|
11
9
|
* @example
|
|
12
10
|
* ```typescript
|
|
13
|
-
* import {
|
|
11
|
+
* import { Component } from '@combos-fun/engine'
|
|
14
12
|
*
|
|
15
|
-
* assert(getComponentName(
|
|
16
|
-
* assert(getComponentName(new
|
|
13
|
+
* assert(getComponentName(MyComponent) === 'MyComponent')
|
|
14
|
+
* assert(getComponentName(new MyComponent()) === 'MyComponent')
|
|
17
15
|
* ```
|
|
18
16
|
*/
|
|
19
17
|
function getComponentName(component) {
|
|
@@ -108,14 +106,38 @@ function removeObjectCache(component) {
|
|
|
108
106
|
* @param {pureObserverProp} param0.prop - pure observer prop
|
|
109
107
|
* @param {ObserverType} param0.type - observer type
|
|
110
108
|
*/
|
|
111
|
-
function addObserver({ systemName, componentName, component, prop, type }) {
|
|
109
|
+
function addObserver({ systemName, componentName, component, prop, type, gameObject }) {
|
|
112
110
|
systemInstance[systemName]?.componentObserver?.add({
|
|
113
111
|
component,
|
|
114
112
|
prop,
|
|
115
113
|
type,
|
|
116
114
|
componentName,
|
|
115
|
+
gameObject,
|
|
117
116
|
});
|
|
118
117
|
}
|
|
118
|
+
const GAME_OBJECT_OBSERVER = 'GameObject';
|
|
119
|
+
/**
|
|
120
|
+
* Push a GameObject field change (parent / inScene) to systems that observe `GameObject`.
|
|
121
|
+
* Hierarchy is not a Component; callers must notify explicitly from addChild / scene.
|
|
122
|
+
*/
|
|
123
|
+
function notifyGameObjectProp(gameObject, propName, type = ObserverType.CHANGE) {
|
|
124
|
+
if (!gameObject)
|
|
125
|
+
return;
|
|
126
|
+
const prop = { prop: [propName], deep: false };
|
|
127
|
+
for (const systemName in observerInfos) {
|
|
128
|
+
const info = observerInfos[systemName]?.[GAME_OBJECT_OBSERVER];
|
|
129
|
+
if (!info?.some(p => p.prop[0] === propName))
|
|
130
|
+
continue;
|
|
131
|
+
addObserver({
|
|
132
|
+
systemName,
|
|
133
|
+
componentName: GAME_OBJECT_OBSERVER,
|
|
134
|
+
component: undefined,
|
|
135
|
+
gameObject,
|
|
136
|
+
prop,
|
|
137
|
+
type,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
119
141
|
function pushToQueue({ prop, component, componentName, }) {
|
|
120
142
|
for (const systemName in observerInfos) {
|
|
121
143
|
const observerInfo = observerInfos[systemName] || {};
|
|
@@ -291,154 +313,6 @@ function setSystemObserver(system, S) {
|
|
|
291
313
|
systemInstance[S.systemName] = system;
|
|
292
314
|
}
|
|
293
315
|
|
|
294
|
-
/** Basic component for gameObject, See {@link TransformParams} */
|
|
295
|
-
class Transform extends Component {
|
|
296
|
-
constructor() {
|
|
297
|
-
super(...arguments);
|
|
298
|
-
this.name = 'Transform';
|
|
299
|
-
this._parent = null;
|
|
300
|
-
/** Whether this transform in a scene object */
|
|
301
|
-
this.inScene = false;
|
|
302
|
-
/** Child transform components */
|
|
303
|
-
this.children = [];
|
|
304
|
-
this.position = { x: 0, y: 0 };
|
|
305
|
-
this.size = { width: 0, height: 0 };
|
|
306
|
-
this.origin = { x: 0, y: 0 };
|
|
307
|
-
this.anchor = { x: 0, y: 0 };
|
|
308
|
-
this.scale = { x: 1, y: 1 };
|
|
309
|
-
this.skew = { x: 0, y: 0 };
|
|
310
|
-
this.rotation = 0;
|
|
311
|
-
}
|
|
312
|
-
/**
|
|
313
|
-
* component's name
|
|
314
|
-
* @readonly
|
|
315
|
-
*/
|
|
316
|
-
static { this.componentName = 'Transform'; }
|
|
317
|
-
/**
|
|
318
|
-
* Init component
|
|
319
|
-
* @param params - Transform init data
|
|
320
|
-
*/
|
|
321
|
-
init(params = {}) {
|
|
322
|
-
const props = ['position', 'size', 'origin', 'anchor', 'scale', 'skew'];
|
|
323
|
-
for (const key of props) {
|
|
324
|
-
Object.assign(this[key], params[key]);
|
|
325
|
-
}
|
|
326
|
-
this.rotation = params.rotation ?? this.rotation;
|
|
327
|
-
}
|
|
328
|
-
set parent(val) {
|
|
329
|
-
if (val) {
|
|
330
|
-
val.addChild(this);
|
|
331
|
-
}
|
|
332
|
-
else if (this.parent) {
|
|
333
|
-
this.parent.removeChild(this);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
/**
|
|
337
|
-
* Get parent of this component
|
|
338
|
-
*/
|
|
339
|
-
get parent() {
|
|
340
|
-
return this._parent;
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* Add Child Transform
|
|
344
|
-
* @remarks
|
|
345
|
-
* If `child` is already a child of this component, `child` will removed to the last of children list
|
|
346
|
-
* If `child` is already a child of other component, `child` will removed from its parent first
|
|
347
|
-
* @param child - child gameObject's transform component
|
|
348
|
-
*/
|
|
349
|
-
addChild(child) {
|
|
350
|
-
if (child.parent === this) {
|
|
351
|
-
const index = this.children.findIndex(item => item === child);
|
|
352
|
-
this.children.splice(index, 1);
|
|
353
|
-
}
|
|
354
|
-
else if (child.parent) {
|
|
355
|
-
child.parent.removeChild(child);
|
|
356
|
-
}
|
|
357
|
-
child._parent = this;
|
|
358
|
-
this.children.push(child);
|
|
359
|
-
}
|
|
360
|
-
/**
|
|
361
|
-
* Remove child transform
|
|
362
|
-
* @param child - child gameObject's transform component
|
|
363
|
-
*/
|
|
364
|
-
removeChild(child) {
|
|
365
|
-
const index = this.children.findIndex(item => item === child);
|
|
366
|
-
if (index > -1) {
|
|
367
|
-
this.children.splice(index, 1);
|
|
368
|
-
child._parent = null;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
/** Clear all child transform */
|
|
372
|
-
clearChildren() {
|
|
373
|
-
this.children.length = 0;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
__decorate([
|
|
377
|
-
Field({
|
|
378
|
-
type: 'vector2',
|
|
379
|
-
step: 1,
|
|
380
|
-
group: 'Transform',
|
|
381
|
-
label: 'Position',
|
|
382
|
-
description: 'Position on the design canvas (x right, y down).',
|
|
383
|
-
})
|
|
384
|
-
], Transform.prototype, "position", void 0);
|
|
385
|
-
__decorate([
|
|
386
|
-
Field({
|
|
387
|
-
type: 'size',
|
|
388
|
-
step: 1,
|
|
389
|
-
min: 0,
|
|
390
|
-
group: 'Transform',
|
|
391
|
-
label: 'Size',
|
|
392
|
-
description: 'Width and height of the object in design pixels.',
|
|
393
|
-
})
|
|
394
|
-
], Transform.prototype, "size", void 0);
|
|
395
|
-
__decorate([
|
|
396
|
-
Field({
|
|
397
|
-
type: 'vector2',
|
|
398
|
-
step: 0.1,
|
|
399
|
-
group: 'Transform',
|
|
400
|
-
label: 'Origin',
|
|
401
|
-
description: 'Local origin used for layout math.',
|
|
402
|
-
})
|
|
403
|
-
], Transform.prototype, "origin", void 0);
|
|
404
|
-
__decorate([
|
|
405
|
-
Field({
|
|
406
|
-
type: 'vector2',
|
|
407
|
-
step: 0.1,
|
|
408
|
-
group: 'Transform',
|
|
409
|
-
label: 'Anchor',
|
|
410
|
-
description: 'Anchor point (0–1) used when positioning and scaling.',
|
|
411
|
-
})
|
|
412
|
-
], Transform.prototype, "anchor", void 0);
|
|
413
|
-
__decorate([
|
|
414
|
-
Field({
|
|
415
|
-
type: 'vector2',
|
|
416
|
-
step: 0.1,
|
|
417
|
-
group: 'Transform',
|
|
418
|
-
label: 'Scale',
|
|
419
|
-
description: 'Scale multipliers on X and Y (1 = original size).',
|
|
420
|
-
})
|
|
421
|
-
], Transform.prototype, "scale", void 0);
|
|
422
|
-
__decorate([
|
|
423
|
-
Field({
|
|
424
|
-
type: 'vector2',
|
|
425
|
-
step: 0.1,
|
|
426
|
-
group: 'Transform',
|
|
427
|
-
label: 'Skew',
|
|
428
|
-
description: 'Skew amounts on X and Y.',
|
|
429
|
-
})
|
|
430
|
-
], Transform.prototype, "skew", void 0);
|
|
431
|
-
__decorate([
|
|
432
|
-
Field({
|
|
433
|
-
type: 'number',
|
|
434
|
-
step: 0.1,
|
|
435
|
-
group: 'Transform',
|
|
436
|
-
label: 'Rotation',
|
|
437
|
-
description: 'Rotation in radians.',
|
|
438
|
-
editor: 'number-stepper',
|
|
439
|
-
})
|
|
440
|
-
], Transform.prototype, "rotation", void 0);
|
|
441
|
-
|
|
442
316
|
let _id = 0;
|
|
443
317
|
/** Generate unique id for gameObject */
|
|
444
318
|
function getId() {
|
|
@@ -450,28 +324,23 @@ function getId() {
|
|
|
450
324
|
*/
|
|
451
325
|
class GameObject {
|
|
452
326
|
/**
|
|
453
|
-
*
|
|
327
|
+
* Construct a new gameObject
|
|
454
328
|
* @param name - the name of this gameObject
|
|
455
|
-
* @param obj - optional transform parameters for default Transform component
|
|
456
329
|
*/
|
|
457
|
-
constructor(name
|
|
330
|
+
constructor(name) {
|
|
331
|
+
this._parent = null;
|
|
458
332
|
/** A key-value map for components on this gameObject */
|
|
459
333
|
this._componentCache = {};
|
|
334
|
+
/** Child gameObjects in sibling order */
|
|
335
|
+
this.children = [];
|
|
336
|
+
/** Whether this gameObject is registered on a scene */
|
|
337
|
+
this.inScene = false;
|
|
460
338
|
/** Components apply to this gameObject */
|
|
461
339
|
this.components = [];
|
|
462
340
|
/** GameObject has been destroyed */
|
|
463
341
|
this.destroyed = false;
|
|
464
342
|
this._name = name;
|
|
465
343
|
this.id = getId();
|
|
466
|
-
this.addComponent(Transform, obj);
|
|
467
|
-
}
|
|
468
|
-
/**
|
|
469
|
-
* Get default transform component
|
|
470
|
-
* @returns transform component on this gameObject
|
|
471
|
-
* @readonly
|
|
472
|
-
*/
|
|
473
|
-
get transform() {
|
|
474
|
-
return this.getComponent(Transform);
|
|
475
344
|
}
|
|
476
345
|
/**
|
|
477
346
|
* Get parent gameObject
|
|
@@ -479,7 +348,7 @@ class GameObject {
|
|
|
479
348
|
* @readonly
|
|
480
349
|
*/
|
|
481
350
|
get parent() {
|
|
482
|
-
return this.
|
|
351
|
+
return this._parent;
|
|
483
352
|
}
|
|
484
353
|
/**
|
|
485
354
|
* Get the name of this gameObject
|
|
@@ -493,10 +362,8 @@ class GameObject {
|
|
|
493
362
|
return;
|
|
494
363
|
const scene = this._scene;
|
|
495
364
|
this._scene = val;
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
child.gameObject.scene = val;
|
|
499
|
-
}
|
|
365
|
+
for (const child of this.children) {
|
|
366
|
+
child.scene = val;
|
|
500
367
|
}
|
|
501
368
|
if (val) {
|
|
502
369
|
val.addGameObject(this);
|
|
@@ -518,16 +385,28 @@ class GameObject {
|
|
|
518
385
|
* @param gameObject - child gameobject
|
|
519
386
|
*/
|
|
520
387
|
addChild(gameObject) {
|
|
521
|
-
if (!gameObject ||
|
|
388
|
+
if (!gameObject || gameObject === this)
|
|
522
389
|
return;
|
|
523
390
|
if (!(gameObject instanceof GameObject)) {
|
|
524
391
|
throw new Error('addChild only receive GameObject');
|
|
525
392
|
}
|
|
526
|
-
if (
|
|
393
|
+
if (this.destroyed) {
|
|
527
394
|
throw new Error(`gameObject '${this.name}' has been destroy`);
|
|
528
395
|
}
|
|
529
|
-
gameObject.
|
|
396
|
+
if (gameObject.parent === this) {
|
|
397
|
+
const index = this.children.indexOf(gameObject);
|
|
398
|
+
if (index > -1)
|
|
399
|
+
this.children.splice(index, 1);
|
|
400
|
+
this.children.push(gameObject);
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
if (gameObject.parent) {
|
|
404
|
+
gameObject.parent.removeChild(gameObject);
|
|
405
|
+
}
|
|
406
|
+
gameObject._parent = this;
|
|
407
|
+
this.children.push(gameObject);
|
|
530
408
|
gameObject.scene = this.scene;
|
|
409
|
+
notifyGameObjectProp(gameObject, 'parent', ObserverType.CHANGE);
|
|
531
410
|
}
|
|
532
411
|
/**
|
|
533
412
|
* Remove child gameObject
|
|
@@ -537,8 +416,12 @@ class GameObject {
|
|
|
537
416
|
if (!(gameObject instanceof GameObject) || !gameObject.parent || gameObject.parent !== this) {
|
|
538
417
|
return gameObject;
|
|
539
418
|
}
|
|
540
|
-
|
|
419
|
+
const index = this.children.indexOf(gameObject);
|
|
420
|
+
if (index > -1)
|
|
421
|
+
this.children.splice(index, 1);
|
|
422
|
+
gameObject._parent = null;
|
|
541
423
|
gameObject.scene = null;
|
|
424
|
+
notifyGameObjectProp(gameObject, 'parent', ObserverType.CHANGE);
|
|
542
425
|
return gameObject;
|
|
543
426
|
}
|
|
544
427
|
addComponent(C, obj) {
|
|
@@ -580,9 +463,6 @@ class GameObject {
|
|
|
580
463
|
else if (c.componentName) {
|
|
581
464
|
componentName = c.componentName;
|
|
582
465
|
}
|
|
583
|
-
if (componentName === 'Transform') {
|
|
584
|
-
throw new Error("Transform can't be removed");
|
|
585
|
-
}
|
|
586
466
|
return this._removeComponent(componentName);
|
|
587
467
|
}
|
|
588
468
|
_removeComponent(componentName) {
|
|
@@ -625,15 +505,15 @@ class GameObject {
|
|
|
625
505
|
}
|
|
626
506
|
/** Destroy this gameObject */
|
|
627
507
|
destroy() {
|
|
628
|
-
if (
|
|
508
|
+
if (this.destroyed) {
|
|
629
509
|
console.error('Cannot destroy gameObject that have already been destroyed.');
|
|
630
510
|
return;
|
|
631
511
|
}
|
|
632
|
-
Array.from(this.
|
|
633
|
-
|
|
512
|
+
Array.from(this.children).forEach(child => {
|
|
513
|
+
child.destroy();
|
|
634
514
|
});
|
|
635
515
|
this.remove();
|
|
636
|
-
this.
|
|
516
|
+
this.children.length = 0;
|
|
637
517
|
for (const key in this._componentCache) {
|
|
638
518
|
this._removeComponent(key);
|
|
639
519
|
}
|
|
@@ -665,22 +545,30 @@ class ComponentObserver {
|
|
|
665
545
|
* @param type - change event type
|
|
666
546
|
* @param componentName - `component.name` this parameter will deprecated
|
|
667
547
|
*/
|
|
668
|
-
add({ component, prop, type, componentName }) {
|
|
548
|
+
add({ component, prop, type, componentName, gameObject }) {
|
|
549
|
+
const go = gameObject ?? component?.gameObject;
|
|
669
550
|
if (type === ObserverType.REMOVE) {
|
|
670
|
-
|
|
671
|
-
|
|
551
|
+
const sameTarget = (changed) => component
|
|
552
|
+
? changed.component === component
|
|
553
|
+
: changed.gameObject === go && changed.componentName === componentName;
|
|
554
|
+
if (this.events.find(changed => sameTarget(changed) && changed.type === ObserverType.ADD)) {
|
|
555
|
+
this.events = this.events.filter(changed => !sameTarget(changed));
|
|
672
556
|
return;
|
|
673
557
|
}
|
|
674
|
-
this.events = this.events.filter(changed => changed
|
|
558
|
+
this.events = this.events.filter(changed => !sameTarget(changed));
|
|
675
559
|
}
|
|
676
|
-
const index = this.events.findIndex(changed => changed.
|
|
560
|
+
const index = this.events.findIndex(changed => changed.gameObject === go &&
|
|
561
|
+
changed.component === component &&
|
|
562
|
+
changed.componentName === componentName &&
|
|
563
|
+
isEqual(changed.prop, prop) &&
|
|
564
|
+
changed.type === type);
|
|
677
565
|
if (index > -1) {
|
|
678
566
|
this.events.splice(index, 1);
|
|
679
567
|
}
|
|
680
568
|
this.events.push({
|
|
681
|
-
gameObject:
|
|
569
|
+
gameObject: go,
|
|
682
570
|
component,
|
|
683
|
-
prop
|
|
571
|
+
prop,
|
|
684
572
|
type,
|
|
685
573
|
componentName,
|
|
686
574
|
});
|
|
@@ -955,8 +843,8 @@ class Ticker {
|
|
|
955
843
|
* Scene is a gameObject container
|
|
956
844
|
*/
|
|
957
845
|
class Scene extends GameObject {
|
|
958
|
-
constructor(name
|
|
959
|
-
super(name
|
|
846
|
+
constructor(name) {
|
|
847
|
+
super(name);
|
|
960
848
|
this.gameObjects = [];
|
|
961
849
|
this.scene = this; // gameObject.scene = this
|
|
962
850
|
}
|
|
@@ -966,9 +854,10 @@ class Scene extends GameObject {
|
|
|
966
854
|
*/
|
|
967
855
|
addGameObject(gameObject) {
|
|
968
856
|
this.gameObjects.push(gameObject);
|
|
969
|
-
if (gameObject.
|
|
970
|
-
|
|
971
|
-
|
|
857
|
+
if (gameObject.inScene)
|
|
858
|
+
return;
|
|
859
|
+
gameObject.inScene = true;
|
|
860
|
+
notifyGameObjectProp(gameObject, 'inScene', ObserverType.CHANGE);
|
|
972
861
|
}
|
|
973
862
|
/**
|
|
974
863
|
* Remove gameObject
|
|
@@ -978,8 +867,9 @@ class Scene extends GameObject {
|
|
|
978
867
|
const index = this.gameObjects.indexOf(gameObject);
|
|
979
868
|
if (index === -1)
|
|
980
869
|
return;
|
|
981
|
-
if (gameObject.
|
|
982
|
-
gameObject.
|
|
870
|
+
if (gameObject.inScene) {
|
|
871
|
+
gameObject.inScene = false;
|
|
872
|
+
notifyGameObjectProp(gameObject, 'inScene', ObserverType.CHANGE);
|
|
983
873
|
}
|
|
984
874
|
this.gameObjects.splice(index, 1);
|
|
985
875
|
}
|
|
@@ -995,7 +885,7 @@ class Scene extends GameObject {
|
|
|
995
885
|
}
|
|
996
886
|
|
|
997
887
|
/** Generated at build from package.json */
|
|
998
|
-
const version = "0.0
|
|
888
|
+
const version = "0.1.0";
|
|
999
889
|
|
|
1000
890
|
/**
|
|
1001
891
|
* Sent to `window.parent` after each `System.init` completes during `Game.addSystem`
|
|
@@ -2170,5 +2060,5 @@ const decorators = {
|
|
|
2170
2060
|
};
|
|
2171
2061
|
console.log(`@combos-fun/engine version: ${version}`);
|
|
2172
2062
|
|
|
2173
|
-
export { COMBOS_GAME_PLUGIN_INIT_SUCCESS, COMBOS_GAME_READY, COMBOS_GAME_SET_PLAYING, COMBOS_GAME_STATE_CHANGED, Component, DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES, Game, GameObject, IDEProp, LOAD_EVENT, LOAD_SCENE_MODE, ObserverType as OBSERVER_TYPE, RESOURCE_TYPE, RESOURCE_TYPE_STRATEGY, Scene, System,
|
|
2063
|
+
export { COMBOS_GAME_PLUGIN_INIT_SUCCESS, COMBOS_GAME_READY, COMBOS_GAME_SET_PLAYING, COMBOS_GAME_STATE_CHANGED, Component, DEFAULT_ALLOWED_MESSAGE_HOST_SUFFIXES, Game, GameObject, IDEProp, LOAD_EVENT, LOAD_SCENE_MODE, ObserverType as OBSERVER_TYPE, RESOURCE_TYPE, RESOURCE_TYPE_STRATEGY, Scene, System, componentObserver, decorators, isAllowedMessageOrigin, mergeAllowedMessageOrigins, normalizeResourceSrc, normalizeSpritesheetData, parseSetPlayingMessage, postParentGameReady, postParentGameState, postParentPluginInitSuccess, resource, resourceLoader, version };
|
|
2174
2064
|
//# sourceMappingURL=engine.esm.js.map
|