diff --git a/scripts/lib/StarterThemer.js b/scripts/lib/StarterThemer.js index 20f93d5dd..50293389f 100644 --- a/scripts/lib/StarterThemer.js +++ b/scripts/lib/StarterThemer.js @@ -836,17 +836,27 @@ const applyThemeToStarter = ( instance.y - (placeholderFrame.originPoint.y * instance.height) / placeholderImage.height; - const width = firstThemed.slot.width * scale; - const height = firstThemed.slot.height * scale; + // Art wider than the instance is drawn at half the scale, so + // that it does not cover what is next to the instance. + const isHalved = + scale % 2 === 0 && + firstThemed.slot.width * scale > instance.width; + const instanceScale = isHalved ? scale / 2 : scale; + const width = firstThemed.slot.width * instanceScale; + const height = firstThemed.slot.height * instanceScale; instance.x = - left + (instance.width - width) / 2 + themedOrigin.x * scale; + left + + (instance.width - width) / 2 + + themedOrigin.x * instanceScale; instance.y = top + (anchor === 'bottom' ? instance.height - height : (instance.height - height) / 2) + - themedOrigin.y * scale; - instance.customSize = false; + themedOrigin.y * instanceScale; + instance.customSize = isHalved; + instance.width = width; + instance.height = height; } ); if (usedSlotIds.length === 1 && firstThemed.slot.assetStoreId) { diff --git a/scripts/lib/__tests__/StarterThemer.spec.js b/scripts/lib/__tests__/StarterThemer.spec.js index b0189aa0d..247cc826e 100644 --- a/scripts/lib/__tests__/StarterThemer.spec.js +++ b/scripts/lib/__tests__/StarterThemer.spec.js @@ -985,6 +985,8 @@ describe('applyThemeToStarter on a 2D starter', () => { const slot = theme.slots['2d.side.player']; // 16 pixels tiles, for a starter built on 64 pixels tiles. slot.tileSize = 16; + slot.width = 32; + slot.height = 32; const project = makeProject(); applyThemeToStarter(project, makeThemeSlots(), theme, options); /** @type {any} */ @@ -1007,6 +1009,42 @@ describe('applyThemeToStarter on a 2D starter', () => { expect(pixelPlayer.preScale).toBe(2); }); + it('halves the scale of grid art wider than an instance with a custom size', () => { + const theme = makeTheme(); + /** @type {any} */ + const slot = theme.slots['2d.side.player']; + slot.tileSize = 16; + slot.width = 32; + slot.height = 48; + slot.objectContent.animations.forEach((/** @type {any} */ animation) => { + animation.directions[0].sprites[0].customCollisionMask = [ + [ + { x: 0, y: 0 }, + { x: 32, y: 0 }, + { x: 32, y: 48 }, + { x: 0, y: 48 }, + ], + ]; + }); + const project = makeProject(); + Object.assign(project.layouts[0].instances[1], { + x: 100, + y: 200, + width: 64, + height: 128, + }); + applyThemeToStarter(project, makeThemeSlots(), theme, options); + // 128x192 at the scale of the grid: 64x96, standing on the same bottom. + // The origin is at (8, 32) in the art, so the art is drawn at (100, 232). + expect(project.layouts[0].instances[1]).toMatchObject({ + customSize: true, + x: 116, + y: 296, + width: 64, + height: 96, + }); + }); + it('plays an animation with the theme animation the starter asks for', () => { const project = makeProject(); /** @type {any} */