diff options
Diffstat (limited to 'scene/2d')
-rw-r--r-- | scene/2d/animated_sprite_2d.cpp | 118 | ||||
-rw-r--r-- | scene/2d/animated_sprite_2d.h | 3 | ||||
-rw-r--r-- | scene/2d/area_2d.cpp | 13 | ||||
-rw-r--r-- | scene/2d/area_2d.h | 3 | ||||
-rw-r--r-- | scene/2d/parallax_background.cpp | 4 | ||||
-rw-r--r-- | scene/2d/parallax_layer.cpp | 10 | ||||
-rw-r--r-- | scene/2d/parallax_layer.h | 4 | ||||
-rw-r--r-- | scene/2d/physics_body_2d.cpp | 12 | ||||
-rw-r--r-- | scene/2d/physics_body_2d.h | 4 |
9 files changed, 99 insertions, 72 deletions
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp index b1b1cb23ed..f84e82a6bb 100644 --- a/scene/2d/animated_sprite_2d.cpp +++ b/scene/2d/animated_sprite_2d.cpp @@ -63,9 +63,13 @@ Rect2 AnimatedSprite2D::_edit_get_rect() const { } bool AnimatedSprite2D::_edit_use_rect() const { - if (!frames.is_valid() || !frames->has_animation(animation) || frame < 0 || frame >= frames->get_frame_count(animation)) { + if (frames.is_null() || !frames->has_animation(animation)) { return false; } + if (frame < 0 || frame >= frames->get_frame_count(animation)) { + return false; + } + Ref<Texture2D> t; if (animation) { t = frames->get_frame(animation, frame); @@ -79,7 +83,10 @@ Rect2 AnimatedSprite2D::get_anchorable_rect() const { } Rect2 AnimatedSprite2D::_get_rect() const { - if (!frames.is_valid() || !frames->has_animation(animation) || frame < 0 || frame >= frames->get_frame_count(animation)) { + if (frames.is_null() || !frames->has_animation(animation)) { + return Rect2(); + } + if (frame < 0 || frame >= frames->get_frame_count(animation)) { return Rect2(); } @@ -108,6 +115,7 @@ void AnimatedSprite2D::_validate_property(PropertyInfo &p_property) const { if (!frames.is_valid()) { return; } + if (p_property.name == "animation") { p_property.hint = PROPERTY_HINT_ENUM; List<StringName> names; @@ -137,9 +145,15 @@ void AnimatedSprite2D::_validate_property(PropertyInfo &p_property) const { p_property.hint_string = String(animation) + "," + p_property.hint_string; } } + return; } if (p_property.name == "frame") { + if (playing) { + p_property.usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY; + return; + } + p_property.hint = PROPERTY_HINT_RANGE; if (frames->has_animation(animation) && frames->get_frame_count(animation) > 0) { p_property.hint_string = "0," + itos(frames->get_frame_count(animation) - 1) + ",1"; @@ -154,54 +168,52 @@ void AnimatedSprite2D::_validate_property(PropertyInfo &p_property) const { void AnimatedSprite2D::_notification(int p_what) { switch (p_what) { case NOTIFICATION_INTERNAL_PROCESS: { - if (frames.is_null()) { + if (frames.is_null() || !frames->has_animation(animation)) { return; } - if (!frames->has_animation(animation)) { - return; - } - if (frame < 0) { - return; + + double speed = frames->get_animation_speed(animation) * Math::abs(speed_scale); + if (speed == 0) { + return; // Do nothing. } + int last_frame = frames->get_frame_count(animation) - 1; double remaining = get_process_delta_time(); - while (remaining) { - double speed = frames->get_animation_speed(animation) * speed_scale; - if (speed == 0) { - return; // Do nothing. - } - if (timeout <= 0) { timeout = _get_frame_duration(); - int fc = frames->get_frame_count(animation); - if ((!backwards && frame >= fc - 1) || (backwards && frame <= 0)) { - if (frames->get_animation_loop(animation)) { - if (backwards) { - frame = fc - 1; - } else { - frame = 0; - } - - emit_signal(SceneStringNames::get_singleton()->animation_finished); - } else { - if (backwards) { + if (!playing_backwards) { + // Forward. + if (frame >= last_frame) { + if (frames->get_animation_loop(animation)) { frame = 0; - } else { - frame = fc - 1; - } - - if (!is_over) { - is_over = true; emit_signal(SceneStringNames::get_singleton()->animation_finished); + } else { + frame = last_frame; + if (!is_over) { + is_over = true; + emit_signal(SceneStringNames::get_singleton()->animation_finished); + } } + } else { + frame++; } } else { - if (backwards) { - frame--; + // Reversed. + if (frame <= 0) { + if (frames->get_animation_loop(animation)) { + frame = last_frame; + emit_signal(SceneStringNames::get_singleton()->animation_finished); + } else { + frame = 0; + if (!is_over) { + is_over = true; + emit_signal(SceneStringNames::get_singleton()->animation_finished); + } + } } else { - frame++; + frame--; } } @@ -217,13 +229,7 @@ void AnimatedSprite2D::_notification(int p_what) { } break; case NOTIFICATION_DRAW: { - if (frames.is_null()) { - return; - } - if (frame < 0) { - return; - } - if (!frames->has_animation(animation)) { + if (frames.is_null() || !frames->has_animation(animation)) { return; } @@ -259,14 +265,15 @@ void AnimatedSprite2D::_notification(int p_what) { void AnimatedSprite2D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) { if (frames.is_valid()) { - frames->disconnect("changed", callable_mp(this, &AnimatedSprite2D::_res_changed)); + frames->disconnect(SceneStringNames::get_singleton()->changed, callable_mp(this, &AnimatedSprite2D::_res_changed)); } + frames = p_frames; if (frames.is_valid()) { - frames->connect("changed", callable_mp(this, &AnimatedSprite2D::_res_changed)); + frames->connect(SceneStringNames::get_singleton()->changed, callable_mp(this, &AnimatedSprite2D::_res_changed)); } - if (!frames.is_valid()) { + if (frames.is_null()) { frame = 0; } else { set_frame(frame); @@ -283,7 +290,7 @@ Ref<SpriteFrames> AnimatedSprite2D::get_sprite_frames() const { } void AnimatedSprite2D::set_frame(int p_frame) { - if (!frames.is_valid()) { + if (frames.is_null()) { return; } @@ -314,11 +321,16 @@ int AnimatedSprite2D::get_frame() const { } void AnimatedSprite2D::set_speed_scale(double p_speed_scale) { + if (speed_scale == p_speed_scale) { + return; + } + double elapsed = _get_frame_duration() - timeout; - speed_scale = MAX(p_speed_scale, 0.0f); + speed_scale = p_speed_scale; + playing_backwards = signbit(speed_scale) != backwards; - // We adapt the timeout so that the animation speed adapts as soon as the speed scale is changed + // We adapt the timeout so that the animation speed adapts as soon as the speed scale is changed. _reset_timeout(); timeout -= elapsed; } @@ -378,18 +390,20 @@ void AnimatedSprite2D::set_playing(bool p_playing) { playing = p_playing; _reset_timeout(); set_process_internal(playing); + notify_property_list_changed(); } bool AnimatedSprite2D::is_playing() const { return playing; } -void AnimatedSprite2D::play(const StringName &p_animation, const bool p_backwards) { +void AnimatedSprite2D::play(const StringName &p_animation, bool p_backwards) { backwards = p_backwards; + playing_backwards = signbit(speed_scale) != backwards; if (p_animation) { set_animation(p_animation); - if (frames.is_valid() && backwards && get_frame() == 0) { + if (frames.is_valid() && playing_backwards && get_frame() == 0) { set_frame(frames->get_frame_count(p_animation) - 1); } } @@ -404,7 +418,7 @@ void AnimatedSprite2D::stop() { double AnimatedSprite2D::_get_frame_duration() { if (frames.is_valid() && frames->has_animation(animation)) { - double speed = frames->get_animation_speed(animation) * speed_scale; + double speed = frames->get_animation_speed(animation) * Math::abs(speed_scale); if (speed > 0) { return 1.0 / speed; } @@ -444,7 +458,7 @@ TypedArray<String> AnimatedSprite2D::get_configuration_warnings() const { TypedArray<String> warnings = Node::get_configuration_warnings(); if (frames.is_null()) { - warnings.push_back(RTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite to display frames.")); + warnings.push_back(RTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite2D to display frames.")); } return warnings; diff --git a/scene/2d/animated_sprite_2d.h b/scene/2d/animated_sprite_2d.h index 0a19e250d8..be1cc5353e 100644 --- a/scene/2d/animated_sprite_2d.h +++ b/scene/2d/animated_sprite_2d.h @@ -39,6 +39,7 @@ class AnimatedSprite2D : public Node2D { Ref<SpriteFrames> frames; bool playing = false; + bool playing_backwards = false; bool backwards = false; StringName animation = "default"; int frame = 0; @@ -81,7 +82,7 @@ public: void set_sprite_frames(const Ref<SpriteFrames> &p_frames); Ref<SpriteFrames> get_sprite_frames() const; - void play(const StringName &p_animation = StringName(), const bool p_backwards = false); + void play(const StringName &p_animation = StringName(), bool p_backwards = false); void stop(); void set_playing(bool p_playing); diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp index 3def41eaa5..b3f80b5e43 100644 --- a/scene/2d/area_2d.cpp +++ b/scene/2d/area_2d.cpp @@ -459,6 +459,16 @@ TypedArray<Area2D> Area2D::get_overlapping_areas() const { return ret; } +bool Area2D::has_overlapping_bodies() const { + ERR_FAIL_COND_V_MSG(!monitoring, false, "Can't find overlapping bodies when monitoring is off."); + return !body_map.is_empty(); +} + +bool Area2D::has_overlapping_areas() const { + ERR_FAIL_COND_V_MSG(!monitoring, false, "Can't find overlapping areas when monitoring is off."); + return !area_map.is_empty(); +} + bool Area2D::overlaps_area(Node *p_area) const { ERR_FAIL_NULL_V(p_area, false); HashMap<ObjectID, AreaState>::ConstIterator E = area_map.find(p_area->get_instance_id()); @@ -578,6 +588,9 @@ void Area2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_overlapping_bodies"), &Area2D::get_overlapping_bodies); ClassDB::bind_method(D_METHOD("get_overlapping_areas"), &Area2D::get_overlapping_areas); + ClassDB::bind_method(D_METHOD("has_overlapping_bodies"), &Area2D::has_overlapping_bodies); + ClassDB::bind_method(D_METHOD("has_overlapping_areas"), &Area2D::has_overlapping_areas); + ClassDB::bind_method(D_METHOD("overlaps_body", "body"), &Area2D::overlaps_body); ClassDB::bind_method(D_METHOD("overlaps_area", "area"), &Area2D::overlaps_area); diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h index 3d8d77eabb..f70f1dfc3d 100644 --- a/scene/2d/area_2d.h +++ b/scene/2d/area_2d.h @@ -180,6 +180,9 @@ public: TypedArray<Node2D> get_overlapping_bodies() const; //function for script TypedArray<Area2D> get_overlapping_areas() const; //function for script + bool has_overlapping_bodies() const; + bool has_overlapping_areas() const; + bool overlaps_area(Node *p_area) const; bool overlaps_body(Node *p_body) const; diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp index bd5a01f5a4..f1a28b7852 100644 --- a/scene/2d/parallax_background.cpp +++ b/scene/2d/parallax_background.cpp @@ -102,9 +102,9 @@ void ParallaxBackground::_update_scroll() { } if (ignore_camera_zoom) { - l->set_base_offset_and_scale((ofs + screen_offset * (scale - 1)) / scale, 1.0, screen_offset); + l->set_base_offset_and_scale((ofs + screen_offset * (scale - 1)) / scale, 1.0); } else { - l->set_base_offset_and_scale(ofs, scale, screen_offset); + l->set_base_offset_and_scale(ofs, scale); } } } diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp index f0aad1b8a4..d4138dc516 100644 --- a/scene/2d/parallax_layer.cpp +++ b/scene/2d/parallax_layer.cpp @@ -39,7 +39,7 @@ void ParallaxLayer::set_motion_scale(const Size2 &p_scale) { if (pb && is_inside_tree()) { Vector2 ofs = pb->get_final_offset(); real_t scale = pb->get_scroll_scale(); - set_base_offset_and_scale(ofs, scale, screen_offset); + set_base_offset_and_scale(ofs, scale); } } @@ -54,7 +54,7 @@ void ParallaxLayer::set_motion_offset(const Size2 &p_offset) { if (pb && is_inside_tree()) { Vector2 ofs = pb->get_final_offset(); real_t scale = pb->get_scroll_scale(); - set_base_offset_and_scale(ofs, scale, screen_offset); + set_base_offset_and_scale(ofs, scale); } } @@ -111,9 +111,7 @@ void ParallaxLayer::_notification(int p_what) { } } -void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, real_t p_scale, const Point2 &p_screen_offset) { - screen_offset = p_screen_offset; - +void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, real_t p_scale) { if (!is_inside_tree()) { return; } @@ -121,7 +119,7 @@ void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, real_t p_s return; } - Point2 new_ofs = (screen_offset + (p_offset - screen_offset) * motion_scale) + motion_offset * p_scale + orig_offset * p_scale; + Point2 new_ofs = p_offset * motion_scale + motion_offset * p_scale + orig_offset * p_scale; if (mirroring.x) { real_t den = mirroring.x * p_scale; diff --git a/scene/2d/parallax_layer.h b/scene/2d/parallax_layer.h index b4dcf0ea61..c03f4cc293 100644 --- a/scene/2d/parallax_layer.h +++ b/scene/2d/parallax_layer.h @@ -43,8 +43,6 @@ class ParallaxLayer : public Node2D { Vector2 mirroring; void _update_mirroring(); - Point2 screen_offset; - protected: void _notification(int p_what); static void _bind_methods(); @@ -59,7 +57,7 @@ public: void set_mirroring(const Size2 &p_mirroring); Size2 get_mirroring() const; - void set_base_offset_and_scale(const Point2 &p_offset, real_t p_scale, const Point2 &p_screen_offset); + void set_base_offset_and_scale(const Point2 &p_offset, real_t p_scale); TypedArray<String> get_configuration_warnings() const override; ParallaxLayer(); diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 714d196779..2aa14aa11a 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -34,8 +34,8 @@ #include "scene/scene_string_names.h" void PhysicsBody2D::_bind_methods() { - ClassDB::bind_method(D_METHOD("move_and_collide", "distance", "test_only", "safe_margin"), &PhysicsBody2D::_move, DEFVAL(false), DEFVAL(0.08)); - ClassDB::bind_method(D_METHOD("test_move", "from", "distance", "collision", "safe_margin"), &PhysicsBody2D::test_move, DEFVAL(Variant()), DEFVAL(0.08)); + ClassDB::bind_method(D_METHOD("move_and_collide", "distance", "test_only", "safe_margin", "recovery_as_collision"), &PhysicsBody2D::_move, DEFVAL(false), DEFVAL(0.08), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("test_move", "from", "distance", "collision", "safe_margin", "recovery_as_collision"), &PhysicsBody2D::test_move, DEFVAL(Variant()), DEFVAL(0.08), DEFVAL(false)); ClassDB::bind_method(D_METHOD("get_collision_exceptions"), &PhysicsBody2D::get_collision_exceptions); ClassDB::bind_method(D_METHOD("add_collision_exception_with", "body"), &PhysicsBody2D::add_collision_exception_with); @@ -54,9 +54,9 @@ PhysicsBody2D::~PhysicsBody2D() { } } -Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_distance, bool p_test_only, real_t p_margin) { +Ref<KinematicCollision2D> PhysicsBody2D::_move(const Vector2 &p_distance, bool p_test_only, real_t p_margin, bool p_recovery_as_collision) { PhysicsServer2D::MotionParameters parameters(get_global_transform(), p_distance, p_margin); - parameters.recovery_as_collision = false; // Don't report collisions generated only from recovery. + parameters.recovery_as_collision = p_recovery_as_collision; PhysicsServer2D::MotionResult result; @@ -128,7 +128,7 @@ bool PhysicsBody2D::move_and_collide(const PhysicsServer2D::MotionParameters &p_ return colliding; } -bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_distance, const Ref<KinematicCollision2D> &r_collision, real_t p_margin) { +bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_distance, const Ref<KinematicCollision2D> &r_collision, real_t p_margin, bool p_recovery_as_collision) { ERR_FAIL_COND_V(!is_inside_tree(), false); PhysicsServer2D::MotionResult *r = nullptr; @@ -141,7 +141,7 @@ bool PhysicsBody2D::test_move(const Transform2D &p_from, const Vector2 &p_distan } PhysicsServer2D::MotionParameters parameters(p_from, p_distance, p_margin); - parameters.recovery_as_collision = false; // Don't report collisions generated only from recovery. + parameters.recovery_as_collision = p_recovery_as_collision; return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), parameters, r); } diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index eaba9aadad..1bc24f3264 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -47,11 +47,11 @@ protected: Ref<KinematicCollision2D> motion_cache; - Ref<KinematicCollision2D> _move(const Vector2 &p_distance, bool p_test_only = false, real_t p_margin = 0.08); + Ref<KinematicCollision2D> _move(const Vector2 &p_distance, bool p_test_only = false, real_t p_margin = 0.08, bool p_recovery_as_collision = false); public: bool move_and_collide(const PhysicsServer2D::MotionParameters &p_parameters, PhysicsServer2D::MotionResult &r_result, bool p_test_only = false, bool p_cancel_sliding = true); - bool test_move(const Transform2D &p_from, const Vector2 &p_distance, const Ref<KinematicCollision2D> &r_collision = Ref<KinematicCollision2D>(), real_t p_margin = 0.08); + bool test_move(const Transform2D &p_from, const Vector2 &p_distance, const Ref<KinematicCollision2D> &r_collision = Ref<KinematicCollision2D>(), real_t p_margin = 0.08, bool p_recovery_as_collision = false); TypedArray<PhysicsBody2D> get_collision_exceptions(); void add_collision_exception_with(Node *p_node); //must be physicsbody |