Clip the children of an object to a clip area (#260)
game-maker / gate (push) Successful in 3m43s
game-maker / suite (push) Failing after 11m7s

An inventory grid could not scroll, because nothing could cut a child
off at an edge. A game also had no way to hear the mouse wheel. Both
are needed for a scrolling list, a dialog text or a window with more
content than room.

- A new object type Clip area has width and height and turns, scales
  and mirrors with its parent. The size gizmo drags width and height.
- Everything below a clip area, on every level, is drawn only inside
  its rectangle, in the Scene view as in the game. Nested areas cut to
  their intersection. The rule works on a convex polygon, so a turned
  area cuts right as well.
- On click, Is hovered and On mouse wheel do not hit a cut-off part.
  The Scene view does not pick it either.
- In the Scene view the area is a dashed frame that is grabbed only at
  its edge, so a click inside lands on the content. The eye under
  Shape hides the frame. In the game the area is invisible.
- While an object below an area or one of its parents is selected, the
  Scene view shows the cut-off part at 30 % opacity and it can be
  grabbed there. The rule lives in core/properties/clip.ts.
- The Properties node knows the type Clip area.
- The new event node On mouse wheel fires by the rule of On click. Its
  delta counts in notches, positive is down, and a frame's turns
  arrive as one value. It also gives x and y.

Limits:

- Only sprites and texts show the faded rest. Tilemaps and particles
  are cut and can be grabbed when open, but are not shown faded.
- Masks by texture shape are out, as noted in the issue.

Tests:

- ./check.sh: 2773 tests, CHECK EXIT 0.
- Full e2e run (local): ALL PASSED, 1549 checks, measured.
- tests/core/clip-areas.test.ts: 12 tests for the cut rule, scene and
  game, save and load, hits, the wheel with and without owner, the
  notch conversion and the open rule.
- e2e 58, 5 checks with real mouse and wheel: the scene cuts (74 of 74
  red inside, 0 outside), a click on the cut part picks nothing, the
  selected rest is faded and grabbable, the game cuts, one notch
  logs 1.
- e2e 04 and 46 count the object types and the eye rows. They now
  include Clip area.
- Counter-checks: 6 in unit tests and 3 in the browser, all fail as
  expected. The originals were restored and checked with cmp.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5.5 committed 2026-09-29 07:08:00 +02:00
1 parent 89aa92d2e3
commit 0c41cb97b1
32 files changed
+759 -27

No files matched your search

+2
View File
@@ -70,6 +70,8 @@ export interface PointerState {
down: boolean;
pressed: boolean;
released: boolean;
/** How far the wheel turned this tick, in notches, positive downwards (see `wheelNotches`). */
wheel: number;
}
/**
@@ -0,0 +1,15 @@
import type { NodeDef } from '../../NodeRegistry';
import { exec, num } from '../shared';
export const OnMouseWheel: NodeDef = {
type: 'OnMouseWheel',
label: 'On mouse wheel',
category: 'event',
description:
'Runs when the mouse wheel turns over the owner (or over anything parented below it) in the Game tab. ' +
'Without an owner it runs on a turn anywhere in the game view. delta is in notches of a mouse wheel, ' +
'positive downwards; a trackpad gives fractions.',
inputs: [],
outputs: [exec(), num('delta', 'notches, positive downwards'), num('x', 'world x'), num('y', 'world y')],
params: [],
};
+2
View File
@@ -102,6 +102,7 @@ import { SubList } from './data/SubList';
import { TextureSize } from './data/TextureSize';
import { OnAnimationFinished } from './events/OnAnimationFinished';
import { OnClick } from './events/OnClick';
import { OnMouseWheel } from './events/OnMouseWheel';
import { OnCollisionEnter } from './events/OnCollisionEnter';
import { OnCollisionExit } from './events/OnCollisionExit';
import { OnCollisionStay } from './events/OnCollisionStay';
@@ -152,6 +153,7 @@ export const BUILT_IN_NODES: readonly NodeDef[] = [
OnCollisionStay,
OnCollisionExit,
OnClick,
OnMouseWheel,
OnAnimationFinished,
OnStateEntered,
OnStateExited,
+1
View File
@@ -22,6 +22,7 @@ export const PROPERTY_TARGETS = [
'rigidbody',
'camera',
'container',
'clip',
'behavior',
] as const;
export type PropertyTarget = (typeof PROPERTY_TARGETS)[number];