@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.
- package/CHANGELOG.md +10 -0
- package/README.md +3 -3
- package/lib/platypus.js +1 -1
- package/package.json +6 -5
- package/src/AABB.js +685 -0
- package/src/ActionState.js +121 -0
- package/src/AssetManager.js +206 -0
- package/src/CollisionData.js +96 -0
- package/src/CollisionDataContainer.js +127 -0
- package/src/CollisionShape.js +315 -0
- package/src/Component.js +231 -0
- package/src/Data.js +64 -0
- package/src/DataMap.js +204 -0
- package/src/Entity.js +404 -0
- package/src/EntityLinker.js +113 -0
- package/src/EventHandler.js +115 -0
- package/src/EventHandlerList.js +251 -0
- package/src/Game.js +840 -0
- package/src/Gamepad.js +175 -0
- package/src/ID3CaptionPlayer.js +61 -0
- package/src/Messenger.js +365 -0
- package/src/PIXIAnimation.js +622 -0
- package/src/RandomSet.js +140 -0
- package/src/SFXPlayer.js +120 -0
- package/src/StateMap.js +252 -0
- package/src/Storage.js +152 -0
- package/src/TickerClient.js +48 -0
- package/src/TickerServer.js +23 -0
- package/src/TimeEvent.js +50 -0
- package/src/TimeEventList.js +100 -0
- package/src/VOPlayer.js +684 -0
- package/src/Vector.js +702 -0
- package/src/components/AIChaser.js +161 -0
- package/src/components/AIPacer.js +107 -0
- package/src/components/AudioMusic.js +151 -0
- package/src/components/AudioSFX.js +673 -0
- package/src/components/AudioVO.js +301 -0
- package/src/components/CollisionBasic.js +826 -0
- package/src/components/CollisionFilter.js +74 -0
- package/src/components/CollisionGroup.js +448 -0
- package/src/components/CollisionTiles.js +608 -0
- package/src/components/ComponentSwitcher.js +173 -0
- package/src/components/ControllerInput.js +65 -0
- package/src/components/Counter.js +165 -0
- package/src/components/EntityCamera.js +215 -0
- package/src/components/EntityContainer.js +549 -0
- package/src/components/EntityController.js +541 -0
- package/src/components/HandlerCamera.js +1052 -0
- package/src/components/HandlerCollision.js +1318 -0
- package/src/components/HandlerController.js +291 -0
- package/src/components/HandlerLogic.js +394 -0
- package/src/components/HandlerRender.js +217 -0
- package/src/components/Interactive.js +502 -0
- package/src/components/LevelBuilder.js +524 -0
- package/src/components/LogicAngularMovement.js +154 -0
- package/src/components/LogicAttachment.js +265 -0
- package/src/components/LogicButton.js +466 -0
- package/src/components/LogicCarrier.js +39 -0
- package/src/components/LogicDestroyMe.js +58 -0
- package/src/components/LogicDirectionalMovement.js +325 -0
- package/src/components/LogicDragDrop.js +371 -0
- package/src/components/LogicImpactLaunch.js +144 -0
- package/src/components/LogicPacingPlatform.js +64 -0
- package/src/components/LogicPortable.js +112 -0
- package/src/components/LogicPortal.js +115 -0
- package/src/components/LogicPushable.js +98 -0
- package/src/components/LogicRebounder.js +136 -0
- package/src/components/LogicRegionSpawner.js +139 -0
- package/src/components/LogicRotationalMovement.js +205 -0
- package/src/components/LogicSpawner.js +159 -0
- package/src/components/LogicStateMachine.js +382 -0
- package/src/components/LogicSwitch.js +77 -0
- package/src/components/LogicTeleportee.js +68 -0
- package/src/components/LogicTeleporter.js +93 -0
- package/src/components/LogicTimer.js +178 -0
- package/src/components/LogicWindUpRacer.js +179 -0
- package/src/components/Motion.js +371 -0
- package/src/components/Mover.js +566 -0
- package/src/components/Node.js +289 -0
- package/src/components/NodeMap.js +295 -0
- package/src/components/NodeResident.js +636 -0
- package/src/components/Orientation.js +697 -0
- package/src/components/RandomEvents.js +73 -0
- package/src/components/RelativePosition.js +204 -0
- package/src/components/RelayFamily.js +106 -0
- package/src/components/RelayGame.js +53 -0
- package/src/components/RelayLinker.js +94 -0
- package/src/components/RelayParent.js +57 -0
- package/src/components/RelaySelf.js +55 -0
- package/src/components/Render.js +178 -0
- package/src/components/RenderAnimator.js +275 -0
- package/src/components/RenderContainer.js +646 -0
- package/src/components/RenderDebug.js +319 -0
- package/src/components/RenderDestroyMe.js +59 -0
- package/src/components/RenderLottie.js +149 -0
- package/src/components/RenderProgress.js +120 -0
- package/src/components/RenderSpine.js +833 -0
- package/src/components/RenderSprite.js +527 -0
- package/src/components/RenderText.js +147 -0
- package/src/components/RenderTiles.js +1391 -0
- package/src/components/SceneChanger.js +128 -0
- package/src/components/TiledLoader.js +1451 -0
- package/src/components/Timeline.js +314 -0
- package/src/components/Tutorial.js +267 -0
- package/src/components/Tween.js +296 -0
- package/src/components/VoiceOver.js +373 -0
- package/src/components/XHR.js +129 -0
- package/src/components/index.js +79 -0
- package/src/factory.js +305 -0
- package/src/index.js +159 -0
- package/src/mixins/PIXI.Graphics.js +41 -0
- package/src/platypus.css +68 -0
- package/src/sayHello.js +50 -0
- package/src/shapes/Capsule.js +74 -0
- package/src/shapes/Circle.js +43 -0
- package/src/shapes/Ellipse.js +117 -0
- package/src/shapes/Point.js +191 -0
- package/src/shapes/Polygon.js +112 -0
- package/src/shapes/Polyline.js +97 -0
- package/src/shapes/Rectangle.js +78 -0
- package/src/shapes/RoundedRectangle.js +33 -0
- package/src/shapes/Segment.js +346 -0
- package/src/shapes/adjustedXY.js +19 -0
- package/src/shapes/castFromBox2D.js +92 -0
- package/src/shapes/castFromObject.js +53 -0
- package/src/shapes/castFromPixiGraphics.js +6 -0
- package/src/shapes/castFromPixiShape.js +89 -0
- package/src/shapes/castToBox2D.js +190 -0
- package/src/shapes/castToPixiGraphics.js +100 -0
- package/src/shapes/castToPixiShape.js +61 -0
- package/src/shapes/checkPointsMap.js +313 -0
- package/src/shapes/index.js +35 -0
- package/src/utils/array.js +73 -0
- package/src/utils/string.js +39 -0
- package/lib/243.platypus.mjs +0 -1
- package/lib/platypus.mjs +0 -1
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
/* global platypus */
|
|
2
|
+
import Vector from '../Vector.js';
|
|
3
|
+
import createComponentClass from '../factory.js';
|
|
4
|
+
|
|
5
|
+
const
|
|
6
|
+
processDirection = function (direction) {
|
|
7
|
+
return function (state) {
|
|
8
|
+
this[direction] = !state || (state.pressed !== false);
|
|
9
|
+
};
|
|
10
|
+
},
|
|
11
|
+
doNothing = function () {},
|
|
12
|
+
rotate = {
|
|
13
|
+
x: function (heading, lastHeading) {
|
|
14
|
+
if (heading !== lastHeading) {
|
|
15
|
+
if (((heading > 180) && (lastHeading <= 180)) || ((heading <= 180) && (lastHeading > 180))) {
|
|
16
|
+
this.owner.triggerEvent('transform', 'vertical');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
y: function (heading, lastHeading) {
|
|
21
|
+
if (heading !== lastHeading) {
|
|
22
|
+
if (((heading > 90 && heading <= 270) && (lastHeading <= 90 || lastHeading > 270)) || ((heading <= 90 || heading > 270) && (lastHeading > 90 && lastHeading <= 270))) {
|
|
23
|
+
this.owner.triggerEvent('transform', 'horizontal');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
z: function (heading, lastHeading) {
|
|
28
|
+
if (heading !== lastHeading) {
|
|
29
|
+
this.owner.triggerEvent('replace-transform', 'rotate-' + heading);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default createComponentClass(/** @lends platypus.components.LogicDirectionalMovement.prototype */{
|
|
35
|
+
id: 'LogicDirectionalMovement',
|
|
36
|
+
|
|
37
|
+
properties: {
|
|
38
|
+
/**
|
|
39
|
+
* Defines the axis around which the entity should be transformed. Defaults to "y" for platforming behavior. Use "z" for top-down behavior.
|
|
40
|
+
*
|
|
41
|
+
* @property axis
|
|
42
|
+
* @type String
|
|
43
|
+
* @default "y"
|
|
44
|
+
*/
|
|
45
|
+
axis: 'y',
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Defines the distance in world units that the entity should be moved per millisecond.
|
|
49
|
+
*
|
|
50
|
+
* @property speed
|
|
51
|
+
* @type Number
|
|
52
|
+
* @default 0.3
|
|
53
|
+
*/
|
|
54
|
+
speed: 0.3
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* This component changes the [Motion](platypus.components.Motion.html) of an entity according to its current speed and heading. It accepts directional messages that can stand alone, or come from a mapped controller, in which case it checks the `pressed` value of the message before changing its course.
|
|
59
|
+
*
|
|
60
|
+
* @memberof platypus.components
|
|
61
|
+
* @uses platypus.Component
|
|
62
|
+
* @constructs
|
|
63
|
+
* @listens platypus.Entity#accelerate
|
|
64
|
+
* @listens platypus.Entity#component-added
|
|
65
|
+
* @listens platypus.Entity#face
|
|
66
|
+
* @listens platypus.Entity#handle-logic
|
|
67
|
+
* @listens platypus.Entity#stop
|
|
68
|
+
* @listens platypus.Entity#go-down
|
|
69
|
+
* @listens platypus.Entity#go-south
|
|
70
|
+
* @listens platypus.Entity#go-down-left
|
|
71
|
+
* @listens platypus.Entity#go-southwest
|
|
72
|
+
* @listens platypus.Entity#go-left
|
|
73
|
+
* @listens platypus.Entity#go-west
|
|
74
|
+
* @listens platypus.Entity#go-up-left
|
|
75
|
+
* @listens platypus.Entity#go-northwest
|
|
76
|
+
* @listens platypus.Entity#go-up
|
|
77
|
+
* @listens platypus.Entity#go-north
|
|
78
|
+
* @listens platypus.Entity#go-up-right
|
|
79
|
+
* @listens platypus.Entity#go-northeast
|
|
80
|
+
* @listens platypus.Entity#go-right
|
|
81
|
+
* @listens platypus.Entity#go-east
|
|
82
|
+
* @listens platypus.Entity#go-down-right
|
|
83
|
+
* @listens platypus.Entity#go-southeast
|
|
84
|
+
* @fires platypus.Entity#replace-transform
|
|
85
|
+
* @fires platypus.Entity#transform
|
|
86
|
+
*/
|
|
87
|
+
initialize: function () {
|
|
88
|
+
const
|
|
89
|
+
state = this.state = this.owner.state;
|
|
90
|
+
|
|
91
|
+
if (typeof this.speed === 'number') {
|
|
92
|
+
this.speed = [this.speed, 0, 0];
|
|
93
|
+
}
|
|
94
|
+
this.initialVector = Vector.setUp(this.speed);
|
|
95
|
+
this.reorient = rotate[this.axis];
|
|
96
|
+
if (!this.reorient) {
|
|
97
|
+
this.reorient = doNothing;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this.moving = state.set('moving', false);
|
|
101
|
+
this.left = state.set('left', false);
|
|
102
|
+
this.right = state.set('right', false);
|
|
103
|
+
this.up = state.set('up', false);
|
|
104
|
+
this.down = state.set('down', false);
|
|
105
|
+
|
|
106
|
+
this.upLeft = false;
|
|
107
|
+
this.upRight = false;
|
|
108
|
+
this.downLeft = false;
|
|
109
|
+
this.downRight = false;
|
|
110
|
+
|
|
111
|
+
this.heading = 0;
|
|
112
|
+
this.owner.heading = this.owner.heading || 0;
|
|
113
|
+
this.headingsMap = {
|
|
114
|
+
up: 270,
|
|
115
|
+
north: 270,
|
|
116
|
+
down: 90,
|
|
117
|
+
south: 90,
|
|
118
|
+
left: 180,
|
|
119
|
+
west: 180,
|
|
120
|
+
right: 0,
|
|
121
|
+
east: 0,
|
|
122
|
+
"up-left": 225,
|
|
123
|
+
northwest: 225,
|
|
124
|
+
"up-right": 315,
|
|
125
|
+
northeast: 315,
|
|
126
|
+
"down-left": 135,
|
|
127
|
+
southwest: 135,
|
|
128
|
+
"down-right": 45,
|
|
129
|
+
southeast: 45
|
|
130
|
+
};
|
|
131
|
+
},
|
|
132
|
+
events: {
|
|
133
|
+
"component-added": function (component) {
|
|
134
|
+
if (component === this) {
|
|
135
|
+
if (!this.owner.addMover) {
|
|
136
|
+
platypus.debug.warn('The "LogicDirectionalMovement" component requires a "Mover" component to function correctly.');
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
this.direction = this.owner.addMover({
|
|
141
|
+
velocity: this.speed,
|
|
142
|
+
drag: 0,
|
|
143
|
+
friction: 0,
|
|
144
|
+
stopOnCollision: false,
|
|
145
|
+
orient: false,
|
|
146
|
+
aliases: {
|
|
147
|
+
"moving": "control-velocity"
|
|
148
|
+
}
|
|
149
|
+
}).velocity;
|
|
150
|
+
|
|
151
|
+
if (this.owner.heading !== this.heading) {
|
|
152
|
+
this.direction.setVector(this.initialVector).rotate((this.owner.heading / 180) * Math.PI);
|
|
153
|
+
this.heading = this.owner.heading;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
this.owner.triggerEvent('moving', this.moving);
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
"handle-logic": function () {
|
|
161
|
+
const state = this.state,
|
|
162
|
+
upLeft = this.upLeft || (this.up && this.left),
|
|
163
|
+
downLeft = this.downLeft || (this.down && this.left),
|
|
164
|
+
downRight = this.downRight || (this.down && this.right),
|
|
165
|
+
upRight = this.upRight || (this.up && this.right);
|
|
166
|
+
let up = this.up || this.upLeft || this.upRight,
|
|
167
|
+
left = this.left || this.upLeft || this.downLeft,
|
|
168
|
+
down = this.down || this.downLeft || this.downRight,
|
|
169
|
+
right = this.right || this.upRight || this.downRight;
|
|
170
|
+
|
|
171
|
+
if ((left && right) || (up && down)) {
|
|
172
|
+
this.moving = false;
|
|
173
|
+
} else if (upLeft) {
|
|
174
|
+
this.moving = true;
|
|
175
|
+
this.heading = 225;
|
|
176
|
+
} else if (upRight) {
|
|
177
|
+
this.moving = true;
|
|
178
|
+
this.heading = 315;
|
|
179
|
+
} else if (downLeft) {
|
|
180
|
+
this.moving = true;
|
|
181
|
+
this.heading = 135;
|
|
182
|
+
} else if (downRight) {
|
|
183
|
+
this.moving = true;
|
|
184
|
+
this.heading = 45;
|
|
185
|
+
} else if (left) {
|
|
186
|
+
this.moving = true;
|
|
187
|
+
this.heading = 180;
|
|
188
|
+
} else if (right) {
|
|
189
|
+
this.moving = true;
|
|
190
|
+
this.heading = 0;
|
|
191
|
+
} else if (up) {
|
|
192
|
+
this.moving = true;
|
|
193
|
+
this.heading = 270;
|
|
194
|
+
} else if (down) {
|
|
195
|
+
this.moving = true;
|
|
196
|
+
this.heading = 90;
|
|
197
|
+
} else {
|
|
198
|
+
this.moving = false;
|
|
199
|
+
|
|
200
|
+
// This is to retain the entity's direction even if there is no movement. There's probably a better way to do this since this is a bit of a retrofit. - DDD
|
|
201
|
+
switch (this.heading) {
|
|
202
|
+
case 270:
|
|
203
|
+
up = true;
|
|
204
|
+
break;
|
|
205
|
+
case 90:
|
|
206
|
+
down = true;
|
|
207
|
+
break;
|
|
208
|
+
case 180:
|
|
209
|
+
left = true;
|
|
210
|
+
break;
|
|
211
|
+
case 225:
|
|
212
|
+
up = true;
|
|
213
|
+
left = true;
|
|
214
|
+
break;
|
|
215
|
+
case 315:
|
|
216
|
+
up = true;
|
|
217
|
+
right = true;
|
|
218
|
+
break;
|
|
219
|
+
case 135:
|
|
220
|
+
down = true;
|
|
221
|
+
left = true;
|
|
222
|
+
break;
|
|
223
|
+
case 45:
|
|
224
|
+
down = true;
|
|
225
|
+
right = true;
|
|
226
|
+
break;
|
|
227
|
+
case 0:
|
|
228
|
+
default:
|
|
229
|
+
right = true;
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (this.owner.heading !== this.heading) {
|
|
235
|
+
this.direction.setVector(this.initialVector).rotate((this.heading / 180) * Math.PI);
|
|
236
|
+
this.reorient(this.heading, this.owner.heading);
|
|
237
|
+
this.owner.heading = this.heading;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
//TODO: possibly remove the separation of this.state.direction and this.direction to just use state?
|
|
241
|
+
if (state.get('moving') !== this.moving) {
|
|
242
|
+
this.owner.triggerEvent('moving', this.moving);
|
|
243
|
+
state.set('moving', this.moving);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
state.set('up', up);
|
|
247
|
+
state.set('right', right);
|
|
248
|
+
state.set('down', down);
|
|
249
|
+
state.set('left', left);
|
|
250
|
+
},
|
|
251
|
+
|
|
252
|
+
"go-down": processDirection('down'),
|
|
253
|
+
|
|
254
|
+
"go-south": processDirection('down'),
|
|
255
|
+
|
|
256
|
+
"go-down-left": processDirection('downLeft'),
|
|
257
|
+
|
|
258
|
+
"go-southwest": processDirection('downLeft'),
|
|
259
|
+
|
|
260
|
+
"go-left": processDirection('left'),
|
|
261
|
+
|
|
262
|
+
"go-west": processDirection('left'),
|
|
263
|
+
|
|
264
|
+
"go-up-left": processDirection('upLeft'),
|
|
265
|
+
|
|
266
|
+
"go-northwest": processDirection('upLeft'),
|
|
267
|
+
|
|
268
|
+
"go-up": processDirection('up'),
|
|
269
|
+
|
|
270
|
+
"go-north": processDirection('up'),
|
|
271
|
+
|
|
272
|
+
"go-up-right": processDirection('upRight'),
|
|
273
|
+
|
|
274
|
+
"go-northeast": processDirection('upRight'),
|
|
275
|
+
|
|
276
|
+
"go-right": processDirection('right'),
|
|
277
|
+
|
|
278
|
+
"go-east": processDirection('right'),
|
|
279
|
+
|
|
280
|
+
"go-down-right": processDirection('downRight'),
|
|
281
|
+
|
|
282
|
+
"go-southeast": processDirection('downRight'),
|
|
283
|
+
|
|
284
|
+
"stop": function (state) {
|
|
285
|
+
if (!state || (state.pressed !== false)) {
|
|
286
|
+
this.left = false;
|
|
287
|
+
this.right = false;
|
|
288
|
+
this.up = false;
|
|
289
|
+
this.down = false;
|
|
290
|
+
this.upLeft = false;
|
|
291
|
+
this.upRight = false;
|
|
292
|
+
this.downLeft = false;
|
|
293
|
+
this.downRight = false;
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Set the direction the entity should face while stopped.
|
|
299
|
+
*
|
|
300
|
+
* @event platypus.Entity#face
|
|
301
|
+
* @param direction {String} A value such as "north" or "left" to point the entity in a particular direction.
|
|
302
|
+
*/
|
|
303
|
+
"face": function (direction) {
|
|
304
|
+
this.heading = this.headingsMap[direction] || 0;
|
|
305
|
+
},
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Changes the velocity of the Entity when in motion.
|
|
309
|
+
*
|
|
310
|
+
* @event platypus.Entity#accelerate
|
|
311
|
+
* @param velocity {Number|platypus.Vector} The magnitude or Vector to multiply the current velocity by.
|
|
312
|
+
*/
|
|
313
|
+
"accelerate": function (velocity) {
|
|
314
|
+
this.initialVector.normalize().multiply(velocity);
|
|
315
|
+
this.direction.normalize().multiply(velocity);
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
|
|
319
|
+
methods: {
|
|
320
|
+
destroy: function () {
|
|
321
|
+
this.initialVector.recycle();
|
|
322
|
+
this.state = null;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
});
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
/* global platypus */
|
|
2
|
+
import {Container, Rectangle} from 'pixi.js';
|
|
3
|
+
import createComponentClass from '../factory.js';
|
|
4
|
+
|
|
5
|
+
const
|
|
6
|
+
claimHitArea = new Rectangle(-2000, -2000, 4000, 4000),
|
|
7
|
+
allDraggedItems = [];
|
|
8
|
+
|
|
9
|
+
export default createComponentClass(/** @lends platypus.components.LogicDragDrop.prototype */{
|
|
10
|
+
id: 'LogicDragDrop',
|
|
11
|
+
|
|
12
|
+
properties: {
|
|
13
|
+
//TODO: Impement Multi-Drag
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Sets how far a `pressmove` event can deviate from the original `pointerdown` before a stickyClick becomes unstuck (ie normal drag-drop). `0` means any movement will unstick the click. `10` means the mouse needs to move more than 10 units before the unstick occurs. `stickyClick` must be enabled for this property to matter.
|
|
17
|
+
*
|
|
18
|
+
* @property stickiness
|
|
19
|
+
* @type Number
|
|
20
|
+
* @default 0
|
|
21
|
+
*/
|
|
22
|
+
stickiness: 0,
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Sets whether an entity can be dragged at initial. Change via disable-drag().
|
|
26
|
+
*
|
|
27
|
+
* @property dragDisabled
|
|
28
|
+
* @type Boolean
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
dragDisabled: false
|
|
32
|
+
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
publicProperties: {
|
|
36
|
+
/**
|
|
37
|
+
* Whether dragged items must stay within the camera frame.
|
|
38
|
+
*
|
|
39
|
+
* @property stayInViewport
|
|
40
|
+
* @type Boolean
|
|
41
|
+
* @default false
|
|
42
|
+
*/
|
|
43
|
+
stayInViewport: false,
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Sets whether a click-move should start the dragging behavior in addition to click-drag. Defaults to `true` on desktop and `false` on mobile devices.
|
|
47
|
+
*
|
|
48
|
+
* @property stickyClick
|
|
49
|
+
* @type Boolean
|
|
50
|
+
* @default undefined
|
|
51
|
+
*/
|
|
52
|
+
stickyClick: undefined
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* A component that allows an object to be dragged and dropped. Can use collision to prevent dropping the objects in certain locations.
|
|
57
|
+
*
|
|
58
|
+
* @memberof platypus.components
|
|
59
|
+
* @uses platypus.Component
|
|
60
|
+
* @constructs
|
|
61
|
+
* @listens platypus.Entity#camera-update
|
|
62
|
+
* @listens platypus.Entity#component-added
|
|
63
|
+
* @listens platypus.Entity#handle-logic
|
|
64
|
+
* @listens platypus.Entity#handle-post-collision-logic
|
|
65
|
+
* @listens platypus.Entity#pointerdown
|
|
66
|
+
* @listens platypus.Entity#pointermove
|
|
67
|
+
* @listens platypus.Entity#prepare-logic
|
|
68
|
+
* @listens platypus.Entity#pressmove
|
|
69
|
+
* @listens platypus.Entity#pressup
|
|
70
|
+
*/
|
|
71
|
+
initialize: function () {
|
|
72
|
+
this.aabb = this.owner.parent.worldCamera.viewport;
|
|
73
|
+
this.cameraScaleX = 1;
|
|
74
|
+
this.cameraScaleY = 1;
|
|
75
|
+
this.nextX = this.owner.x;
|
|
76
|
+
this.nextY = this.owner.y;
|
|
77
|
+
this.grabOffsetX = 0;
|
|
78
|
+
this.grabOffsetY = 0;
|
|
79
|
+
this.state = this.owner.state;
|
|
80
|
+
this.state.set('dragging', false);
|
|
81
|
+
this.dragId = null;
|
|
82
|
+
this.originalContainer = null
|
|
83
|
+
this.dragContainer = new Container();
|
|
84
|
+
|
|
85
|
+
this.dragContainer.zIndex = Infinity;
|
|
86
|
+
|
|
87
|
+
if (this.stickyClick === undefined) {
|
|
88
|
+
this.stickyClick = !platypus.supports.mobile;
|
|
89
|
+
}
|
|
90
|
+
this.releaseStick = false;
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
events: {
|
|
94
|
+
"camera-update": function ({scaleX, scaleY}) {
|
|
95
|
+
this.cameraScaleX = scaleX;
|
|
96
|
+
this.cameraScaleY = scaleY;
|
|
97
|
+
this.checkCamera();
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
"prepare-logic": function () {
|
|
101
|
+
this.checkCamera(); // may end dragging
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
"handle-logic": function () {
|
|
105
|
+
let defaultCancelled = false;
|
|
106
|
+
|
|
107
|
+
if (this.state.get('dragging')) {
|
|
108
|
+
const
|
|
109
|
+
{dragContainer, nextX, nextY, owner} = this;
|
|
110
|
+
|
|
111
|
+
owner.triggerEvent('dragging', {
|
|
112
|
+
dragContainer,
|
|
113
|
+
entity: owner,
|
|
114
|
+
x: nextX,
|
|
115
|
+
y: nextY,
|
|
116
|
+
pointer: {
|
|
117
|
+
x: nextX + this.grabOffsetX,
|
|
118
|
+
y: nextY + this.grabOffsetY
|
|
119
|
+
},
|
|
120
|
+
preventDefault: () => {
|
|
121
|
+
defaultCancelled = true;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
if (!defaultCancelled) {
|
|
126
|
+
owner.x = nextX;
|
|
127
|
+
owner.y = nextY;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
"pointerdown": function (eventData) {
|
|
133
|
+
if (this.dragDisabled) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (this.sticking) {
|
|
138
|
+
this.sticking = null;
|
|
139
|
+
this.nextX = eventData.x - this.grabOffsetX;
|
|
140
|
+
this.nextY = eventData.y - this.grabOffsetY;
|
|
141
|
+
if (this.stayInViewport) {
|
|
142
|
+
this.checkCamera();
|
|
143
|
+
}
|
|
144
|
+
this.releaseStick = true; // Delay release until logic runs in case of collision checks, etc.
|
|
145
|
+
} else {
|
|
146
|
+
const
|
|
147
|
+
{owner} = this;
|
|
148
|
+
|
|
149
|
+
if (this.dragId === null) {
|
|
150
|
+
const
|
|
151
|
+
{dragContainer} = this;
|
|
152
|
+
let defaultCancelled = false;
|
|
153
|
+
|
|
154
|
+
this.dragId = eventData.event.pointerId;
|
|
155
|
+
|
|
156
|
+
owner.triggerEvent('drag-start', {
|
|
157
|
+
dragContainer,
|
|
158
|
+
entity: owner,
|
|
159
|
+
preventDefault: () => {
|
|
160
|
+
defaultCancelled = true;
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
if (defaultCancelled) {
|
|
165
|
+
this.dragId = null;
|
|
166
|
+
} else {
|
|
167
|
+
const
|
|
168
|
+
{state} = this,
|
|
169
|
+
{x, y} = owner;
|
|
170
|
+
|
|
171
|
+
this.nextX = x;
|
|
172
|
+
this.nextY = y;
|
|
173
|
+
this.grabOffsetX = (eventData.x >> 0) - x;
|
|
174
|
+
this.grabOffsetY = (eventData.y >> 0) - y;
|
|
175
|
+
state.set('dragging', true);
|
|
176
|
+
owner.dragMode = true;
|
|
177
|
+
this.sticking = this.stickyClick ? {x, y} : null;
|
|
178
|
+
this.claimPointer();
|
|
179
|
+
|
|
180
|
+
// put in top layer
|
|
181
|
+
this.checkCamera(); //update dragContainer dimensions
|
|
182
|
+
this.originalContainer = owner.container.parent;
|
|
183
|
+
dragContainer.addChild(owner.container);
|
|
184
|
+
owner.parent.stage.addChild(dragContainer);
|
|
185
|
+
allDraggedItems.push(this);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
eventData.pixiEvent.stopPropagation();
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
"pressup": function (eventData) {
|
|
194
|
+
if (this.releaseStick) {
|
|
195
|
+
this.release();
|
|
196
|
+
this.releaseStick = false;
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (!this.state.get('dragging')) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (this.dragId !== null && !this.sticking) {
|
|
205
|
+
this.release();
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
eventData.pixiEvent.stopPropagation();
|
|
209
|
+
},
|
|
210
|
+
|
|
211
|
+
"input-off": function () {
|
|
212
|
+
if (this.state.get('dragging') && this.dragId !== null) {
|
|
213
|
+
this.release();
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
|
|
217
|
+
"pointermove": function (eventData) {
|
|
218
|
+
if (!this.state.get('dragging')) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (this.sticking) {
|
|
223
|
+
this.nextX = eventData.x - this.grabOffsetX;
|
|
224
|
+
this.nextY = eventData.y - this.grabOffsetY;
|
|
225
|
+
if (this.stayInViewport) {
|
|
226
|
+
this.checkCamera();
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
eventData.event.preventDefault();
|
|
230
|
+
eventData.pixiEvent.stopPropagation();
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
"pressmove": function (eventData) {
|
|
235
|
+
if (!this.state.get('dragging')) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (this.dragId !== null) {
|
|
240
|
+
const
|
|
241
|
+
{stickiness, sticking} = this;
|
|
242
|
+
|
|
243
|
+
this.nextX = eventData.x - this.grabOffsetX;
|
|
244
|
+
this.nextY = eventData.y - this.grabOffsetY;
|
|
245
|
+
if (this.stayInViewport) {
|
|
246
|
+
this.checkCamera();
|
|
247
|
+
}
|
|
248
|
+
if (sticking && (((this.nextX - sticking.x) ** 2) + ((this.nextY - sticking.y) ** 2) > stickiness ** 2)) {
|
|
249
|
+
this.sticking = null;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
eventData.event.preventDefault();
|
|
253
|
+
eventData.pixiEvent.stopPropagation();
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
|
|
257
|
+
"disable-drag": function (disable) {
|
|
258
|
+
//If we don't send in a value, we toggle the dragDisabled.
|
|
259
|
+
this.dragDisabled = typeof disable === 'boolean' ? disable : !this.dragDisabled;
|
|
260
|
+
|
|
261
|
+
if (this.dragDisabled && this.state.get('dragging')) {
|
|
262
|
+
this.release();
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
|
|
267
|
+
methods: {// These are methods that are called by this component.
|
|
268
|
+
checkCamera () {
|
|
269
|
+
const
|
|
270
|
+
{state, stayInViewport} = this,
|
|
271
|
+
dragging = state?.get('dragging');
|
|
272
|
+
|
|
273
|
+
if (dragging || stayInViewport) {
|
|
274
|
+
const
|
|
275
|
+
{aabb} = this;
|
|
276
|
+
|
|
277
|
+
if (!aabb.containsPoint(dragging ? this.nextX + this.grabOffsetX : this.owner.x, dragging ? this.nextY + this.grabOffsetY : this.owner.y)) {
|
|
278
|
+
if (this.stayInViewport) {
|
|
279
|
+
if (dragging) {
|
|
280
|
+
this.nextX = Math.min(aabb.right, Math.max(aabb.left, this.nextX + this.grabOffsetX)) - this.grabOffsetX;
|
|
281
|
+
this.nextY = Math.min(aabb.bottom, Math.max(aabb.top, this.nextY + this.grabOffsetY)) - this.grabOffsetY;
|
|
282
|
+
} else {
|
|
283
|
+
this.owner.x = Math.min(aabb.right, Math.max(aabb.left, this.owner.x));
|
|
284
|
+
this.owner.y = Math.min(aabb.bottom, Math.max(aabb.top, this.owner.y));
|
|
285
|
+
}
|
|
286
|
+
} else {
|
|
287
|
+
this.release();
|
|
288
|
+
}
|
|
289
|
+
} else { // adjust container if needed.
|
|
290
|
+
const
|
|
291
|
+
{cameraScaleX, cameraScaleY, dragContainer} = this;
|
|
292
|
+
|
|
293
|
+
dragContainer.scale.x = cameraScaleX;
|
|
294
|
+
dragContainer.scale.y = cameraScaleY;
|
|
295
|
+
dragContainer.x = -(aabb.left * cameraScaleX);
|
|
296
|
+
dragContainer.y = -(aabb.top * cameraScaleY);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
|
|
301
|
+
claimPointer () {
|
|
302
|
+
this.lastHitArea = this.owner.container.hitArea;
|
|
303
|
+
|
|
304
|
+
this.owner.container.hitArea = claimHitArea; // capture all the clicks!
|
|
305
|
+
},
|
|
306
|
+
|
|
307
|
+
releasePointer () {
|
|
308
|
+
this.owner.container.hitArea = this.lastHitArea;
|
|
309
|
+
},
|
|
310
|
+
|
|
311
|
+
releaseContainer () {
|
|
312
|
+
const
|
|
313
|
+
{originalContainer, owner} = this,
|
|
314
|
+
index = allDraggedItems.indexOf(this);
|
|
315
|
+
|
|
316
|
+
if (index >= 0) {
|
|
317
|
+
allDraggedItems.splice(index, 1);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (originalContainer) {
|
|
321
|
+
owner.parent.stage.removeChild(this.dragContainer);
|
|
322
|
+
originalContainer.addChild(owner.container);
|
|
323
|
+
this.originalContainer = null;
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
|
|
327
|
+
release () {
|
|
328
|
+
const
|
|
329
|
+
{dragContainer, owner, state} = this,
|
|
330
|
+
dropX = owner.x,
|
|
331
|
+
dropY = owner.y;
|
|
332
|
+
let defaultCancelled = false;
|
|
333
|
+
|
|
334
|
+
this.sticking = null;
|
|
335
|
+
|
|
336
|
+
this.dragId = null;
|
|
337
|
+
state.set('dragging', false);
|
|
338
|
+
owner.dragMode = false;
|
|
339
|
+
this.releasePointer();
|
|
340
|
+
|
|
341
|
+
this.releaseContainer();
|
|
342
|
+
|
|
343
|
+
owner.triggerEvent('drop', {
|
|
344
|
+
dragContainer,
|
|
345
|
+
entity: owner,
|
|
346
|
+
x: dropX,
|
|
347
|
+
y: dropY,
|
|
348
|
+
preventDefault: () => {
|
|
349
|
+
defaultCancelled = true;
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
if (!defaultCancelled) {
|
|
354
|
+
//do default drop actions here
|
|
355
|
+
owner.x = dropX;
|
|
356
|
+
owner.y = dropY;
|
|
357
|
+
owner.triggerEvent('drop-complete');
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
|
|
361
|
+
destroy () {
|
|
362
|
+
if (this.state.get('dragging')) {
|
|
363
|
+
this.dragId = null;
|
|
364
|
+
this.releaseContainer();
|
|
365
|
+
this.state.set('dragging', false);
|
|
366
|
+
}
|
|
367
|
+
this.owner.dragMode = false;
|
|
368
|
+
this.state = null;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
});
|