|
2 | 2 | "author": "D8H", |
3 | 3 | "category": "Movement", |
4 | 4 | "extensionNamespace": "", |
5 | | - "gdevelopVersion": ">=5.5.222", |
6 | 5 | "fullName": "Stick objects to others", |
| 6 | + "gdevelopVersion": ">=5.5.222", |
7 | 7 | "helpPath": "", |
8 | 8 | "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLXN0aWNrZXItb3V0bGluZSIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiPjxwYXRoIGQ9Ik01LjUgMkMzLjYgMiAyIDMuNiAyIDUuNVYxOC41QzIgMjAuNCAzLjYgMjIgNS41IDIySDE2TDIyIDE2VjUuNUMyMiAzLjYgMjAuNCAyIDE4LjUgMkg1LjVNNS44IDRIMTguM0MxOS4zIDQgMjAuMSA0LjggMjAuMSA1LjhWMTVIMTguNkMxNi43IDE1IDE1LjEgMTYuNiAxNS4xIDE4LjVWMjBINS44QzQuOCAyMCA0IDE5LjIgNCAxOC4yVjUuOEM0IDQuOCA0LjggNCA1LjggNCIgLz48L3N2Zz4=", |
9 | 9 | "name": "Sticker", |
10 | 10 | "previewIconUrl": "https://resources.gdevelop-app.com/assets/Icons/sticker-outline.svg", |
11 | 11 | "shortDescription": "Make objects follow the position and rotation of the object they are stuck to.", |
12 | | - "version": "0.5.1", |
| 12 | + "version": "0.5.2", |
13 | 13 | "description": [ |
14 | 14 | "This extension can be useful to:", |
15 | | - "* Stick accessories to moving objects", |
16 | | - "* Animate a skeleton", |
17 | | - "* Delete an object with another one", |
| 15 | + "- Stick accessories to moving objects", |
| 16 | + "- Animate a skeleton", |
| 17 | + "- Delete an object with another one", |
18 | 18 | "", |
19 | 19 | "An example allows to check it out ([open the project online](https://editor.gdevelop.io/?project=example://stick-objects))." |
20 | 20 | ], |
|
41 | 41 | "IWykYNRvhCZBN3vEgKEbBPOR3Oc2" |
42 | 42 | ], |
43 | 43 | "dependencies": [], |
| 44 | + "globalVariables": [], |
| 45 | + "sceneVariables": [], |
44 | 46 | "eventsFunctions": [ |
45 | 47 | { |
46 | 48 | "description": "Define helper classes JavaScript code.", |
|
147 | 149 | " const deltaX = object.getCenterXInScene() - this.basisOldCenterXInScene;", |
148 | 150 | " const deltaY = object.getCenterYInScene() - this.basisOldCenterYInScene;", |
149 | 151 | " const angle = this.basisOldAngle * Math.PI / 180;", |
150 | | - " this.relativeRotatedX = (deltaX * Math.cos(angle) + deltaY * Math.sin(angle)) / this.basisOldWidth;", |
151 | | - " this.relativeRotatedY = (-deltaX * Math.sin(angle) + deltaY * Math.cos(angle)) / this.basisOldHeight;", |
| 152 | + " const cosA = Math.cos(angle);", |
| 153 | + " const sinA = Math.sin(angle);", |
| 154 | + " this.relativeRotatedX = (deltaX * cosA + deltaY * sinA) / this.basisOldWidth;", |
| 155 | + " this.relativeRotatedY = (-deltaX * sinA + deltaY * cosA) / this.basisOldHeight;", |
152 | 156 | "", |
153 | 157 | " // Save initial values to avoid calculus and rounding errors", |
154 | 158 | " this.basisOriginalWidth = this.basisObject.getWidth();", |
|
194 | 198 | " }", |
195 | 199 | " this.followingDoneThisFrame = true;", |
196 | 200 | " const basisObject = this.basisObject;", |
197 | | - " if (basisObject) {", |
198 | | - " // If the behavior on the basis object has a different name,", |
199 | | - " // the objects will still follow their basis objects", |
200 | | - " // but frame delays could happen.", |
201 | | - " const behaviorName = this.behavior.getName();", |
202 | | - " if (basisObject.hasBehavior(behaviorName)) {", |
203 | | - " const basisBehavior = basisObject.getBehavior(behaviorName);", |
204 | | - " if (basisBehavior.type === this.behavior.type) {", |
205 | | - " // Follow parents 1st to avoid frame delays", |
206 | | - " basisBehavior._sticker.followBasisObject();", |
207 | | - " }", |
| 201 | + " if (!basisObject) {", |
| 202 | + " return;", |
| 203 | + " }", |
| 204 | + " // If the behavior on the basis object has a different name,", |
| 205 | + " // the objects will still follow their basis objects", |
| 206 | + " // but frame delays could happen.", |
| 207 | + " const behaviorName = this.behavior.getName();", |
| 208 | + " if (basisObject.hasBehavior(behaviorName)) {", |
| 209 | + " const basisBehavior = basisObject.getBehavior(behaviorName);", |
| 210 | + " if (basisBehavior.type === this.behavior.type) {", |
| 211 | + " // Follow parents 1st to avoid frame delays", |
| 212 | + " basisBehavior._sticker.followBasisObject();", |
208 | 213 | " }", |
| 214 | + " }", |
| 215 | + " if (this.behavior._getOnlyFollowPosition()) {", |
| 216 | + " this.followPosition();", |
| 217 | + " } else {", |
| 218 | + " this.followTransformation();", |
| 219 | + " }", |
| 220 | + " this.updateOldCoordinates();", |
| 221 | + " }", |
209 | 222 | "", |
210 | | - " const object = this.behavior.owner;", |
211 | | - "", |
212 | | - " if (this.behavior._getOnlyFollowPosition()) {", |
213 | | - " if (object.getX() !== this.ownerOldX", |
214 | | - " || object.getY() !== this.ownerOldY) {", |
215 | | - " this.updateRelativeCoordinates();", |
216 | | - " }", |
217 | | - "", |
218 | | - " if (this.basisOldX !== basisObject.getX() ||", |
219 | | - " this.basisOldY !== basisObject.getY()) {", |
220 | | - " object.setPosition(", |
221 | | - " basisObject.getX() + this.relativeX,", |
222 | | - " basisObject.getY() + this.relativeY);", |
223 | | - " }", |
224 | | - " } else {", |
225 | | - " if (object.getX() !== this.ownerOldX", |
226 | | - " || object.getY() !== this.ownerOldY", |
227 | | - " || object.getAngle() !== this.ownerOldAngle", |
228 | | - " || object.getWidth() !== this.ownerOldWidth", |
229 | | - " || object.getHeight() !== this.ownerOldHeight) {", |
230 | | - " this.updateRelativeCoordinates();", |
231 | | - " }", |
| 223 | + " followPosition() {", |
| 224 | + " const object = this.behavior.owner;", |
| 225 | + " const basisObject = this.basisObject;", |
| 226 | + " if (!basisObject) {", |
| 227 | + " return;", |
| 228 | + " }", |
| 229 | + " if (object.getX() !== this.ownerOldX", |
| 230 | + " || object.getY() !== this.ownerOldY) {", |
| 231 | + " this.updateRelativeCoordinates();", |
| 232 | + " }", |
| 233 | + " if (this.basisOldX !== basisObject.getX()", |
| 234 | + " || this.basisOldY !== basisObject.getY()) {", |
| 235 | + " object.setPosition(", |
| 236 | + " basisObject.getX() + this.relativeX,", |
| 237 | + " basisObject.getY() + this.relativeY);", |
| 238 | + " }", |
| 239 | + " }", |
232 | 240 | "", |
233 | | - " // Follow basisObject", |
234 | | - " if (basisObject.getAngle() === this.basisOriginalAngle && this.basisOriginalAngle === 0) {", |
235 | | - " if (basisObject.getWidth() === this.basisOriginalWidth ||", |
236 | | - " basisObject.getHeight() === this.basisOriginalHeight) {", |
237 | | - " if (this.basisOldX !== basisObject.getX() ||", |
238 | | - " this.basisOldY !== basisObject.getY()) {", |
239 | | - " object.setPosition(", |
240 | | - " basisObject.getX() + this.relativeX,", |
241 | | - " basisObject.getY() + this.relativeY);", |
242 | | - " }", |
243 | | - " } else {", |
244 | | - " object.setCenterPositionInScene(", |
245 | | - " basisObject.getCenterXInScene() + this.relativeRotatedX * basisObject.getWidth(),", |
246 | | - " basisObject.getCenterYInScene() + this.relativeRotatedY * basisObject.getHeight());", |
| 241 | + " followTransformation() {", |
| 242 | + " const object = this.behavior.owner;", |
| 243 | + " const basisObject = this.basisObject;", |
| 244 | + " if (!basisObject) {", |
| 245 | + " return;", |
| 246 | + " }", |
| 247 | + " if (object.getX() !== this.ownerOldX", |
| 248 | + " || object.getY() !== this.ownerOldY", |
| 249 | + " || object.getAngle() !== this.ownerOldAngle", |
| 250 | + " || object.getWidth() !== this.ownerOldWidth", |
| 251 | + " || object.getHeight() !== this.ownerOldHeight) {", |
| 252 | + " this.updateRelativeCoordinates();", |
| 253 | + " }", |
| 254 | + " if (this.basisOldAngle !== this.basisObject.getAngle()", |
| 255 | + " || this.basisOldWidth !== this.basisObject.getWidth()", |
| 256 | + " || this.basisOldHeight !== this.basisObject.getHeight()", |
| 257 | + " || this.basisOldCenterXInScene !== this.basisObject.getCenterXInScene()", |
| 258 | + " || this.basisOldCenterYInScene !== this.basisObject.getCenterYInScene()) {", |
| 259 | + " // Unproportional dimensions changes won't work as expected", |
| 260 | + " // if the object angle is not null but nothing more can be done", |
| 261 | + " // because there is no full affine transformation on objects.", |
| 262 | + " if (basisObject.getWidth() !== this.basisOriginalWidth) {", |
| 263 | + " object.setWidth(this.relativeWidth * basisObject.getWidth());", |
| 264 | + " }", |
| 265 | + " if (basisObject.getHeight() !== this.basisOriginalHeight) {", |
| 266 | + " object.setHeight(this.relativeHeight * basisObject.getHeight());", |
| 267 | + " }", |
| 268 | + " // Follow basisObject", |
| 269 | + " if (basisObject.getAngle() === this.basisOriginalAngle", |
| 270 | + " && this.basisOriginalAngle === 0) {", |
| 271 | + " if (basisObject.getWidth() === this.basisOriginalWidth", |
| 272 | + " || basisObject.getHeight() === this.basisOriginalHeight) {", |
| 273 | + " if (this.basisOldX !== basisObject.getX() ||", |
| 274 | + " this.basisOldY !== basisObject.getY()) {", |
| 275 | + " object.setPosition(", |
| 276 | + " basisObject.getX() + this.relativeX,", |
| 277 | + " basisObject.getY() + this.relativeY);", |
247 | 278 | " }", |
248 | 279 | " } else {", |
249 | | - " object.setAngle(basisObject.getAngle() + this.relativeAngle);", |
250 | | - "", |
251 | | - " const deltaX = this.relativeRotatedX * basisObject.getWidth();", |
252 | | - " const deltaY = this.relativeRotatedY * basisObject.getHeight();", |
253 | | - " const angle = -basisObject.getAngle() * Math.PI / 180;", |
254 | | - " object.setX(basisObject.getCenterXInScene() + object.getX() - object.getCenterXInScene() + deltaX * Math.cos(angle) + deltaY * Math.sin(angle));", |
255 | | - " object.setY(basisObject.getCenterYInScene() + object.getY() - object.getCenterYInScene() - deltaX * Math.sin(angle) + deltaY * Math.cos(angle));", |
256 | | - " }", |
257 | | - " // Unproportional dimensions changes won't work as expected", |
258 | | - " // if the object angle is not null but nothing more can be done", |
259 | | - " // because there is no full affine transformation on objects.", |
260 | | - " if (basisObject.getWidth() !== this.basisOriginalWidth) {", |
261 | | - " object.setWidth(this.relativeWidth * basisObject.getWidth());", |
| 280 | + " object.setCenterPositionInScene(", |
| 281 | + " basisObject.getCenterXInScene() + this.relativeRotatedX * basisObject.getWidth(),", |
| 282 | + " basisObject.getCenterYInScene() + this.relativeRotatedY * basisObject.getHeight());", |
262 | 283 | " }", |
263 | | - " if (basisObject.getHeight() !== this.basisOriginalHeight) {", |
264 | | - " object.setHeight(this.relativeHeight * basisObject.getHeight());", |
265 | | - " }", |
266 | | - " }", |
| 284 | + " } else {", |
| 285 | + " object.setAngle(basisObject.getAngle() + this.relativeAngle);", |
267 | 286 | "", |
268 | | - " this.updateOldCoordinates();", |
| 287 | + " const deltaX = this.relativeRotatedX * basisObject.getWidth();", |
| 288 | + " const deltaY = this.relativeRotatedY * basisObject.getHeight();", |
| 289 | + " const angle = -basisObject.getAngle() * Math.PI / 180;", |
| 290 | + " const cosA = Math.cos(angle);", |
| 291 | + " const sinA = Math.sin(angle);", |
| 292 | + " object.setX(", |
| 293 | + " basisObject.getCenterXInScene() + object.getX() - object.getCenterXInScene()", |
| 294 | + " + deltaX * cosA + deltaY * sinA);", |
| 295 | + " object.setY(", |
| 296 | + " basisObject.getCenterYInScene() + object.getY() - object.getCenterYInScene()", |
| 297 | + " - deltaX * sinA + deltaY * cosA);", |
| 298 | + " }", |
269 | 299 | " }", |
270 | 300 | " }", |
271 | 301 | "}", |
|
0 commit comments