Skip to content

Commit

Permalink
Allow tilemaps with atlas dimensions not exactly a tile size multiple
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexandreSi committed Sep 16, 2024
1 parent 2cda1fa commit 1ff5813
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 42 deletions.
21 changes: 18 additions & 3 deletions Extensions/TileMap/JsExtension.js
Original file line number Diff line number Diff line change
Expand Up @@ -630,23 +630,38 @@ const defineSimpleTileMap = function (extension, _, gd) {

objectProperties.set(
'columnCount',
new gd.PropertyDescriptor((objectContent.columnCount || 4).toString())
new gd.PropertyDescriptor(
(typeof objectContent.columnCount === 'undefined'
? 4
: objectContent.columnCount
).toString()
)
.setType('number')
.setLabel(_('Columns'))
.setDescription(_('Number of columns.'))
.setHidden(true)
);
objectProperties.set(
'rowCount',
new gd.PropertyDescriptor((objectContent.rowCount || 4).toString())
new gd.PropertyDescriptor(
(typeof objectContent.rowCount === 'undefined'
? 4
: objectContent.rowCount
).toString()
)
.setType('number')
.setLabel(_('Rows'))
.setDescription(_('Number of rows.'))
.setHidden(true)
);
objectProperties.set(
'tileSize',
new gd.PropertyDescriptor((objectContent.tileSize || 8).toString())
new gd.PropertyDescriptor(
(typeof objectContent.tileSize === 'undefined'
? 8
: objectContent.tileSize
).toString()
)
.setType('number')
.setLabel(_('Tile size'))
.setDescription(_('Tile size in pixels.'))
Expand Down
74 changes: 47 additions & 27 deletions newIDE/app/src/InstancesEditor/TileSetVisualizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import useForceUpdate from '../Utils/UseForceUpdate';
import { useLongTouch, type ClientCoordinates } from '../Utils/UseLongTouch';
import Text from '../UI/Text';
import EmptyMessage from '../UI/EmptyMessage';
import { isTileSetBadlyConfigured } from './TileMapPaintingPreview';

const styles = {
tilesetAndTooltipsContainer: {
Expand Down Expand Up @@ -251,18 +252,22 @@ const TileSetVisualizer = ({
x: number,
y: number,
|}>(null);
const objectConfigurationProperties = objectConfiguration.getProperties();
const columnCount = parseFloat(
objectConfiguration
.getProperties()
.get('columnCount')
.getValue()
objectConfigurationProperties.get('columnCount').getValue()
);
const rowCount = parseFloat(
objectConfiguration
.getProperties()
.get('rowCount')
.getValue()
objectConfigurationProperties.get('rowCount').getValue()
);
const tileSize = parseFloat(
objectConfigurationProperties.get('tileSize').getValue()
);
const isBadlyConfigured = isTileSetBadlyConfigured({
atlasImage: '',
columnCount,
rowCount,
tileSize,
});
const [clickStartCoordinates, setClickStartCoordinates] = React.useState<?{|
x: number,
y: number,
Expand Down Expand Up @@ -294,12 +299,23 @@ const TileSetVisualizer = ({
const imageWidth = imageElement
? parseFloat(getComputedStyle(imageElement).width.replace('px', ''))
: 0;
const displayedTileSize = imageWidth ? imageWidth / columnCount : null;
const imageNaturalWidth = imageElement ? imageElement.naturalWidth : 1;
const displayedTileSize =
imageWidth && imageNaturalWidth
? (imageWidth / imageNaturalWidth) * tileSize
: null;

const _onAtlasImageLoaded = React.useCallback(
e => {
if (onAtlasImageLoaded) onAtlasImageLoaded(e, atlasResourceName);
},
[onAtlasImageLoaded, atlasResourceName]
);

const displayTileIdTooltip = React.useCallback(
(e: ClientCoordinates) => {
setShouldCancelClick(true);
if (!displayedTileSize) return;
if (!displayedTileSize || isBadlyConfigured) return;

const imageCoordinates = getImageCoordinatesFromPointerEvent(e);
if (!imageCoordinates) return;
Expand All @@ -320,7 +336,7 @@ const TileSetVisualizer = ({
label: getTileIdFromGridCoordinates({ x, y, columnCount }).toString(),
});
},
[displayedTileSize, columnCount, rowCount]
[displayedTileSize, columnCount, rowCount, isBadlyConfigured]
);

const longTouchProps = useLongTouch(displayTileIdTooltip);
Expand All @@ -334,21 +350,26 @@ const TileSetVisualizer = ({
[forceUpdate]
);

const onPointerDown = React.useCallback((event: PointerEvent) => {
if (event.pointerType === 'touch') {
setTouchStartCoordinates({ x: event.pageX, y: event.pageY });
}
const imageCoordinates = getImageCoordinatesFromPointerEvent(event);
if (!imageCoordinates) return;
setClickStartCoordinates({
x: imageCoordinates.mouseX,
y: imageCoordinates.mouseY,
});
}, []);
const onPointerDown = React.useCallback(
(event: PointerEvent) => {
if (isBadlyConfigured) return;
if (event.pointerType === 'touch') {
setTouchStartCoordinates({ x: event.pageX, y: event.pageY });
}
const imageCoordinates = getImageCoordinatesFromPointerEvent(event);
if (!imageCoordinates) return;
setClickStartCoordinates({
x: imageCoordinates.mouseX,
y: imageCoordinates.mouseY,
});
},
[isBadlyConfigured]
);

const onPointerMove = React.useCallback(
(event: PointerEvent) => {
if (
isBadlyConfigured ||
!clickStartCoordinates ||
!displayedTileSize ||
!allowMultipleSelection ||
Expand Down Expand Up @@ -386,6 +407,7 @@ const TileSetVisualizer = ({
});
},
[
isBadlyConfigured,
displayedTileSize,
columnCount,
rowCount,
Expand All @@ -397,7 +419,7 @@ const TileSetVisualizer = ({
const onPointerUp = React.useCallback(
(event: PointerEvent) => {
try {
if (!displayedTileSize) return;
if (!displayedTileSize || isBadlyConfigured) return;
if (shouldCancelClick) {
setShouldCancelClick(false);
return;
Expand Down Expand Up @@ -503,6 +525,7 @@ const TileSetVisualizer = ({
}
},
[
isBadlyConfigured,
displayedTileSize,
columnCount,
rowCount,
Expand Down Expand Up @@ -741,10 +764,7 @@ const TileSetVisualizer = ({
atlasResourceName,
{}
)}
onLoad={e => {
if (onAtlasImageLoaded)
onAtlasImageLoaded(e, atlasResourceName);
}}
onLoad={_onAtlasImageLoaded}
/>

{interactive && hoveredTile && displayedTileSize && (
Expand Down
18 changes: 6 additions & 12 deletions newIDE/app/src/ObjectEditor/Editors/SimpleTileMapEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,13 @@ const SimpleTileMapEditor = ({
|},
tileSize: number
) => {
const newRowCount = dimensions.height / tileSize;
const newColumnCount = dimensions.width / tileSize;
const newRowCount = Math.floor(dimensions.height / tileSize);
const newColumnCount = Math.floor(dimensions.width / tileSize);

if (rowCount === newRowCount && columnCount === newColumnCount) {
return;
}
setError(null);
objectConfiguration.updateProperty('rowCount', newRowCount.toString());
objectConfiguration.updateProperty(
'columnCount',
Expand All @@ -92,7 +93,6 @@ const SimpleTileMapEditor = ({
if (!value) {
return;
}
setError(null);
objectConfiguration.updateProperty('tileSize', value.toString());
if (loadedAtlasImageDimensions) {
recomputeTileSet(loadedAtlasImageDimensions, value);
Expand Down Expand Up @@ -140,17 +140,11 @@ const SimpleTileMapEditor = ({
React.useEffect(
() => {
if (!loadedAtlasImageDimensions) return;
const _rowCount = loadedAtlasImageDimensions.height / tileSize;
const _columnCount = loadedAtlasImageDimensions.width / tileSize;
if (!Number.isInteger(_rowCount) || !Number.isInteger(_columnCount)) {
setError(
<Trans>
The new atlas image size is not compatible with the tile size.
</Trans>
);
if (rowCount <= 0 || columnCount <= 0) {
setError(<Trans>The atlas image is smaller than the tile size.</Trans>);
}
},
[tileSize, loadedAtlasImageDimensions]
[rowCount, columnCount, loadedAtlasImageDimensions]
);

const onAtlasImageLoaded = React.useCallback(
Expand Down

0 comments on commit 1ff5813

Please sign in to comment.