Tilemaps: trigger tiles, tile and cell on the collision events (#160)

admin committed 2026-10-02 07:28:48 +02:00
1 parent c8a2b3dc73
commit 875594a733
4 files changed
+54 -6

No files matched your search

+1 -1
@@ -193,7 +193,7 @@ playing use the same two words.
set to `a` also hears `A`, and a key picked with Shift held is stored lower-case. A key is let go set to `a` also hears `A`, and a key picked with Shift held is stored lower-case. A key is let go
under the name it went down as, even when Shift changes in between (`1` down, `!` up). under the name it went down as, even when Shift changes in between (`1` down, `!` up).
- **Node set** (`src/core/graph/nodes/`, one file per node): events `On start`, `On enable`, `On update`, `On disable`, `On destroy` (see *Lifecycle*), `On key down/up/held`, - **Node set** (`src/core/graph/nodes/`, one file per node): events `On start`, `On enable`, `On update`, `On disable`, `On destroy` (see *Lifecycle*), `On key down/up/held`,
`On timer` (fires on the first frame past each due time; `late` says by how much, so `time - late` is exactly a multiple of the interval), `On collision enter/stay/exit` (stay every frame, or with an interval; while playing enter and stay tell normal, impulse and point of the contact), `On click` (the mouse pressed on the owner — anywhere when it has none), `On mouse wheel` (the wheel turned over the owner, or anywhere without one; `delta` in notches, positive downwards, a trackpad gives fractions), `On animation finished`, `On state entered`, `On state exited` (one output per state, see *State machines*), `Start` · flow `Branch`, `Sequence`, `Repeat`, `For each`, `Find` … `Match`, `Run behavior`, `End`, and the four that move or follow a state machine, `State branch`, `Set state`, `Set state by name`, `State transition` (see *State machines*) · data `Self`, `Owner`, `Parent`, `Object by name`, `Child by name` (the nearest object of that name below the given one: its children, then their children, and so on; within a level the first in hierarchy order, nothing when none is called so), `Name of`, `On timer` (fires on the first frame past each due time; `late` says by how much, so `time - late` is exactly a multiple of the interval), `On collision enter/stay/exit` (stay every frame, or with an interval; while playing enter and stay tell normal, impulse and point of the contact; on a trigger tile of a tilemap all three tell `tile` and `cell x/y`, once per area or with the input `per cell` once per cell, see [Tilemaps](Tilemaps#trigger-tiles)), `On click` (the mouse pressed on the owner — anywhere when it has none), `On mouse wheel` (the wheel turned over the owner, or anywhere without one; `delta` in notches, positive downwards, a trackpad gives fractions), `On animation finished`, `On state entered`, `On state exited` (one output per state, see *State machines*), `Start` · flow `Branch`, `Sequence`, `Repeat`, `For each`, `Find` … `Match`, `Run behavior`, `End`, and the four that move or follow a state machine, `State branch`, `Set state`, `Set state by name`, `State transition` (see *State machines*) · data `Self`, `Owner`, `Parent`, `Object by name`, `Child by name` (the nearest object of that name below the given one: its children, then their children, and so on; within a level the first in hierarchy order, nothing when none is called so), `Name of`,
`Is asset` (is this object an instance of asset X — how you tell what you collided with), `Is asset` (is this object an instance of asset X — how you tell what you collided with),
and the plural lookups, each handing on a `list` of objects taken at that moment (destroyed and the plural lookups, each handing on a `list` of objects taken at that moment (destroyed
objects are never in it, switched-off ones are, as with the single lookups): `Objects by name` objects are never in it, switched-off ones are, as with the single lookups): `Objects by name`
+3 -1
@@ -77,7 +77,9 @@ and `collider` (the own one); while playing, `On collision enter` and `On collis
tell the direction, the strength and the point of the contact (see [Physics](Physics)). tell the direction, the strength and the point of the contact (see [Physics](Physics)).
`On collision stay` fires every frame by default; with an **Interval (s)** above 0 it fires once each `On collision stay` fires every frame by default; with an **Interval (s)** above 0 it fires once each
time that long has passed since the pair met, on a clock of its own per pair that starts over when time that long has passed since the pair met, on a clock of its own per pair that starts over when
they meet again (#149). `Is touching(a, b)` answers the same question on demand — an they meet again (#149). On a trigger tile of a tilemap the three events also tell the `tile` and
its `cell x` and `cell y`, once per area of the tile or, with the input **per cell**, once per cell
(see [Tilemaps](Tilemaps#trigger-tiles)). `Is touching(a, b)` answers the same question on demand — an
object stands for its collider children, a collider for itself. The geometry lives in object stands for its collider children, a collider for itself. The geometry lives in
`src/core/properties/collider.ts` so editor and runtime agree on it. `src/core/properties/collider.ts` so editor and runtime agree on it.
+1 -1
@@ -18,7 +18,7 @@ php tests/php/accounts.test.php # the API's accoun
# has and the web server's container has not (SKIP there) # has and the web server's container has not (SKIP there)
php tests/php/snapshots.test.php # the snapshot store (#231), the same way php tests/php/snapshots.test.php # the snapshot store (#231), the same way
php tests/php/releases.test.php # the release store (#266), the same way php tests/php/releases.test.php # the release store (#266), the same way
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1645 editor checks, screenshots in /tmp/gm-e2e-*.png node tools/seed-e2e.mjs && node tools/e2e.mjs # 1648 editor checks, screenshots in /tmp/gm-e2e-*.png
GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step
./e2e.sh start [GM_STEPS] # the same run detached, see below ./e2e.sh start [GM_STEPS] # the same run detached, see below
./e2e.sh status # live progress, or the last run's result ./e2e.sh status # live progress, or the last run's result
+49 -3
@@ -300,7 +300,7 @@ In the running game the placed map is a **body of its own** in the collision sys
other. other.
- Cells painted while the game runs count from the next frame on. - Cells painted while the game runs count from the next frame on.
There are no trigger tiles yet: a tile blocks or it does not. A tile that should report instead of block is a trigger tile, see [Trigger tiles](#trigger-tiles).
### The cost of outlined cells ### The cost of outlined cells
@@ -359,6 +359,50 @@ A frame still costs what it touches: an object standing **inside** many outlined
against each of them, so an outline of a hundred corners around every cell of a lake is dearer than against each of them, so an outline of a hundred corners around every cell of a lake is dearer than
a few around its shore. Draw as few corners as the shape needs. a few around its shore. Draw as few corners as the shape needs.
### Trigger tiles
A tile with **Trigger (reports, never blocks)** on (#160) is water, lava, spikes or a goal: its
cells stop nothing — not a `Move`, not a falling body, not a ray — and tell the collision events
what lies on them. Trigger wins over Solid, as it does on a collider. In the scene view the cells
are outlined in the trigger collider's yellow, merged into rectangles like the solid ones but never
with them.
`On collision enter`, `On collision stay` and `On collision exit` fire for a collider that lies on
such a cell, with the tilemap as `other`, and three outputs say where:
| Output | What it holds |
|---|---|
| `tile` | the tile asset, to compare with a `Tile` literal: water or lava |
| `cell x`, `cell y` | the cell in the map, as `Tile at` and `Set tile` count it |
For another collider, and for the solid cells of a map, `tile` is empty and the cell is -1, -1.
How often the events come is up to the node's input **per cell**:
- **Off (the default): once per area.** An area is the stretch of cells of the same tile that touch
side to side. Walking through a pond is one enter and one exit, however many cells it crosses.
The cell told is the one of the area nearest to the collider's middle; on exit, the last one.
Water next to lava is two areas, and so are two ponds that only meet at a corner.
- **On: once per cell.** Every cell the collider comes to lie on enters, stays and exits on its
own. A stay with an interval keeps a clock per cell.
The input is a port like any other: unconnected it is a checkbox on the node, connected it is read
each time an event comes.
What else holds:
- The tile's **Collision scale** and the **outlines** of its picture shape a trigger cell exactly as
they shape a solid one. One-way, Friction and Bounciness mean nothing on a trigger.
- The map's **Layer** and **Collides with** decide which colliders are told at all, and a collider
that is itself a trigger is told as well.
- A cell holding two trigger tiles on two layers reports both.
- `Is touching` with the map as one side is true on a trigger tile too.
- `Set tile` changes them while the game runs: a trigger tile put under a collider enters in the
next frame.
- The editor run and the played game tell the same. Both test the overlap where the objects are
drawn (`src/runtime/systems/tileTriggers.ts`); the physics engine never sees a trigger tile.
- A ray does not meet a trigger tile, with *Hit triggers* on either.
### One-way tiles ### One-way tiles
A solid tile with **One-way (from above)** on (#155) blocks only what comes down on it from above, A solid tile with **One-way (from above)** on (#155) blocks only what comes down on it from above,
@@ -389,5 +433,7 @@ The map of the first version (#128) is not read any more (#137): such a layer lo
## What it does not do yet ## What it does not do yet
- No trigger tiles: a tile that only reports an overlap (water that fires an event) is not there - A trigger tile tells no contact: `normal`, `impulse` and `point` are 0 on its events, as for a
yet — a tile blocks or it does not. trigger collider.
- The solid cells of a map do not say which tile was hit: `tile` and the cell are only told for
trigger tiles.