Collision outlines for autotiles: a frame holds several outlines (click adds a corner to the active one, Ctrl/Cmd-click starts a new one, clicking another outline makes it active, Delete removes the active outline and never the frame in collision mode), an autotile's outlines are drawn over the whole block, cut at the quarters and each cell takes the pieces of exactly the quarters its image is made of, so edges, outer corners and notches follow automatically; a tile of the block with nothing drawn blocks fully, cells of only full quarters merge back into rectangles, collision scale does not apply to an outlined autotile, and the previous format with one flat outline still loads (#141)
game-maker / gate (push) Successful in 1m53s
game-maker / suite (push) Successful in 6m41s

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5 committed 2026-09-19 01:56:20 +02:00
1 parent 32057a96fc
commit 947a6b1977
11 files changed
+545 -139

No files matched your search

+13 -2
View File
@@ -39,6 +39,7 @@ import {
type PropertyValue,
type StructValue,
tagOf,
type Vec2,
} from '../model/Properties';
import { PROJECT_FORMAT_VERSION, type Project } from '../model/Project';
import { readScope } from '../model/Scope';
@@ -482,13 +483,23 @@ function normalizeTexture(
fill: f.fill === 'stretch' ? 'stretch' : DEFAULT_FILL,
});
// Corners that are no numbers fall away; what is left is kept only as an outline (#141).
const collision = pointsOf(f.collision as PropertyValue);
if (collision.length >= 3) setFrameCollision(frame, collision);
const outlines = collisionOutlines(f.collision).filter((outline) => outline.length >= 3);
if (outlines.length > 0) setFrameCollision(frame, outlines);
frames.push(frame);
}
return { file, width, height, frames };
}
/**
* A frame's stored outlines: a list of corner lists, or – as saved before a frame held several –
* one corner list, which is one outline.
*/
function collisionOutlines(raw: unknown): Vec2[][] {
if (!Array.isArray(raw)) return [];
if (raw.some((item) => !Array.isArray(item))) return [pointsOf(raw as PropertyValue)];
return raw.map((outline) => pointsOf(outline as PropertyValue));
}
/**
* The rows of an animation. Keys hold flat values only – a row animates one property – and are
* sorted onto whole frames; a second row on the same target and property, or with an id already