castle-web-cli 0.4.86 → 0.4.87
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/dist/shell/assets/{index-BJLaUTJE.js → index-BFCG4tLs.js} +3 -3
- package/dist/shell/assets/{index-DonnH--m.css → index-DSIr52Kl.css} +1 -1
- package/dist/shell/index.html +2 -2
- package/kits/basic-2d/editors/PxArtEditor.jsx +155 -17
- package/kits/basic-2d/editors/SceneEditor.jsx +93 -42
- package/kits/basic-2d/editors/useArtboardFit.js +4 -1
- package/kits/basic-2d/engine/ScenePlayer.jsx +14 -1
- package/kits/basic-2d/engine/ui.jsx +7 -0
- package/kits/physics-2d/editors/PxArtEditor.jsx +155 -17
- package/kits/physics-2d/editors/SceneEditor.jsx +93 -42
- package/kits/physics-2d/editors/useArtboardFit.js +4 -1
- package/kits/physics-2d/engine/ScenePlayer.jsx +14 -1
- package/kits/physics-2d/engine/ui.jsx +7 -0
- package/kits/physics-2d/physics/behaviors/AnalogStick.jsx +4 -2
- package/kits/physics-2d/physics/behaviors/Slingshot.jsx +8 -2
- package/kits/physics-2d/physics/controls.js +14 -0
- package/package.json +1 -1
|
@@ -93,7 +93,20 @@ export function ScenePlayer({ sceneData, sprites, files, behaviorClasses, onFirs
|
|
|
93
93
|
<canvas
|
|
94
94
|
ref={canvasRef}
|
|
95
95
|
tabIndex={0}
|
|
96
|
-
style={{
|
|
96
|
+
style={{
|
|
97
|
+
width: '100%',
|
|
98
|
+
height: '100%',
|
|
99
|
+
display: 'block',
|
|
100
|
+
outline: 'none',
|
|
101
|
+
// Claim touches for the game: without this, a mobile WebView
|
|
102
|
+
// (castle-client) treats a drag as a scroll/pan gesture and fires
|
|
103
|
+
// `pointercancel` mid-drag, so a held Draggable/Slingshot loses its
|
|
104
|
+
// grip. Also suppress long-press text selection / callout.
|
|
105
|
+
touchAction: 'none',
|
|
106
|
+
userSelect: 'none',
|
|
107
|
+
WebkitUserSelect: 'none',
|
|
108
|
+
WebkitTouchCallout: 'none',
|
|
109
|
+
}}
|
|
97
110
|
/>
|
|
98
111
|
<SceneUI getRuntime={getRuntime} />
|
|
99
112
|
{error ? <PlayErrorOverlay error={error} onRestart={onRestart} /> : null}
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
faCode,
|
|
14
14
|
faCodeBranch,
|
|
15
15
|
faEraser,
|
|
16
|
+
faExpand,
|
|
16
17
|
faExternalLinkAlt,
|
|
17
18
|
faEyeDropper,
|
|
18
19
|
faFile,
|
|
@@ -27,6 +28,8 @@ import {
|
|
|
27
28
|
faPlay,
|
|
28
29
|
faPlus,
|
|
29
30
|
faRedo,
|
|
31
|
+
faSearchMinus,
|
|
32
|
+
faSearchPlus,
|
|
30
33
|
faShapes,
|
|
31
34
|
faSlash,
|
|
32
35
|
faVectorSquare,
|
|
@@ -180,6 +183,7 @@ const icons = {
|
|
|
180
183
|
// FA5 has no faCodeFork (that's the FA6 name); faCodeBranch is the fork glyph.
|
|
181
184
|
'code-fork': faCodeBranch,
|
|
182
185
|
eraser: faEraser,
|
|
186
|
+
expand: faExpand,
|
|
183
187
|
external: faExternalLinkAlt,
|
|
184
188
|
eyedropper: faEyeDropper,
|
|
185
189
|
fill: faFillDrip,
|
|
@@ -199,6 +203,9 @@ const icons = {
|
|
|
199
203
|
plus: faPlus,
|
|
200
204
|
redo: faRedo,
|
|
201
205
|
rotate: faSyncAlt,
|
|
206
|
+
'zoom-in': faSearchPlus,
|
|
207
|
+
'zoom-out': faSearchMinus,
|
|
208
|
+
fit: faExpand,
|
|
202
209
|
shapes: faShapes,
|
|
203
210
|
slash: faSlash,
|
|
204
211
|
square: faSquare,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Panel, SelectField } from '../../engine/ui';
|
|
3
3
|
import { AutoFields, overrideProps } from '../../engine/autoInspector';
|
|
4
|
-
import { analogVelocity, inActorWorldSpace, stickVector } from '../controls';
|
|
4
|
+
import { analogVelocity, inActorWorldSpace, pressOnDraggable, stickVector } from '../controls';
|
|
5
5
|
|
|
6
6
|
// AnalogStick: an on-screen virtual joystick that drives the actor it's on --
|
|
7
7
|
// the look and feel of castle-client's Analog Stick. Press anywhere to place
|
|
@@ -29,7 +29,9 @@ export class AnalogStick {
|
|
|
29
29
|
const rt = actor.runtime;
|
|
30
30
|
const pressed = p.down && !rt._stickWasDown;
|
|
31
31
|
rt._stickWasDown = p.down;
|
|
32
|
-
|
|
32
|
+
// A press on a draggable is consumed by the drag; every other press drives
|
|
33
|
+
// the stick.
|
|
34
|
+
if (pressed && !pressOnDraggable(scene)) rt._stickOrigin = { x: p.x, y: p.y };
|
|
33
35
|
|
|
34
36
|
// Only drive velocity while the stick is actually held.
|
|
35
37
|
if (p.down && rt._stickOrigin) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Panel } from '../../engine/ui';
|
|
3
3
|
import { AutoFields } from '../../engine/autoInspector';
|
|
4
|
-
import { inActorWorldSpace, slingLaunch, slingPull } from '../controls';
|
|
4
|
+
import { inActorWorldSpace, pressOnDraggable, slingLaunch, slingPull } from '../controls';
|
|
5
5
|
|
|
6
6
|
// Slingshot: pull back and release to fling the actor the opposite way
|
|
7
7
|
// (angry-birds style) -- the physics feel of castle-client's Sling. While
|
|
@@ -31,8 +31,14 @@ export class Slingshot {
|
|
|
31
31
|
const pressed = p.down && !rt._slingWasDown;
|
|
32
32
|
rt._slingWasDown = p.down;
|
|
33
33
|
|
|
34
|
+
// A press on a draggable is consumed by the drag; otherwise the sling grabs
|
|
35
|
+
// (anywhere, or on its own actor when grabAnywhere is off).
|
|
34
36
|
const grabAnywhere = this.props.grabAnywhere ?? true;
|
|
35
|
-
if (
|
|
37
|
+
if (
|
|
38
|
+
pressed &&
|
|
39
|
+
!pressOnDraggable(scene) &&
|
|
40
|
+
(grabAnywhere || scene.actorAt(p.x, p.y)?.id === actor.id)
|
|
41
|
+
) {
|
|
36
42
|
rt._slinging = true;
|
|
37
43
|
// Anchor at the press point (like castle-client): the aim/launch depends
|
|
38
44
|
// on the drag gesture, not where the press landed relative to the actor.
|
|
@@ -29,6 +29,20 @@ export function chaseVelocity(target, layout, props = {}) {
|
|
|
29
29
|
return { x: (target.x - c.x) * stiffness, y: (target.y - c.y) * stiffness };
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
// --- Touch ownership -------------------------------------------------------
|
|
33
|
+
// Hierarchy: a press that lands ON a Draggable object is CONSUMED by that drag,
|
|
34
|
+
// so Slingshot/AnalogStick ignore it. A press anywhere else is shared -- both
|
|
35
|
+
// Slingshot and AnalogStick act (no fair way to rank them). So the only gate the
|
|
36
|
+
// non-drag controls need is this: did the current press land on a draggable?
|
|
37
|
+
// Stateless -- a pure per-press query (the controls only ask on their press
|
|
38
|
+
// edge), so there's no owner to latch and nothing to reset.
|
|
39
|
+
export function pressOnDraggable(scene) {
|
|
40
|
+
const p = scene.pointer;
|
|
41
|
+
if (!p.down) return false;
|
|
42
|
+
const hit = scene.actorAt(p.x, p.y);
|
|
43
|
+
return !!hit && !!hit.components.Draggable;
|
|
44
|
+
}
|
|
45
|
+
|
|
32
46
|
// Run `draw(ctx)` in world space, undoing the actor's Layout rotation that the
|
|
33
47
|
// runtime applies about the actor's center. Overlay controls (Slingshot,
|
|
34
48
|
// AnalogStick) use this so their on-screen UI stays anchored where the user
|