|
4 | 4 | // By: SharkPool
|
5 | 5 | // License: MIT
|
6 | 6 |
|
7 |
| -// Version V.1.0.07 |
| 7 | +// Version V.1.0.08 |
8 | 8 |
|
9 | 9 | (function (Scratch) {
|
10 | 10 | "use strict";
|
|
53 | 53 | }
|
54 | 54 |
|
55 | 55 | // camera utils
|
| 56 | + const radianConstant = Math.PI / 180; |
| 57 | + const epsilon = 1e-12; |
| 58 | + const applyEpsilon = (value) => (Math.abs(value) < epsilon ? 0 : value); |
| 59 | + |
56 | 60 | function setupState(drawable) {
|
57 | 61 | drawable[cameraSymbol] = {
|
58 | 62 | name: "default",
|
|
65 | 69 |
|
66 | 70 | function translatePosition(xy, invert, camData) {
|
67 | 71 | if (invert) {
|
68 |
| - const invRads = (camData.ogDir / 180) * Math.PI; |
| 72 | + const invRads = camData.ogDir * radianConstant; |
69 | 73 | const invSin = Math.sin(invRads),
|
70 | 74 | invCos = Math.cos(invRads);
|
71 | 75 | const scaledX = xy[0] / camData.ogSZ;
|
72 | 76 | const scaledY = xy[1] / camData.ogSZ;
|
73 | 77 | const invOffX = scaledX * invCos + scaledY * invSin;
|
74 | 78 | const invOffY = -scaledX * invSin + scaledY * invCos;
|
75 |
| - return [invOffX - camData.ogXY[0], invOffY - camData.ogXY[1]]; |
| 79 | + return [ |
| 80 | + applyEpsilon(invOffX - camData.ogXY[0]), |
| 81 | + applyEpsilon(invOffY - camData.ogXY[1]), |
| 82 | + ]; |
76 | 83 | } else {
|
77 |
| - const rads = (camData.dir / 180) * Math.PI; |
| 84 | + const rads = camData.dir * radianConstant; |
78 | 85 | const sin = Math.sin(rads),
|
79 | 86 | cos = Math.cos(rads);
|
80 | 87 | const offX = xy[0] + camData.xy[0];
|
81 | 88 | const offY = xy[1] + camData.xy[1];
|
82 | 89 | return [
|
83 |
| - camData.zoom * (offX * cos - offY * sin), |
84 |
| - camData.zoom * (offX * sin + offY * cos), |
| 90 | + applyEpsilon(camData.zoom * (offX * cos - offY * sin)), |
| 91 | + applyEpsilon(camData.zoom * (offX * sin + offY * cos)), |
85 | 92 | ];
|
86 | 93 | }
|
87 | 94 | }
|
|
252 | 259 | this.skin?.emitWasAltered();
|
253 | 260 | };
|
254 | 261 |
|
| 262 | + // Clones should inherit the parents camera |
| 263 | + const ogInitDrawable = vm.exports.RenderedTarget.prototype.initDrawable; |
| 264 | + vm.exports.RenderedTarget.prototype.initDrawable = function (layerGroup) { |
| 265 | + ogInitDrawable.call(this, layerGroup); |
| 266 | + if (this.isOriginal) return; |
| 267 | + |
| 268 | + const parentSprite = this.sprite.clones[0]; // clone[0] is always the original |
| 269 | + const parentDrawable = render._allDrawables[parentSprite.drawableID]; |
| 270 | + const name = parentDrawable[cameraSymbol]?.name ?? "default"; |
| 271 | + |
| 272 | + const drawable = render._allDrawables[this.drawableID]; |
| 273 | + bindDrawable(drawable, name); |
| 274 | + }; |
| 275 | + |
255 | 276 | // Turbowarp Extension Storage
|
256 | 277 | runtime.on("PROJECT_LOADED", () => {
|
257 | 278 | const stored = runtime.extensionStorage["SPcamera"];
|
|
700 | 721 | }
|
701 | 722 |
|
702 | 723 | translateAngledMovement(xy, steps, direction) {
|
703 |
| - const radians = direction * (Math.PI / 180); |
| 724 | + const radians = direction * radianConstant; |
704 | 725 | return [
|
705 |
| - xy[0] + steps * Math.cos(radians), |
706 |
| - xy[1] + steps * Math.sin(radians), |
| 726 | + applyEpsilon(xy[0] + steps * Math.cos(radians)), |
| 727 | + applyEpsilon(xy[1] + steps * Math.sin(radians)), |
707 | 728 | ];
|
708 | 729 | }
|
709 | 730 |
|
|
0 commit comments