@makefully/platypus 4.1.5 → 4.1.6

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.
Files changed (136) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +3 -3
  3. package/lib/platypus.js +1 -1
  4. package/package.json +6 -5
  5. package/src/AABB.js +685 -0
  6. package/src/ActionState.js +121 -0
  7. package/src/AssetManager.js +206 -0
  8. package/src/CollisionData.js +96 -0
  9. package/src/CollisionDataContainer.js +127 -0
  10. package/src/CollisionShape.js +315 -0
  11. package/src/Component.js +231 -0
  12. package/src/Data.js +64 -0
  13. package/src/DataMap.js +204 -0
  14. package/src/Entity.js +404 -0
  15. package/src/EntityLinker.js +113 -0
  16. package/src/EventHandler.js +115 -0
  17. package/src/EventHandlerList.js +251 -0
  18. package/src/Game.js +840 -0
  19. package/src/Gamepad.js +175 -0
  20. package/src/ID3CaptionPlayer.js +61 -0
  21. package/src/Messenger.js +365 -0
  22. package/src/PIXIAnimation.js +622 -0
  23. package/src/RandomSet.js +140 -0
  24. package/src/SFXPlayer.js +120 -0
  25. package/src/StateMap.js +252 -0
  26. package/src/Storage.js +152 -0
  27. package/src/TickerClient.js +48 -0
  28. package/src/TickerServer.js +23 -0
  29. package/src/TimeEvent.js +50 -0
  30. package/src/TimeEventList.js +100 -0
  31. package/src/VOPlayer.js +684 -0
  32. package/src/Vector.js +702 -0
  33. package/src/components/AIChaser.js +161 -0
  34. package/src/components/AIPacer.js +107 -0
  35. package/src/components/AudioMusic.js +151 -0
  36. package/src/components/AudioSFX.js +673 -0
  37. package/src/components/AudioVO.js +301 -0
  38. package/src/components/CollisionBasic.js +826 -0
  39. package/src/components/CollisionFilter.js +74 -0
  40. package/src/components/CollisionGroup.js +448 -0
  41. package/src/components/CollisionTiles.js +608 -0
  42. package/src/components/ComponentSwitcher.js +173 -0
  43. package/src/components/ControllerInput.js +65 -0
  44. package/src/components/Counter.js +165 -0
  45. package/src/components/EntityCamera.js +215 -0
  46. package/src/components/EntityContainer.js +549 -0
  47. package/src/components/EntityController.js +541 -0
  48. package/src/components/HandlerCamera.js +1052 -0
  49. package/src/components/HandlerCollision.js +1318 -0
  50. package/src/components/HandlerController.js +291 -0
  51. package/src/components/HandlerLogic.js +394 -0
  52. package/src/components/HandlerRender.js +217 -0
  53. package/src/components/Interactive.js +502 -0
  54. package/src/components/LevelBuilder.js +524 -0
  55. package/src/components/LogicAngularMovement.js +154 -0
  56. package/src/components/LogicAttachment.js +265 -0
  57. package/src/components/LogicButton.js +466 -0
  58. package/src/components/LogicCarrier.js +39 -0
  59. package/src/components/LogicDestroyMe.js +58 -0
  60. package/src/components/LogicDirectionalMovement.js +325 -0
  61. package/src/components/LogicDragDrop.js +371 -0
  62. package/src/components/LogicImpactLaunch.js +144 -0
  63. package/src/components/LogicPacingPlatform.js +64 -0
  64. package/src/components/LogicPortable.js +112 -0
  65. package/src/components/LogicPortal.js +115 -0
  66. package/src/components/LogicPushable.js +98 -0
  67. package/src/components/LogicRebounder.js +136 -0
  68. package/src/components/LogicRegionSpawner.js +139 -0
  69. package/src/components/LogicRotationalMovement.js +205 -0
  70. package/src/components/LogicSpawner.js +159 -0
  71. package/src/components/LogicStateMachine.js +382 -0
  72. package/src/components/LogicSwitch.js +77 -0
  73. package/src/components/LogicTeleportee.js +68 -0
  74. package/src/components/LogicTeleporter.js +93 -0
  75. package/src/components/LogicTimer.js +178 -0
  76. package/src/components/LogicWindUpRacer.js +179 -0
  77. package/src/components/Motion.js +371 -0
  78. package/src/components/Mover.js +566 -0
  79. package/src/components/Node.js +289 -0
  80. package/src/components/NodeMap.js +295 -0
  81. package/src/components/NodeResident.js +636 -0
  82. package/src/components/Orientation.js +697 -0
  83. package/src/components/RandomEvents.js +73 -0
  84. package/src/components/RelativePosition.js +204 -0
  85. package/src/components/RelayFamily.js +106 -0
  86. package/src/components/RelayGame.js +53 -0
  87. package/src/components/RelayLinker.js +94 -0
  88. package/src/components/RelayParent.js +57 -0
  89. package/src/components/RelaySelf.js +55 -0
  90. package/src/components/Render.js +178 -0
  91. package/src/components/RenderAnimator.js +275 -0
  92. package/src/components/RenderContainer.js +646 -0
  93. package/src/components/RenderDebug.js +319 -0
  94. package/src/components/RenderDestroyMe.js +59 -0
  95. package/src/components/RenderLottie.js +149 -0
  96. package/src/components/RenderProgress.js +120 -0
  97. package/src/components/RenderSpine.js +833 -0
  98. package/src/components/RenderSprite.js +527 -0
  99. package/src/components/RenderText.js +147 -0
  100. package/src/components/RenderTiles.js +1391 -0
  101. package/src/components/SceneChanger.js +128 -0
  102. package/src/components/TiledLoader.js +1451 -0
  103. package/src/components/Timeline.js +314 -0
  104. package/src/components/Tutorial.js +267 -0
  105. package/src/components/Tween.js +296 -0
  106. package/src/components/VoiceOver.js +373 -0
  107. package/src/components/XHR.js +129 -0
  108. package/src/components/index.js +79 -0
  109. package/src/factory.js +305 -0
  110. package/src/index.js +159 -0
  111. package/src/mixins/PIXI.Graphics.js +41 -0
  112. package/src/platypus.css +68 -0
  113. package/src/sayHello.js +50 -0
  114. package/src/shapes/Capsule.js +74 -0
  115. package/src/shapes/Circle.js +43 -0
  116. package/src/shapes/Ellipse.js +117 -0
  117. package/src/shapes/Point.js +191 -0
  118. package/src/shapes/Polygon.js +112 -0
  119. package/src/shapes/Polyline.js +97 -0
  120. package/src/shapes/Rectangle.js +78 -0
  121. package/src/shapes/RoundedRectangle.js +33 -0
  122. package/src/shapes/Segment.js +346 -0
  123. package/src/shapes/adjustedXY.js +19 -0
  124. package/src/shapes/castFromBox2D.js +92 -0
  125. package/src/shapes/castFromObject.js +53 -0
  126. package/src/shapes/castFromPixiGraphics.js +6 -0
  127. package/src/shapes/castFromPixiShape.js +89 -0
  128. package/src/shapes/castToBox2D.js +190 -0
  129. package/src/shapes/castToPixiGraphics.js +100 -0
  130. package/src/shapes/castToPixiShape.js +61 -0
  131. package/src/shapes/checkPointsMap.js +313 -0
  132. package/src/shapes/index.js +35 -0
  133. package/src/utils/array.js +73 -0
  134. package/src/utils/string.js +39 -0
  135. package/lib/243.platypus.mjs +0 -1
  136. package/lib/platypus.mjs +0 -1
@@ -0,0 +1,144 @@
1
+ /* global platypus */
2
+ import Vector from '../Vector.js';
3
+ import createComponentClass from '../factory.js';
4
+
5
+ export default (function () {
6
+ return createComponentClass(/** @lends platypus.components.LogicImpactLaunch.prototype */{
7
+ id: 'LogicImpactLaunch',
8
+
9
+ properties: {
10
+ /**
11
+ * Acceleration in X entity should have in world units while being launched.
12
+ *
13
+ * @property accelerationX
14
+ * @type number
15
+ * @default -0.3
16
+ */
17
+ accelerationX: -0.3,
18
+
19
+ /**
20
+ * Acceleration in Y entity should have in world units while being launched.
21
+ *
22
+ * @property accelerationY
23
+ * @type number
24
+ * @default -0.8
25
+ */
26
+ accelerationY: -0.8,
27
+
28
+ /**
29
+ * Whether X acceleration should flip according to the direction of the collision.
30
+ *
31
+ * @property flipX
32
+ * @type boolean
33
+ * @default true
34
+ */
35
+ flipX: true,
36
+
37
+ /**
38
+ * Whether Y acceleration should flip according to the direction of the collision.
39
+ *
40
+ * @property flipY
41
+ * @type boolean
42
+ * @default false
43
+ */
44
+ flipY: false,
45
+
46
+ /**
47
+ * This sets the state of the entity while it's being launched. Defaults to "stunned".
48
+ *
49
+ * @property state
50
+ * @type string
51
+ * @default "stunned"
52
+ */
53
+ state: "stunned"
54
+ },
55
+
56
+ /**
57
+ * This component will cause the entity to move in a certain direction on colliding with another entity.
58
+ *
59
+ * @memberof platypus.components
60
+ * @uses platypus.Component
61
+ * @constructs
62
+ * @listens platypus.Entity#component-added
63
+ * @listens platypus.Entity#handle-logic
64
+ * @listens platypus.Entity#hit-solid
65
+ */
66
+ initialize: function (definition) {
67
+ this.stunState = definition.state || "stunned";
68
+
69
+ this.flipX = this.flipX ? -1 : 1;
70
+ this.flipY = this.flipY ? -1 : 1;
71
+
72
+ this.justJumped = false;
73
+ this.stunned = false;
74
+
75
+ this.state = this.owner.state;
76
+ this.state.set('impact', false);
77
+ this.state.set(this.stunState, false);
78
+ },
79
+
80
+ events: {
81
+ "component-added": function (component) {
82
+ if (component === this) {
83
+ if (!this.owner.addMover) {
84
+ platypus.debug.warn('The "LogicDirectionalMovement" component requires a "Mover" component to function correctly.');
85
+ return;
86
+ }
87
+
88
+ this.direction = this.owner.addMover({
89
+ velocity: [0, 0, 0],
90
+ orient: false
91
+ }).velocity;
92
+ this.vector = Vector.setUp();
93
+ }
94
+ },
95
+
96
+ "handle-logic": function () {
97
+ this.state.set('impact', this.justJumped);
98
+ this.state.set(this.stunState, this.stunned);
99
+
100
+ if (this.justJumped) {
101
+ this.direction.setVector(this.vector);
102
+ this.justJumped = false;
103
+ this.stunned = true;
104
+ }
105
+ },
106
+
107
+ "impact-launch": function ({entity, x, y}) {
108
+ if (!this.stunned) {
109
+ const
110
+ {owner, vector} = this,
111
+ dx = entity ? entity.x - owner.x : x,
112
+ dy = entity ? entity.y - owner.y : y;
113
+
114
+ this.justJumped = true;
115
+ if (dx >= 0) {
116
+ vector.x = this.accelerationX;
117
+ } else if (dx < 0) {
118
+ vector.x = this.accelerationX * this.flipX;
119
+ }
120
+ if (dy >= 0) {
121
+ vector.y = this.accelerationY;
122
+ } else if (dy < 0) {
123
+ vector.y = this.accelerationY * this.flipY;
124
+ }
125
+ }
126
+ },
127
+
128
+ "hit-solid": function (collisionInfo) {
129
+ if (this.stunned && (collisionInfo.y > 0)) {
130
+ this.direction.x = 0;
131
+ this.direction.y = 0;
132
+ this.stunned = false;
133
+ }
134
+ }
135
+ },
136
+
137
+ methods: {
138
+ destroy: function () {
139
+ this.vector.recycle();
140
+ this.state = null;
141
+ }
142
+ }
143
+ });
144
+ }());
@@ -0,0 +1,64 @@
1
+ /**
2
+ ## JSON Definition:
3
+ {
4
+ "type": "LogicDirectionalMovement",
5
+
6
+ "angle": 3.14,
7
+ // Optional. Defines the angle of movement in radians. Defaults to 0 (horizontal, starts moving right).
8
+
9
+ "distance": 440,
10
+ // Optional. Declares distance in world units that the entity should move back and forth across. Defaults to 128.
11
+
12
+ "period": 6000,
13
+ // Optional. Sets the time in milliseconds that the entity should take to make a complete movement cycle. Defaults to 4 seconds (4000).
14
+
15
+ "startPos": 0
16
+ // Optional. Position in the cycle that the movement should begin. Defaults in the middle at 0; PI/2 and -PI/2 will put you at the extremes.
17
+ }
18
+ */
19
+ import createComponentClass from '../factory.js';
20
+
21
+ export default (function () {
22
+ return createComponentClass(/** @lends platypus.components.LogicPacingPlatform.prototype */{
23
+
24
+ id: 'LogicPacingPlatform',
25
+
26
+ /**
27
+ * This component changes the (x, y) position of an object according to its speed and heading and alternates back and forth. This is useful for in-place moving platforms.
28
+ *
29
+ * @memberof platypus.components
30
+ * @uses platypus.Component
31
+ * @constructs
32
+ * @param {*} definition
33
+ * @listens platypus.Entity#handle-logic
34
+ */
35
+ initialize: function (definition) {
36
+ this.ang = this.owner.angle || definition.angle || 0; //PI/2 makes it go down first
37
+ this.dist = this.owner.distance || definition.distance || 128; //Distance in pixels
38
+ this.dX = this.dist * Math.cos(this.ang);
39
+ this.dY = this.dist * Math.sin(this.ang);
40
+ this.period = this.owner.period || definition.period || 4000;
41
+ this.time = 0;
42
+ this.startPos = this.owner.startPos || definition.startPos || 0; //PI/2 and -PI/2 will put you at the extremes
43
+ this.offset = 0;
44
+ this.originX = this.owner.x;
45
+ this.originY = this.owner.y;
46
+ },
47
+
48
+ events: {
49
+ "handle-logic": function ({delta}) {
50
+ const
51
+ {period} = this;
52
+
53
+ this.time += delta;
54
+ if (this.time > period) {
55
+ this.time = this.time % period;
56
+ }
57
+ this.offset = (this.time / period) * (2 * Math.PI);
58
+
59
+ this.owner.x = this.originX + Math.sin(this.offset + this.startPos) * this.dX;
60
+ this.owner.y = this.originY + Math.sin(this.offset + this.startPos) * this.dY;
61
+ }
62
+ }
63
+ });
64
+ }());
@@ -0,0 +1,112 @@
1
+ import createComponentClass from '../factory.js';
2
+
3
+ export default (function () {
4
+ return createComponentClass(/** @lends platypus.components.LogicPortable.prototype */{
5
+ id: 'LogicPortable',
6
+ properties: {
7
+ /**
8
+ * This is an object specifying the directions that this portable entity can be carried on. Default is {down:true}, but "up", "down", "left", and/or "right" can be specified as object properties set to `true`.
9
+ *
10
+ * @property portableDirections
11
+ * @type Object
12
+ * @default {"down": true}
13
+ */
14
+ portableDirections: {
15
+ down: true //default is false, 'true' means as soon as carrier is connected downward
16
+ }
17
+ },
18
+
19
+ /**
20
+ * This component allows this entity to be carried by other entities with which it collides. Entities that should carry this entity need to have a [[Logic-Carrier]] component attached.
21
+ *
22
+ * @memberof platypus.components
23
+ * @uses platypus.Component
24
+ * @constructs
25
+ * @listens platypus.Entity#force-release
26
+ * @listens platypus.Entity#handle-logic
27
+ * @listens platypus.Entity#hit-solid
28
+ * @fires platypus.Entity#carry-me
29
+ * @fires platypus.Entity#release-me
30
+ */
31
+ initialize: function () {
32
+ this.carrier = this.lastCarrier = null;
33
+ this.message = {
34
+ entity: this.owner
35
+ };
36
+ },
37
+
38
+ events: {
39
+ "handle-logic": function () {
40
+ const
41
+ {message: msg} = this;
42
+
43
+ if (this.carrierConnected) {
44
+ if (this.carrier !== this.lastCarrier) {
45
+ if (this.lastCarrier) {
46
+ this.lastCarrier.triggerEvent('release-me', msg);
47
+ }
48
+
49
+ /**
50
+ * This message is triggered on a potential carrying peer, notifying the peer that this entity is portable.
51
+ *
52
+ * @event platypus.Entity#carry-me
53
+ * @param {platypus.Entity} message.entity This entity, requesting to be carried.
54
+ */
55
+ this.carrier.triggerEvent('carry-me', msg);
56
+ }
57
+
58
+ this.carrierConnected = false;
59
+ } else if (this.carrier) {
60
+
61
+ /**
62
+ * This message is triggered on the current carrier, notifying them to release this entity.
63
+ *
64
+ * @event platypus.Entity#release-me
65
+ * @param {platypus.Entity} message.entity This entity, requesting to be released.
66
+ */
67
+ this.carrier.triggerEvent('release-me', msg);
68
+ this.carrier = null;
69
+ }
70
+ this.lastCarrier = this.carrier;
71
+ },
72
+
73
+ "hit-solid": function (collisionInfo) {
74
+ if (collisionInfo.y > 0) {
75
+ this.updateCarrier(collisionInfo.entity, 'down');
76
+ } else if (collisionInfo.y < 0) {
77
+ this.updateCarrier(collisionInfo.entity, 'up');
78
+ } else if (collisionInfo.x < 0) {
79
+ this.updateCarrier(collisionInfo.entity, 'left');
80
+ } else if (collisionInfo.x > 0) {
81
+ this.updateCarrier(collisionInfo.entity, 'right');
82
+ }
83
+ },
84
+
85
+ /**
86
+ * On receiving this message, this component immediately triggers 'release-me' on its owner's carrier.
87
+ *
88
+ * @event platypus.Entity#force-release
89
+ */
90
+ "force-release": function () {
91
+ if (this.carrier) {
92
+ this.carrier.triggerEvent('release-me', this.message);
93
+ }
94
+ this.carrier = null;
95
+ this.lastCarrier = this.carrier;
96
+ this.carrierConnected = false;
97
+ }
98
+ },
99
+ methods: {
100
+ updateCarrier: function (entity, direction) {
101
+ if (this.portableDirections[direction]) {
102
+ if (entity) {
103
+ if (entity !== this.carrier) {
104
+ this.carrier = entity;
105
+ }
106
+ this.carrierConnected = true;
107
+ }
108
+ }
109
+ }
110
+ }
111
+ });
112
+ }());
@@ -0,0 +1,115 @@
1
+ /**
2
+ ### Peer Broadcasts:
3
+ - **portal-waiting** - Informs another object that the portal is waiting on it to send the activate message.
4
+ - @param entity - This is the portal entity. To be used so that the object can communicate with it directly.
5
+
6
+ ## JSON Definition
7
+ {
8
+ "type": "name-of-component",
9
+ "destination" : "level-2"
10
+ //Required - The destination scene to which the portal will take us. In most cases this will come into the portal from Tiled where you'll set a property on the portal you place.
11
+ }
12
+ */
13
+ import DataMap from '../DataMap.js';
14
+ import createComponentClass from '../factory.js';
15
+
16
+ export default (function () {
17
+ return createComponentClass(/** @lends platypus.components.LogicPortal.prototype */{
18
+ id: 'LogicPortal',
19
+
20
+ /**
21
+ * A component which changes the scene when activated. When the portal receives an occupied message it sends the entity in that message notifying it. This message is meant to give the entity a chance to activate the portal in the manner it wants. The portal can also be activated by simply telling it to activate.
22
+ *
23
+ * @memberof platypus.components
24
+ * @uses platypus.Component
25
+ * @constructs
26
+ * @param {*} definition
27
+ * @listens platypus.Entity#handle-logic
28
+ */
29
+ initialize: function (definition) {
30
+ const
31
+ entrants = definition.entrants || definition.entrant || 'no one',
32
+ state = this.owner.state;
33
+
34
+ this.destination = this.owner.destination || definition.destination;
35
+ this.used = false;
36
+ this.ready = false;
37
+ this.wasReady = false;
38
+
39
+ this.entrants = DataMap.setUp();
40
+ if (Array.isArray(entrants)) {
41
+ for (let i = 0; i < entrants.length; i++) {
42
+ this.entrants.set(entrants[i], false);
43
+ }
44
+ } else {
45
+ this.entrants.set(entrants, false);
46
+ }
47
+
48
+ this.state = state;
49
+
50
+ state.set('occupied', false);
51
+ state.set('ready', true);
52
+ },
53
+ events: {
54
+ "handle-logic": function () {
55
+ const
56
+ {entrants, state} = this,
57
+ keys = entrants.keys;
58
+ let i = keys.length,
59
+ occupied = false,
60
+ ready = true;
61
+
62
+ if (!this.used && this.activated) {
63
+ this.owner.triggerEvent("port-" + this.destination);
64
+ this.used = true;
65
+ } else if (this.ready && !this.wasReady) {
66
+ this.owner.triggerEvent('portal-waiting');
67
+ this.wasReady = true;
68
+ } else if (this.wasReady && !this.ready) {
69
+ this.owner.triggerEvent('portal-not-waiting');
70
+ this.wasReady = false;
71
+ }
72
+
73
+
74
+ //Reset portal for next collision run.
75
+ while (i--) {
76
+ if (entrants[keys[i]]) {
77
+ occupied = true;
78
+ entrants.set(keys[i], false);
79
+ } else {
80
+ ready = false;
81
+ }
82
+ }
83
+ state.set('occupied', occupied);
84
+ state.set('ready', ready);
85
+ this.ready = false;
86
+ },
87
+ "occupied-portal": function (collision) {
88
+ const
89
+ entrants = this.entrants,
90
+ keys = entrants.keys;
91
+ let i = keys.length;
92
+
93
+ entrants.set(collision.entity.type, true);
94
+
95
+ while (i--) {
96
+ if (!entrants.get(keys[i])) {
97
+ return;
98
+ }
99
+ }
100
+
101
+ this.ready = true;
102
+ },
103
+ "activate-portal": function () {
104
+ this.activated = true;
105
+ }
106
+ },
107
+ methods: {
108
+ destroy: function () {
109
+ this.state = null;
110
+ this.entrants.recycle();
111
+ this.entrants = null;
112
+ }
113
+ }
114
+ });
115
+ }());
@@ -0,0 +1,98 @@
1
+ /**
2
+ ## JSON Definition
3
+ {
4
+ "type": "LogicPushable",
5
+ "xPush" : .01,
6
+ //Optional - The distance per millisecond this object can be pushed in x. Defaults to .01.
7
+ "yPush" : .01,
8
+ //Optional - The distance per millisecond this object can be pushed in y. Defaults to .01.
9
+ "push" : .01
10
+ //Optional - The distance per millisecond this object can be pushed in x and y. Overwritten by the more specific values xPush and yPush. Defaults to .01.
11
+ }
12
+ */
13
+ import {arrayCache} from '../utils/array.js';
14
+ import createComponentClass from '../factory.js';
15
+
16
+ const
17
+ setMagnitude = function (direction, magnitude) {
18
+ return (direction / Math.abs(direction)) * magnitude;
19
+ };
20
+
21
+ export default createComponentClass(/** @lends platypus.components.LogicPushable.prototype */{
22
+ id: 'LogicPushable',
23
+
24
+ /**
25
+ * A component that enables an entity to be pushed.
26
+ *
27
+ * @memberof platypus.components
28
+ * @uses platypus.Component
29
+ * @constructs
30
+ * @param {*} definition
31
+ * @listens platypus.Entity#handle-logic
32
+ * @listens platypus.Entity#hit-solid
33
+ */
34
+ initialize: function (definition) {
35
+ this.yPush = definition.push || definition.yPush || 0;
36
+ this.xPush = definition.push || definition.xPush || 0.1;
37
+ if (definition.roll) {
38
+ this.radius = definition.radius || this.owner.radius || ((this.owner.width || this.owner.height || 2) / 2);
39
+ this.owner.orientation = this.owner.orientation || 0;
40
+ } else {
41
+ this.radius = 0;
42
+ }
43
+ this.currentPushX = 0;
44
+ this.currentPushY = 0;
45
+ this.lastX = this.owner.x;
46
+ this.lastY = this.owner.y;
47
+ this.pushers = arrayCache.setUp();
48
+ },
49
+
50
+ events: {
51
+ "handle-logic": function ({delta}) {
52
+ if (this.currentPushY) {
53
+ this.owner.y += setMagnitude(this.currentPushY, this.yPush * delta);
54
+ this.currentPushY = 0;
55
+ }
56
+ if (this.currentPushX) {
57
+ this.owner.x += setMagnitude(this.currentPushX, this.xPush * delta);
58
+ this.currentPushX = 0;
59
+ }
60
+ if ((this.lastX !== this.owner.x) || (this.lastY !== this.owner.y)) {
61
+ if (this.radius) {
62
+ this.owner.orientation += (this.owner.x + this.owner.y - this.lastX - this.lastY) / this.radius;
63
+ }
64
+ this.lastX = this.owner.x;
65
+ this.lastY = this.owner.y;
66
+ }
67
+ for (let i = 0; i < this.pushers.length; i++) {
68
+ this.pushers[i].triggerEvent('pushed', this.owner);
69
+ }
70
+ this.pushers.length = 0;
71
+ },
72
+ "push-entity": function (collisionInfo) {
73
+ const
74
+ x = (collisionInfo.x || 0),
75
+ y = (collisionInfo.y || 0);
76
+
77
+ this.currentPushX -= x;
78
+ this.currentPushY -= y;
79
+ if ((this.yPush && y) || (this.xPush && x)) {
80
+ this.pushers.push(collisionInfo.entity);
81
+ }
82
+ },
83
+ "hit-solid": function (collisionInfo) {
84
+ if (((collisionInfo.y > 0) && (this.vY > 0)) || ((collisionInfo.y < 0) && (this.vY < 0))) {
85
+ this.vY = 0;
86
+ } else if (((collisionInfo.x < 0) && (this.vX < 0)) || ((collisionInfo.x > 0) && (this.vX > 0))) {
87
+ this.vX = 0;
88
+ }
89
+ return true;
90
+ }
91
+ },
92
+
93
+ methods: {
94
+ destroy: function () {
95
+ arrayCache.recycle(this.pushers);
96
+ }
97
+ }
98
+ });
@@ -0,0 +1,136 @@
1
+ /**
2
+ ### Peer Broadcasts:
3
+ - **share-velocity** - This component triggers this message to prevent double collision calls.
4
+ - @param entity ([[entity]]) - This entity.
5
+
6
+ ## JSON Definition
7
+ {
8
+ "type": "LogicRebounder",
9
+
10
+ "mass": 12,
11
+ // Optional. Relative size of the entity. Defaults to 1.
12
+
13
+ "elasticity": 0.4
14
+ // Optional. Bounciness of the entity. Defaults to 0.8.
15
+ }
16
+ */
17
+ import Vector from '../Vector.js';
18
+ import {arrayCache} from '../utils/array.js';
19
+ import createComponentClass from '../factory.js';
20
+
21
+ export default createComponentClass(/** @lends platypus.components.LogicRebounder.prototype */{
22
+ id: 'LogicRebounder',
23
+
24
+ /**
25
+ * This component works with `CollisionBasic` to cause entities to bounce away on solid collisions.
26
+ *
27
+ * @memberof platypus.components
28
+ * @uses platypus.Component
29
+ * @constructs
30
+ * @param {*} definition
31
+ * @listens platypus.Entity#handle-logic
32
+ */
33
+ initialize: function (definition) {
34
+ Vector.assign(this.owner, 'velocity', 'dx', 'dy', 'dz');
35
+
36
+ this.owner.mass = this.owner.mass || definition.mass || 1;
37
+ this.elasticity = definition.elasticity || 0.8;
38
+
39
+ this.v = Vector.setUp(0, 0, 0);
40
+ this.incidentVector = Vector.setUp(0, 0, 0);
41
+
42
+ this.staticCollisionOccurred = false;
43
+ this.nonStaticCollisionOccurred = false;
44
+
45
+ this.hitThisTick = arrayCache.setUp();
46
+ this.otherV = Vector.setUp(0, 0, 0);
47
+ this.otherVelocityData = arrayCache.setUp();
48
+ },
49
+
50
+ events: {// These are messages that this component listens for
51
+ "handle-logic": function () {
52
+ this.hitThisTick.length = 0;
53
+ for (let i = 0; i < this.otherVelocityData.length; i++) {
54
+ this.otherVelocityData[i].velocity.recycle();
55
+ }
56
+ this.otherVelocityData.length = 0;
57
+ },
58
+ "hit-static": function ({direction, entity: other}) {
59
+ let magnitude = 0;
60
+
61
+ for (let x = 0; x < this.hitThisTick.length; x++) {
62
+ if (other === this.hitThisTick[x]) {
63
+ return;
64
+ }
65
+ }
66
+ this.hitThisTick.push(other);
67
+
68
+ this.v.setVector(this.owner.velocity);
69
+ this.incidentVector.setVector(direction);
70
+
71
+ magnitude = this.v.scalarProjection(this.incidentVector);
72
+ if (!isNaN(magnitude)) {
73
+ this.incidentVector.scale(magnitude * (1 + this.elasticity));
74
+ this.v.subtractVector(this.incidentVector);
75
+ }
76
+
77
+ this.owner.velocity.setVector(this.v);
78
+ },
79
+ "hit-non-static": function ({direction, entity: other}) {
80
+ let otherVSet = false,
81
+ relevantV = 0,
82
+ otherRelevantV = 0,
83
+ reboundV = 0;
84
+
85
+ if (this.hitThisTick.indexOf(other) >= 0) {
86
+ return;
87
+ }
88
+ this.hitThisTick.push(other);
89
+
90
+ for (let x = 0; x < this.otherVelocityData.length; x++) {
91
+ if (other === this.otherVelocityData[x].entity) {
92
+ this.otherV.setVector(this.otherVelocityData[x].velocity);
93
+ otherVSet = true;
94
+ break;
95
+ }
96
+ }
97
+
98
+ if (!otherVSet) {
99
+ this.otherV.setVector(other.velocity);
100
+ other.triggerEvent('share-velocity', this.owner);
101
+ }
102
+
103
+ this.v.setVector(this.owner.velocity);
104
+ this.incidentVector.setVector(direction);
105
+
106
+
107
+ relevantV = this.v.scalarProjection(this.incidentVector);
108
+ relevantV = (isNaN(relevantV)) ? 0 : relevantV;
109
+ otherRelevantV = this.otherV.scalarProjection(this.incidentVector);
110
+ otherRelevantV = (isNaN(otherRelevantV)) ? 0 : otherRelevantV;
111
+
112
+ reboundV = (relevantV * (this.owner.mass - other.mass) + 2 * other.mass * otherRelevantV) / (this.owner.mass + other.mass);
113
+
114
+ this.incidentVector.scale(reboundV - relevantV);
115
+
116
+ this.owner.velocity.setVector(this.incidentVector);
117
+
118
+ },
119
+ "share-velocity": function (other) {
120
+ this.otherVelocityData.push({
121
+ entity: other,
122
+ velocity: Vector.setUp(other.velocity)
123
+ });
124
+ }
125
+ },
126
+
127
+ methods: {// These are methods that are called by this component.
128
+ destroy: function () {
129
+ this.v.recycle();
130
+ this.incidentVector.recycle();
131
+ this.otherV.recycle();
132
+ arrayCache.recycle(this.hitThisTick);
133
+ arrayCache.recycle(this.otherVelocityData);
134
+ }
135
+ }
136
+ });