tilemap-editor 4.3.4__tar.gz → 4.3.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tilemap_editor-4.3.4/src/tilemap_editor.egg-info → tilemap_editor-4.3.5}/PKG-INFO +13 -1
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/README.md +12 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/pyproject.toml +1 -1
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/node_manager.py +23 -7
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/character_collision/editor.py +25 -2
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/character_collision/shape_editor.py +39 -6
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/object_tileset_collision/editor.py +3 -2
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/tileset_collision/collision_painter.py +13 -6
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/tileset_collision/editor.py +19 -4
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5/src/tilemap_editor.egg-info}/PKG-INFO +13 -1
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/tile_grid.py +3 -1
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/region_selector.py +23 -12
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/LICENSE +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/MANIFEST.in +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/fonts/jetbrain-fonts/JetBrainsMono-Bold.ttf +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/fonts/jetbrain-fonts/JetBrainsMono-BoldItalic.ttf +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/fonts/jetbrain-fonts/JetBrainsMono-Italic.ttf +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/fonts/jetbrain-fonts/JetBrainsMono-Regular.ttf +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/fonts/noto/NotoSans-Bold.ttf +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/fonts/noto/NotoSans-BoldItalic.ttf +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/fonts/noto/NotoSans-Italic.ttf +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/fonts/noto/NotoSans-Regular.ttf +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/arrow-down.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/check.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/checked.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/close.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/duplicate.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/error.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/file.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/filedead.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/fit.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/folder.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/grid.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/image.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/info.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/load.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/loop.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/onion.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/pan.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/pause.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/pencil.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/play.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/plus.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/radio.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/reset.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/save.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/skip-back.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/skip-forward.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/stop.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/tilemap.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/tileset.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/unchecked.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/warning.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/zoomin.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/icons/zoomout.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/setup.cfg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/constants.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/editor.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/event_map.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/layers.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/main.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/nodes.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/__init__.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/character_collision/__init__.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/character_collision/models.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/character_collision/protocols.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/character_collision/standalone.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/object_tileset_collision/__init__.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/object_tileset_collision/models.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/object_tileset_collision/protocols.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/object_tileset_collision/standalone.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_animation/__init__.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_animation/__main__.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_animation/clipboard_util.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_animation/editor.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_animation/frame_picker.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_animation/models.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_animation/preview.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_animation/protocols.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_animation/runtime_load.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_animation/standalone.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_animation/timeline.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_animation/validation.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_editor/__init__.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_editor/dialogs.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_editor/editor.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_editor/region_export.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_editor/standalone.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/tileset_collision/__init__.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/tileset_collision/models.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/tileset_collision/protocols.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/tileset_collision/standalone.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/standalone_automap.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/standalone_error_console.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/standalone_filemanager.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/standalone_image_viewer.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/__init__.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/__main__.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/__init__.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Bold.ttf +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-BoldItalic.ttf +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Italic.ttf +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/fonts/jetbrain-fonts/JetBrainsMono-Regular.ttf +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/fonts/noto/NotoSans-Bold.ttf +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/fonts/noto/NotoSans-BoldItalic.ttf +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/fonts/noto/NotoSans-Italic.ttf +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/fonts/noto/NotoSans-Regular.ttf +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/ToolMove.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/arrow-down.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/check.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/checked.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/close.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/duplicate.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/error.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/file.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/filedead.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/fit.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/fold_down_arrow.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/folder.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/gear.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/grid.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/image.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/info.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/load.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/loop.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/miniobj.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/onion.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/pan.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/pause.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/pencil.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/play.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/plus.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/radio.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/reset.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/save.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/skip-back.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/skip-forward.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/stop.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/tilemap.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/tileset.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/unchecked.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/unfold_right_arrow.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/warning.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/zoomin.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/assets/icons/zoomout.svg +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/cli.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/main.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor/settings.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor.egg-info/SOURCES.txt +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor.egg-info/dependency_links.txt +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor.egg-info/entry_points.txt +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor.egg-info/requires.txt +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/tilemap_editor.egg-info/top_level.txt +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/ttypes/__init__.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/ttypes/tilemap.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/utils/__init__.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/utils/editor_preference.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/utils/error_handler.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/utils/font_manager.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/utils/history.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/utils/icon_manager.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/utils/icons_cache.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/utils/log_capture.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/utils/project_paths.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/utils/serialization.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/utils/standalone.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/utils/validation.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/__init__.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/automap_models.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/autotile_template.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/autotiler.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/filemanager.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/input.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/layer_selector.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/map_properties.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/mapsetup.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/particle_presets.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/particle_system.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/regex_automap_designer.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/spritesheet_grid.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/tile_selector.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/button.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/checkbox.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/collision_layer_mask.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/collision_layer_sidebar.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/confirm_dialog.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/dialog_base.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/drag_tracker.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/draw_utils.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/fileinput.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/label.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/layer_type_dialog.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/menubar.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/mode_indicator.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/node_editor.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/node_selector.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/notification.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/particle_config_dialog.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/property_editor.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/scrollbar.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/sidebar_container.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/splitter.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/status_bar.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/theme.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/tileset_type_dialog.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/toast.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/tool_manager.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/toolbar.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/tooltip.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/ui/tree_widget.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/widgets/widget_base.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/tests/test_animation_library_grid_offset.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/tests/test_collision_layer_mask.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/tests/test_collision_layer_sidebar.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/tests/test_drag_tracker.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/tests/test_editor_pan_mode.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/tests/test_gid_collision.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/tests/test_layers_autotile.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/tests/test_project_paths.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/tests/test_render_scale.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/tests/test_serialization_regression.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/tests/test_sprite_animation_editor_grid.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/tests/test_tile_grid_selection.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/tests/test_tile_selector_pick.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/tests/test_tilemap_save.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/tests/test_timeline_invalidate_cache.py +0 -0
- {tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/tests/test_toolbar_tools.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tilemap-editor
|
|
3
|
-
Version: 4.3.
|
|
3
|
+
Version: 4.3.5
|
|
4
4
|
Summary: Pygame tilemap editor with collision, animation, sprite & particle tools
|
|
5
5
|
Author: tilemap editor contributors
|
|
6
6
|
License: Proprietary
|
|
@@ -18,6 +18,15 @@ Dynamic: license-file
|
|
|
18
18
|
|
|
19
19
|
`tilemap-editor` is a pygame-based map editor focused on fast iteration for 2D games.
|
|
20
20
|
|
|
21
|
+
# tilemap-editor
|
|
22
|
+
|
|
23
|
+
`tilemap-editor` is a Pygame-based map editor focused on fast iteration for 2D games.
|
|
24
|
+
|
|
25
|
+
> **Credits:** The initial version of this project was based on DaFluffyPotato's platformer tutorial which is about 6-hours. If you want to understand the foundation this project started from, I highly recommend watching his video: https://www.youtube.com/watch?v=2gABYM5M0ww. While the editor has since evolved with many additional features and improvements, the original map format has been preserved for compatibility.
|
|
26
|
+
|
|
27
|
+
Several features and design ideas were also inspired by the Godot Engine, including the animation workflow, polygon collision editing, and character collision (Sprite2D-style) editing.
|
|
28
|
+
|
|
29
|
+
|
|
21
30
|
## Installation
|
|
22
31
|
|
|
23
32
|
[tilemap-editor on PyPI](https://pypi.org/project/tilemap-editor/)
|
|
@@ -55,3 +64,6 @@ if __name__ == "__main__":
|
|
|
55
64
|
editor = Editor()
|
|
56
65
|
editor.run()
|
|
57
66
|
```
|
|
67
|
+
|
|
68
|
+
> [!WARNING]
|
|
69
|
+
> The current release requires **Python 3.11+**. The documentation incorrectly lists Python 3.10 support due to an accidental dependency on `typing.NotRequired`. This will be fixed in a future update.
|
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
`tilemap-editor` is a pygame-based map editor focused on fast iteration for 2D games.
|
|
4
4
|
|
|
5
|
+
# tilemap-editor
|
|
6
|
+
|
|
7
|
+
`tilemap-editor` is a Pygame-based map editor focused on fast iteration for 2D games.
|
|
8
|
+
|
|
9
|
+
> **Credits:** The initial version of this project was based on DaFluffyPotato's platformer tutorial which is about 6-hours. If you want to understand the foundation this project started from, I highly recommend watching his video: https://www.youtube.com/watch?v=2gABYM5M0ww. While the editor has since evolved with many additional features and improvements, the original map format has been preserved for compatibility.
|
|
10
|
+
|
|
11
|
+
Several features and design ideas were also inspired by the Godot Engine, including the animation workflow, polygon collision editing, and character collision (Sprite2D-style) editing.
|
|
12
|
+
|
|
13
|
+
|
|
5
14
|
## Installation
|
|
6
15
|
|
|
7
16
|
[tilemap-editor on PyPI](https://pypi.org/project/tilemap-editor/)
|
|
@@ -39,3 +48,6 @@ if __name__ == "__main__":
|
|
|
39
48
|
editor = Editor()
|
|
40
49
|
editor.run()
|
|
41
50
|
```
|
|
51
|
+
|
|
52
|
+
> [!WARNING]
|
|
53
|
+
> The current release requires **Python 3.11+**. The documentation incorrectly lists Python 3.10 support due to an accidental dependency on `typing.NotRequired`. This will be fixed in a future update.
|
|
@@ -13,7 +13,7 @@ def create_node_id() -> str:
|
|
|
13
13
|
return str(uuid.uuid4())
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
SIDECAR_VERSION =
|
|
16
|
+
SIDECAR_VERSION = 2
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class NodeManager:
|
|
@@ -49,10 +49,15 @@ class NodeManager:
|
|
|
49
49
|
raw = json.loads(sidecar.read_text(encoding="utf-8"))
|
|
50
50
|
if not isinstance(raw, dict):
|
|
51
51
|
return
|
|
52
|
+
version = raw.get("version", 1)
|
|
52
53
|
self.groups = list(raw.get("groups", []))
|
|
54
|
+
rs = self.editor.tilemap.render_scale
|
|
53
55
|
for item in raw.get("nodes", []):
|
|
54
56
|
if isinstance(item, dict):
|
|
55
57
|
node = Node.from_dict(item)
|
|
58
|
+
if version >= 2:
|
|
59
|
+
node.area.x = int(node.area.x * rs)
|
|
60
|
+
node.area.y = int(node.area.y * rs)
|
|
56
61
|
self.nodes[node.node_id] = node
|
|
57
62
|
except (json.JSONDecodeError, KeyError, ValueError, TypeError):
|
|
58
63
|
import logging
|
|
@@ -62,12 +67,23 @@ class NodeManager:
|
|
|
62
67
|
def save(self, map_path: Path) -> None:
|
|
63
68
|
sidecar = self._sidecar_path_for(map_path)
|
|
64
69
|
self.nodes_dir.mkdir(parents=True, exist_ok=True)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
rs = self.editor.tilemap.render_scale
|
|
71
|
+
orig_areas: dict[str, tuple[int, int]] = {}
|
|
72
|
+
for nid, node in self.nodes.items():
|
|
73
|
+
orig_areas[nid] = (node.area.x, node.area.y)
|
|
74
|
+
node.area.x = int(node.area.x / rs)
|
|
75
|
+
node.area.y = int(node.area.y / rs)
|
|
76
|
+
try:
|
|
77
|
+
data: dict[str, Any] = {
|
|
78
|
+
"version": SIDECAR_VERSION,
|
|
79
|
+
"groups": self.groups,
|
|
80
|
+
"nodes": [node.to_dict() for node in self.nodes.values()],
|
|
81
|
+
}
|
|
82
|
+
sidecar.write_text(json.dumps(data, indent=2), encoding="utf-8")
|
|
83
|
+
finally:
|
|
84
|
+
for nid, (ox, oy) in orig_areas.items():
|
|
85
|
+
self.nodes[nid].area.x = ox
|
|
86
|
+
self.nodes[nid].area.y = oy
|
|
71
87
|
|
|
72
88
|
def add_node(self, node: Node) -> str:
|
|
73
89
|
self.nodes[node.node_id] = node
|
|
@@ -182,11 +182,32 @@ class CharacterCollisionEditor:
|
|
|
182
182
|
self._image_path = self._rel_path(path)
|
|
183
183
|
pygame.display.set_caption(f"Character Collision Editor — {path.stem}")
|
|
184
184
|
self._toast_manager.success(f"Loaded sprite: {path.name}")
|
|
185
|
+
self._auto_load_collision()
|
|
185
186
|
except Exception as e:
|
|
186
187
|
self._toast_manager.error(f"Failed to load image: {e}")
|
|
187
188
|
finally:
|
|
188
189
|
self._image_dialog = None
|
|
189
190
|
|
|
191
|
+
def _auto_load_collision(self) -> bool:
|
|
192
|
+
name = self._name_input.text.strip()
|
|
193
|
+
if not name:
|
|
194
|
+
return False
|
|
195
|
+
safe = re.sub(r"[^\w\-]+", "-", name).strip("-").lower()
|
|
196
|
+
coll_filename = f"{safe}.collision.json"
|
|
197
|
+
try:
|
|
198
|
+
coll_dir = self._get_collision_dir()
|
|
199
|
+
except RuntimeError:
|
|
200
|
+
return False
|
|
201
|
+
coll_path = coll_dir / coll_filename
|
|
202
|
+
if coll_path.exists():
|
|
203
|
+
try:
|
|
204
|
+
self.load_from_file(coll_path)
|
|
205
|
+
self._toast_manager.success(f"Loaded collision: {coll_path.name}")
|
|
206
|
+
return True
|
|
207
|
+
except Exception:
|
|
208
|
+
pass
|
|
209
|
+
return False
|
|
210
|
+
|
|
190
211
|
def _open_image_dialog(self) -> None:
|
|
191
212
|
try:
|
|
192
213
|
data_root = self._data_root or Path.cwd()
|
|
@@ -281,7 +302,6 @@ class CharacterCollisionEditor:
|
|
|
281
302
|
self.character_name = data.name
|
|
282
303
|
self._name_input.text = data.name
|
|
283
304
|
self._name_input.cursor_pos = len(data.name)
|
|
284
|
-
self.shape_editor.load_shape_data(data.shape.to_dict())
|
|
285
305
|
layer = data.properties.get("collision_layer", 1)
|
|
286
306
|
mask = data.properties.get("collision_mask", 0xFFFF)
|
|
287
307
|
self.layer_sidebar.set_layer(layer)
|
|
@@ -293,7 +313,9 @@ class CharacterCollisionEditor:
|
|
|
293
313
|
if resolved:
|
|
294
314
|
self._load_sprite_from_path(resolved)
|
|
295
315
|
self._toast_manager.success(f"Sprite loaded: {resolved.name}")
|
|
296
|
-
|
|
316
|
+
|
|
317
|
+
self.shape_editor.load_shape_data(data.shape.to_dict())
|
|
318
|
+
return
|
|
297
319
|
|
|
298
320
|
if data.name:
|
|
299
321
|
for d in [self._data_root]:
|
|
@@ -545,6 +567,7 @@ class CharacterCollisionEditor:
|
|
|
545
567
|
editor = cls(rect, surface, character_name)
|
|
546
568
|
editor._data_root = data_root
|
|
547
569
|
editor._image_path = image_path
|
|
570
|
+
editor._auto_load_collision()
|
|
548
571
|
return editor
|
|
549
572
|
|
|
550
573
|
def run(self) -> None:
|
{tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/character_collision/shape_editor.py
RENAMED
|
@@ -100,6 +100,30 @@ class ShapeEditor:
|
|
|
100
100
|
self.offset_x = (self.rect.w - sw * self.zoom) / 2
|
|
101
101
|
self.offset_y = (self.rect.h - sh * self.zoom) / 2
|
|
102
102
|
|
|
103
|
+
def _focus_on_shape(self) -> None:
|
|
104
|
+
"""Center the viewport on the shape's bounding box"""
|
|
105
|
+
left, top, right, bottom = self._shape_bounds()
|
|
106
|
+
cx = (left + right) / 2
|
|
107
|
+
cy = (top + bottom) / 2
|
|
108
|
+
self.offset_x = self.rect.w / 2 - cx * self.zoom
|
|
109
|
+
self.offset_y = self.rect.h / 2 - cy * self.zoom
|
|
110
|
+
|
|
111
|
+
def _shape_bounds(self) -> tuple[float, float, float, float]:
|
|
112
|
+
"""Get shape bounding box in sprite-local coords (left, top, right, bottom)"""
|
|
113
|
+
if self.shape_type == "rectangle":
|
|
114
|
+
return (self.rect_x, self.rect_y, self.rect_x + self.rect_w, self.rect_y + self.rect_h)
|
|
115
|
+
if self.shape_type == "circle":
|
|
116
|
+
return (self.circle_x - self.circle_radius, self.circle_y - self.circle_radius,
|
|
117
|
+
self.circle_x + self.circle_radius, self.circle_y + self.circle_radius)
|
|
118
|
+
if self.shape_type == "capsule":
|
|
119
|
+
return (self.capsule_x - self.capsule_radius, self.capsule_y,
|
|
120
|
+
self.capsule_x + self.capsule_radius, self.capsule_y + self.capsule_height)
|
|
121
|
+
if self.shape_type == "polygon" and self.polygon_vertices:
|
|
122
|
+
xs = [v[0] for v in self.polygon_vertices]
|
|
123
|
+
ys = [v[1] for v in self.polygon_vertices]
|
|
124
|
+
return (min(xs), min(ys), max(xs), max(ys))
|
|
125
|
+
return (0, 0, 0, 0)
|
|
126
|
+
|
|
103
127
|
def _center_shape(self) -> None:
|
|
104
128
|
"""Center all shape types on the sprite"""
|
|
105
129
|
sw, sh = self.sprite_surface.get_size()
|
|
@@ -195,6 +219,8 @@ class ShapeEditor:
|
|
|
195
219
|
elif shape_type == "polygon":
|
|
196
220
|
self.polygon_vertices = [tuple(v) for v in data.get("vertices", [])]
|
|
197
221
|
|
|
222
|
+
self._focus_on_shape()
|
|
223
|
+
|
|
198
224
|
def resize(self, rect: Rect) -> None:
|
|
199
225
|
"""Update rect"""
|
|
200
226
|
self.rect = rect
|
|
@@ -254,12 +280,19 @@ class ShapeEditor:
|
|
|
254
280
|
self.hover_handle = None
|
|
255
281
|
|
|
256
282
|
if event.type == pygame.MOUSEWHEEL and self.rect.collidepoint(mouse):
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
283
|
+
mods = pygame.key.get_mods()
|
|
284
|
+
if mods & (pygame.KMOD_CTRL | pygame.KMOD_META):
|
|
285
|
+
self.zoom *= 1.15 if event.y > 0 else 0.87
|
|
286
|
+
self.zoom = max(0.5, min(self.zoom, 8.0))
|
|
287
|
+
sprite_pos = self._screen_to_sprite(mouse)
|
|
288
|
+
self.offset_x = mouse[0] - self.rect.x - sprite_pos[0] * self.zoom
|
|
289
|
+
self.offset_y = mouse[1] - self.rect.y - sprite_pos[1] * self.zoom
|
|
290
|
+
elif mods & pygame.KMOD_SHIFT:
|
|
291
|
+
scroll_val = event.y if event.y != 0 else event.x
|
|
292
|
+
self.offset_x -= scroll_val * 30
|
|
293
|
+
else:
|
|
294
|
+
scroll_val = event.y if event.y != 0 else event.x
|
|
295
|
+
self.offset_y -= scroll_val * 30
|
|
263
296
|
return True
|
|
264
297
|
|
|
265
298
|
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
|
{tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/object_tileset_collision/editor.py
RENAMED
|
@@ -234,12 +234,13 @@ class ObjectTilesetCollisionEditor:
|
|
|
234
234
|
def _layout_toolbar_buttons(self) -> None:
|
|
235
235
|
x = self.toolbar_rect.x + 10
|
|
236
236
|
y = self.toolbar_rect.y + 8
|
|
237
|
-
for
|
|
237
|
+
for btn in self._toolbar_buttons:
|
|
238
238
|
if btn.text == "?":
|
|
239
239
|
w, h = 28, 28
|
|
240
240
|
else:
|
|
241
241
|
w, h = 60, 28
|
|
242
|
-
btn.resize(x
|
|
242
|
+
btn.resize(x, y, w, h)
|
|
243
|
+
x += w + 8
|
|
243
244
|
|
|
244
245
|
def _on_splitter_drag(self, pos: int) -> None:
|
|
245
246
|
self.tileset_selector_height = max(
|
{tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/tileset_collision/collision_painter.py
RENAMED
|
@@ -476,12 +476,19 @@ class CollisionPainter:
|
|
|
476
476
|
return True
|
|
477
477
|
|
|
478
478
|
if event.type == pygame.MOUSEWHEEL and self.rect.collidepoint(mouse):
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
479
|
+
mods = pygame.key.get_mods()
|
|
480
|
+
if mods & (pygame.KMOD_CTRL | pygame.KMOD_META):
|
|
481
|
+
self.zoom *= 1.15 if event.y > 0 else 0.87
|
|
482
|
+
self.zoom = max(0.5, min(self.zoom, 8.0))
|
|
483
|
+
tile_pos = self._screen_to_tile(mouse)
|
|
484
|
+
self.offset_x = mouse[0] - self.rect.x - tile_pos[0] * self.zoom
|
|
485
|
+
self.offset_y = mouse[1] - self.rect.y - tile_pos[1] * self.zoom
|
|
486
|
+
elif mods & pygame.KMOD_SHIFT:
|
|
487
|
+
scroll_val = event.y if event.y != 0 else event.x
|
|
488
|
+
self.offset_x -= scroll_val * 30
|
|
489
|
+
else:
|
|
490
|
+
scroll_val = event.y if event.y != 0 else event.x
|
|
491
|
+
self.offset_y -= scroll_val * 30
|
|
485
492
|
return True
|
|
486
493
|
|
|
487
494
|
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
|
|
@@ -716,8 +716,18 @@ class TilesetCollisionEditor:
|
|
|
716
716
|
return True
|
|
717
717
|
|
|
718
718
|
if event.type == pygame.MOUSEWHEEL:
|
|
719
|
-
|
|
720
|
-
|
|
719
|
+
mods = pygame.key.get_mods()
|
|
720
|
+
if mods & (pygame.KMOD_CTRL | pygame.KMOD_META):
|
|
721
|
+
self.tileset_zoom *= 1.15 if event.y > 0 else 0.87
|
|
722
|
+
self.tileset_zoom = max(0.5, min(self.tileset_zoom, 8.0))
|
|
723
|
+
elif mods & pygame.KMOD_SHIFT:
|
|
724
|
+
scroll_val = event.y if event.y != 0 else event.x
|
|
725
|
+
self.tileset_scroll_x -= scroll_val * 30
|
|
726
|
+
else:
|
|
727
|
+
scroll_val = event.y if event.y != 0 else event.x
|
|
728
|
+
self.tileset_scroll_y -= scroll_val * 30
|
|
729
|
+
self.tileset_scroll_x = max(0, self.tileset_scroll_x)
|
|
730
|
+
self.tileset_scroll_y = max(0, self.tileset_scroll_y)
|
|
721
731
|
return True
|
|
722
732
|
|
|
723
733
|
if event.type == pygame.MOUSEBUTTONUP:
|
|
@@ -947,12 +957,17 @@ class TilesetCollisionEditor:
|
|
|
947
957
|
tw = int(self._tile_size[0] * self.tileset_zoom)
|
|
948
958
|
th = int(self._tile_size[1] * self.tileset_zoom)
|
|
949
959
|
|
|
960
|
+
tileset_scr_w = self.tile_cols * tw
|
|
961
|
+
tileset_scr_h = self.tile_rows * th
|
|
962
|
+
center_off_x = max(0, (self.tileset_selector_rect.w - tileset_scr_w) // 2)
|
|
963
|
+
center_off_y = max(0, (self.tileset_selector_rect.h - tileset_scr_h) // 2)
|
|
964
|
+
|
|
950
965
|
for row in range(self.tile_rows):
|
|
951
966
|
for col in range(self.tile_cols):
|
|
952
967
|
tile_id = row * self.tile_cols + col
|
|
953
968
|
|
|
954
|
-
x = self.tileset_selector_rect.x + col * tw - self.tileset_scroll_x
|
|
955
|
-
y = self.tileset_selector_rect.y + row * th - self.tileset_scroll_y
|
|
969
|
+
x = self.tileset_selector_rect.x + col * tw - self.tileset_scroll_x + center_off_x
|
|
970
|
+
y = self.tileset_selector_rect.y + row * th - self.tileset_scroll_y + center_off_y
|
|
956
971
|
|
|
957
972
|
if (
|
|
958
973
|
x + tw < self.tileset_selector_rect.x
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tilemap-editor
|
|
3
|
-
Version: 4.3.
|
|
3
|
+
Version: 4.3.5
|
|
4
4
|
Summary: Pygame tilemap editor with collision, animation, sprite & particle tools
|
|
5
5
|
Author: tilemap editor contributors
|
|
6
6
|
License: Proprietary
|
|
@@ -18,6 +18,15 @@ Dynamic: license-file
|
|
|
18
18
|
|
|
19
19
|
`tilemap-editor` is a pygame-based map editor focused on fast iteration for 2D games.
|
|
20
20
|
|
|
21
|
+
# tilemap-editor
|
|
22
|
+
|
|
23
|
+
`tilemap-editor` is a Pygame-based map editor focused on fast iteration for 2D games.
|
|
24
|
+
|
|
25
|
+
> **Credits:** The initial version of this project was based on DaFluffyPotato's platformer tutorial which is about 6-hours. If you want to understand the foundation this project started from, I highly recommend watching his video: https://www.youtube.com/watch?v=2gABYM5M0ww. While the editor has since evolved with many additional features and improvements, the original map format has been preserved for compatibility.
|
|
26
|
+
|
|
27
|
+
Several features and design ideas were also inspired by the Godot Engine, including the animation workflow, polygon collision editing, and character collision (Sprite2D-style) editing.
|
|
28
|
+
|
|
29
|
+
|
|
21
30
|
## Installation
|
|
22
31
|
|
|
23
32
|
[tilemap-editor on PyPI](https://pypi.org/project/tilemap-editor/)
|
|
@@ -55,3 +64,6 @@ if __name__ == "__main__":
|
|
|
55
64
|
editor = Editor()
|
|
56
65
|
editor.run()
|
|
57
66
|
```
|
|
67
|
+
|
|
68
|
+
> [!WARNING]
|
|
69
|
+
> The current release requires **Python 3.11+**. The documentation incorrectly lists Python 3.10 support due to an accidental dependency on `typing.NotRequired`. This will be fixed in a future update.
|
|
@@ -799,10 +799,12 @@ class TileGrid:
|
|
|
799
799
|
elif active_layer.layer_type == "object":
|
|
800
800
|
mouse_pos = pygame.mouse.get_pos()
|
|
801
801
|
world_pos = self.screen_to_world(mouse_pos)
|
|
802
|
+
rs = self.editor.tilemap.render_scale
|
|
803
|
+
pick_pos = (int(world_pos[0] / rs), int(world_pos[1] / rs)) if rs else world_pos
|
|
802
804
|
for _obj_id, obj in active_layer.get_all_objects().items():
|
|
803
805
|
area = obj["area"]
|
|
804
806
|
obj_rect = Rect(area["x"], area["y"], area["w"], area["h"])
|
|
805
|
-
if obj_rect.collidepoint(
|
|
807
|
+
if obj_rect.collidepoint(pick_pos):
|
|
806
808
|
ttype = int(obj["ttype"])
|
|
807
809
|
variant = obj["variant"]
|
|
808
810
|
ts_widget.select_tile_by_variant(ttype, variant)
|
|
@@ -329,17 +329,26 @@ class RegionSelector:
|
|
|
329
329
|
self._update_hover(mouse)
|
|
330
330
|
|
|
331
331
|
if event.type == pygame.MOUSEWHEEL and in_bounds:
|
|
332
|
-
|
|
333
|
-
if
|
|
334
|
-
|
|
332
|
+
mods = pygame.key.get_mods()
|
|
333
|
+
if mods & (pygame.KMOD_CTRL | pygame.KMOD_META):
|
|
334
|
+
old_zoom = self.zoom
|
|
335
|
+
if event.y > 0:
|
|
336
|
+
self.zoom = min(self.zoom * 1.15, 8.0)
|
|
337
|
+
else:
|
|
338
|
+
self.zoom = max(self.zoom * 0.87, 0.25)
|
|
339
|
+
if self.image:
|
|
340
|
+
img_x = (mouse[0] - self.rect.x + self.scroll_x) / old_zoom
|
|
341
|
+
img_y = (mouse[1] - self.rect.y + self.scroll_y) / old_zoom
|
|
342
|
+
self.scroll_x = int(img_x * self.zoom - (mouse[0] - self.rect.x))
|
|
343
|
+
self.scroll_y = int(img_y * self.zoom - (mouse[1] - self.rect.y))
|
|
344
|
+
self._clamp_scroll()
|
|
345
|
+
elif mods & pygame.KMOD_SHIFT:
|
|
346
|
+
scroll_val = event.y if event.y != 0 else event.x
|
|
347
|
+
self.scroll_x -= scroll_val * 30
|
|
348
|
+
self._clamp_scroll()
|
|
335
349
|
else:
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
if self.image:
|
|
339
|
-
img_x = (mouse[0] - self.rect.x + self.scroll_x) / old_zoom
|
|
340
|
-
img_y = (mouse[1] - self.rect.y + self.scroll_y) / old_zoom
|
|
341
|
-
self.scroll_x = int(img_x * self.zoom - (mouse[0] - self.rect.x))
|
|
342
|
-
self.scroll_y = int(img_y * self.zoom - (mouse[1] - self.rect.y))
|
|
350
|
+
scroll_val = event.y if event.y != 0 else event.x
|
|
351
|
+
self.scroll_y -= scroll_val * 30
|
|
343
352
|
self._clamp_scroll()
|
|
344
353
|
return True
|
|
345
354
|
|
|
@@ -501,8 +510,10 @@ class RegionSelector:
|
|
|
501
510
|
if self.image:
|
|
502
511
|
img_w = int(self.image.get_width() * self.zoom)
|
|
503
512
|
img_h = int(self.image.get_height() * self.zoom)
|
|
504
|
-
|
|
505
|
-
|
|
513
|
+
center_off_x = max(0, (self.rect.w - img_w) // 2)
|
|
514
|
+
center_off_y = max(0, (self.rect.h - img_h) // 2)
|
|
515
|
+
img_x = self.rect.x - self.scroll_x + center_off_x
|
|
516
|
+
img_y = self.rect.y - self.scroll_y + center_off_y
|
|
506
517
|
|
|
507
518
|
clip = screen.get_clip()
|
|
508
519
|
screen.set_clip(self.rect)
|
|
File without changes
|
|
File without changes
|
{tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/fonts/jetbrain-fonts/JetBrainsMono-Bold.ttf
RENAMED
|
File without changes
|
|
File without changes
|
{tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/fonts/jetbrain-fonts/JetBrainsMono-Italic.ttf
RENAMED
|
File without changes
|
{tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/assets/fonts/jetbrain-fonts/JetBrainsMono-Regular.ttf
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/object_tileset_collision/__init__.py
RENAMED
|
File without changes
|
{tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/object_tileset_collision/models.py
RENAMED
|
File without changes
|
{tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/object_tileset_collision/protocols.py
RENAMED
|
File without changes
|
{tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/object_tileset_collision/standalone.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tilemap_editor-4.3.4 → tilemap_editor-4.3.5}/src/plugins/sprite_animation/clipboard_util.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|