summaryrefslogtreecommitdiff
path: root/scene/2d
diff options
context:
space:
mode:
Diffstat (limited to 'scene/2d')
-rw-r--r--scene/2d/collision_polygon_2d.cpp3
-rw-r--r--scene/2d/sprite.cpp52
-rw-r--r--scene/2d/sprite.h3
-rw-r--r--scene/2d/tile_map.cpp30
-rw-r--r--scene/2d/tile_map.h3
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();