diff options
Diffstat (limited to 'scene/2d')
-rw-r--r-- | scene/2d/collision_polygon_2d.cpp | 3 | ||||
-rw-r--r-- | scene/2d/sprite.cpp | 52 | ||||
-rw-r--r-- | scene/2d/sprite.h | 3 | ||||
-rw-r--r-- | scene/2d/tile_map.cpp | 30 | ||||
-rw-r--r-- | scene/2d/tile_map.h | 3 |
5 files changed, 85 insertions, 6 deletions
diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index 978fb379ac..7e2026d225 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -175,7 +175,8 @@ void CollisionPolygon2D::_notification(int p_what) { Vector2 p = polygon[i]; Vector2 n = polygon[(i + 1) % polygon.size()]; - draw_line(p, n, Color(0.9, 0.2, 0.0, 0.8), 3); + // draw line with width <= 1, so it does not scale with zoom and break pixel exact editing + draw_line(p, n, Color(0.9, 0.2, 0.0, 0.8), 1); } #define DEBUG_DECOMPOSE #if defined(TOOLS_ENABLED) && defined(DEBUG_DECOMPOSE) diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index 0dd02a982c..67f016ae79 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -121,7 +121,15 @@ void Sprite::set_texture(const Ref<Texture> &p_texture) { if (p_texture == texture) return; + + if (texture.is_valid()) + texture->remove_change_receptor(this); + texture = p_texture; + + if (texture.is_valid()) + texture->add_change_receptor(this); + update(); emit_signal("texture_changed"); item_rect_changed(); @@ -281,13 +289,39 @@ bool Sprite::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc Rect2 src_rect, dst_rect; bool filter_clip; _get_rects(src_rect, dst_rect, filter_clip); + dst_rect.size = dst_rect.size.abs(); if (!dst_rect.has_point(p_point)) return false; - Vector2 q = ((p_point - dst_rect.position) / dst_rect.size) * src_rect.size + src_rect.position; + Vector2 q = (p_point - dst_rect.position) / dst_rect.size; + if (hflip) + q.x = 1.0f - q.x; + if (vflip) + q.y = 1.0f - q.y; + q = q * src_rect.size + src_rect.position; + + Ref<Image> image; + Ref<AtlasTexture> atlasTexture = texture; + if (atlasTexture.is_null()) { + image = texture->get_data(); + } else { + ERR_FAIL_COND_V(atlasTexture->get_atlas().is_null(), false); + + image = atlasTexture->get_atlas()->get_data(); + + Rect2 region = atlasTexture->get_region(); + Rect2 margin = atlasTexture->get_margin(); + + q -= margin.position; + + if ((q.x > region.size.width) || (q.y > region.size.height)) { + return false; + } + + q += region.position; + } - Ref<Image> image = texture->get_data(); ERR_FAIL_COND_V(image.is_null(), false); image->lock(); @@ -336,6 +370,15 @@ void Sprite::_validate_property(PropertyInfo &property) const { } } +void Sprite::_changed_callback(Object *p_changed, const char *p_prop) { + + // Changes to the texture need to trigger an update to make + // the editor redraw the sprite with the updated texture. + if (texture.is_valid() && texture.ptr() == p_changed) { + update(); + } +} + void Sprite::_bind_methods() { ClassDB::bind_method(D_METHOD("set_texture", "texture"), &Sprite::set_texture); @@ -410,3 +453,8 @@ Sprite::Sprite() { vframes = 1; hframes = 1; } + +Sprite::~Sprite() { + if (texture.is_valid()) + texture->remove_change_receptor(this); +} diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h index dd3719099f..abd04515ec 100644 --- a/scene/2d/sprite.h +++ b/scene/2d/sprite.h @@ -64,6 +64,8 @@ protected: virtual void _validate_property(PropertyInfo &property) const; + virtual void _changed_callback(Object *p_changed, const char *p_prop); + public: virtual Dictionary _edit_get_state() const; virtual void _edit_set_state(const Dictionary &p_state); @@ -113,6 +115,7 @@ public: Rect2 get_rect() const; Sprite(); + ~Sprite(); }; #endif // SPRITE_H diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 2aa55e2825..b602839b99 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -142,16 +142,20 @@ void TileMap::_update_quadrant_transform() { void TileMap::set_tileset(const Ref<TileSet> &p_tileset) { - if (tile_set.is_valid()) + if (tile_set.is_valid()) { tile_set->disconnect("changed", this, "_recreate_quadrants"); + tile_set->remove_change_receptor(this); + } _clear_quadrants(); tile_set = p_tileset; - if (tile_set.is_valid()) + if (tile_set.is_valid()) { tile_set->connect("changed", this, "_recreate_quadrants"); - else + tile_set->add_change_receptor(this); + } else { clear(); + } _recreate_quadrants(); emit_signal("settings_changed"); @@ -830,6 +834,16 @@ void TileMap::update_dirty_bitmask() { } } +void TileMap::fix_invalid_tiles() { + + for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { + + if (!tile_set->has_tile(get_cell(E->key().x, E->key().y))) { + set_cell(E->key().x, E->key().y, INVALID_CELL); + } + } +} + int TileMap::get_cell(int p_x, int p_y) const { PosKey pk(p_x, p_y); @@ -1515,6 +1529,7 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("is_cell_y_flipped", "x", "y"), &TileMap::is_cell_y_flipped); ClassDB::bind_method(D_METHOD("is_cell_transposed", "x", "y"), &TileMap::is_cell_transposed); + ClassDB::bind_method(D_METHOD("fix_invalid_tiles"), &TileMap::fix_invalid_tiles); ClassDB::bind_method(D_METHOD("clear"), &TileMap::clear); ClassDB::bind_method(D_METHOD("get_used_cells"), &TileMap::get_used_cells); @@ -1573,6 +1588,12 @@ void TileMap::_bind_methods() { BIND_ENUM_CONSTANT(TILE_ORIGIN_BOTTOM_LEFT); } +void TileMap::_changed_callback(Object *p_changed, const char *p_prop) { + if (tile_set.is_valid() && tile_set.ptr() == p_changed) { + emit_signal("settings_changed"); + } +} + TileMap::TileMap() { rect_cache_dirty = true; @@ -1601,5 +1622,8 @@ TileMap::TileMap() { TileMap::~TileMap() { + if (tile_set.is_valid()) + tile_set->remove_change_receptor(this); + clear(); } diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 973e527b42..587bd3b684 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -217,6 +217,8 @@ protected: void _notification(int p_what); static void _bind_methods(); + virtual void _changed_callback(Object *p_changed, const char *p_prop); + public: enum { INVALID_CELL = -1 @@ -308,6 +310,7 @@ public: void set_clip_uv(bool p_enable); bool get_clip_uv() const; + void fix_invalid_tiles(); void clear(); TileMap(); |