diff --git a/headers/enduro2d/high/_high.hpp b/headers/enduro2d/high/_high.hpp index 7f7fb218..c0e40ef4 100644 --- a/headers/enduro2d/high/_high.hpp +++ b/headers/enduro2d/high/_high.hpp @@ -46,7 +46,7 @@ namespace e2d class actor; class behaviour; class camera; - class box_collider; + class rect_collider; class circle_collider; class polygon_collider; template < typename C > diff --git a/headers/enduro2d/high/components/colliders.hpp b/headers/enduro2d/high/components/colliders.hpp index 4a468e36..83967a21 100644 --- a/headers/enduro2d/high/components/colliders.hpp +++ b/headers/enduro2d/high/components/colliders.hpp @@ -12,31 +12,59 @@ namespace e2d { - class box_collider final { + class rect_collider final { public: - box_collider() = default; + rect_collider() = default; + + rect_collider& size(const v2f& value) noexcept; + [[nodiscard]] const v2f& size() const noexcept; + + rect_collider& pivot(const v2f& value) noexcept; + [[nodiscard]] const v2f& pivot() const noexcept; + private: + v2f size_ = v2f::zero(); + v2f pivot_ = v2f(0.5f); }; class circle_collider final { public: circle_collider() = default; + + circle_collider& radius(f32 value) noexcept; + [[nodiscard]] f32 radius() const noexcept; + + circle_collider& pivot(const v2f& value) noexcept; + [[nodiscard]] const v2f& pivot() const noexcept; + private: + f32 radius_ = 0.f; + v2f pivot_ = v2f(0.5f); }; class polygon_collider final { public: polygon_collider() = default; + + polygon_collider& points(vector value) noexcept; + [[nodiscard]] vector& points() noexcept; + [[nodiscard]] const vector& points() const noexcept; + + polygon_collider& pivot(const v2f& value) noexcept; + [[nodiscard]] const v2f& pivot() const noexcept; + private: + vector points_; + v2f pivot_ = v2f(0.5f); }; } namespace e2d { template <> - class factory_loader final : factory_loader<> { + class factory_loader final : factory_loader<> { public: static const char* schema_source; bool operator()( - box_collider& component, + rect_collider& component, const fill_context& ctx) const; bool operator()( @@ -72,3 +100,70 @@ namespace e2d const collect_context& ctx) const; }; } + +namespace e2d +{ + inline rect_collider& rect_collider::size(const v2f& value) noexcept { + size_ = value; + return *this; + } + + inline const v2f& rect_collider::size() const noexcept { + return size_; + } + + inline rect_collider& rect_collider::pivot(const v2f& value) noexcept { + pivot_ = value; + return *this; + } + + inline const v2f& rect_collider::pivot() const noexcept { + return pivot_; + } +} + +namespace e2d +{ + inline circle_collider& circle_collider::radius(f32 value) noexcept { + radius_ = value; + return *this; + } + + inline f32 circle_collider::radius() const noexcept { + return radius_; + } + + inline circle_collider& circle_collider::pivot(const v2f& value) noexcept { + pivot_ = value; + return *this; + } + + inline const v2f& circle_collider::pivot() const noexcept { + return pivot_; + } +} + +namespace e2d +{ + inline polygon_collider& polygon_collider::points(vector value) noexcept { + points_ = std::move(value); + return *this; + } + + inline vector& polygon_collider::points() noexcept { + return points_; + } + + inline const vector& polygon_collider::points() const noexcept { + return points_; + } + + inline polygon_collider& polygon_collider::pivot(const v2f& value) noexcept { + pivot_ = value; + return *this; + } + + inline const v2f& polygon_collider::pivot() const noexcept { + return pivot_; + } +} diff --git a/samples/bin/library/scripts/emmy/components/colliders.lua b/samples/bin/library/scripts/emmy/components/colliders.lua index 0dfdfae4..11c050d7 100644 --- a/samples/bin/library/scripts/emmy/components/colliders.lua +++ b/samples/bin/library/scripts/emmy/components/colliders.lua @@ -1,17 +1,32 @@ ----@class box_collider -local box_collider = { +---@class rect_collider +local rect_collider = { + ---@type v2f + size = v2f.zero(), + + ---@type v2f + pivot = v2f.new(0.5) } ---@class circle_collider local circle_collider = { + ---@type number + radius = 0, + + ---@type v2f + pivot = v2f.new(0.5) } ---@class polygon_collider local polygon_collider = { + ---@type v2f[] + points = {}, + + ---@type v2f + pivot = v2f.new(0.5) } ----@type box_collider -_G.box_collider = _G.box_collider or box_collider +---@type rect_collider +_G.rect_collider = _G.rect_collider or rect_collider ---@type circle_collider _G.circle_collider = _G.circle_collider or circle_collider diff --git a/samples/bin/library/scripts/emmy/high/gobject.lua b/samples/bin/library/scripts/emmy/high/gobject.lua index a50eeef5..c15f3d06 100644 --- a/samples/bin/library/scripts/emmy/high/gobject.lua +++ b/samples/bin/library/scripts/emmy/high/gobject.lua @@ -15,8 +15,8 @@ local gobject = { ---@type camera camera = nil, - ---@type box_collider - box_collider = nil, + ---@type rect_collider + rect_collider = nil, ---@type circle_collider circle_collider = nil, diff --git a/sources/enduro2d/high/bindings/high_binds/components/colliders_binds.cpp b/sources/enduro2d/high/bindings/high_binds/components/colliders_binds.cpp index 80e6ff71..0046aca7 100644 --- a/sources/enduro2d/high/bindings/high_binds/components/colliders_binds.cpp +++ b/sources/enduro2d/high/bindings/high_binds/components/colliders_binds.cpp @@ -8,26 +8,177 @@ #include #include +#include namespace { using namespace e2d; - void bind_box_collider(sol::state& l) { - l.new_usertype>("box_collider", - sol::no_constructor + void bind_rect_collider(sol::state& l) { + l.new_usertype>("rect_collider", + sol::no_constructor, + + "enable", [](gcomponent& c){ + c.owner().component>().remove(); + }, + + "disable", [](gcomponent& c){ + c.owner().component>().ensure(); + }, + + "enabled", sol::property( + [](const gcomponent& c) -> bool { + return !c.owner().component>().exists(); + }, + [](gcomponent& c, bool yesno){ + if ( yesno ) { + c.owner().component>().remove(); + } else { + c.owner().component>().ensure(); + } + } + ), + + "disabled", sol::property( + [](const gcomponent& c) -> bool { + return c.owner().component>().exists(); + }, + [](gcomponent& c, bool yesno){ + if ( yesno ) { + c.owner().component>().ensure(); + } else { + c.owner().component>().remove(); + } + } + ), + + "size", sol::property( + [](const gcomponent& c) -> v2f { + return c->size(); + }, + [](gcomponent& c, const v2f& v){ + c->size(v); + }), + + "pivot", sol::property( + [](const gcomponent& c) -> v2f { + return c->pivot(); + }, + [](gcomponent& c, const v2f& v){ + c->pivot(v); + }) ); } void bind_circle_collider(sol::state& l) { l.new_usertype>("circle_collider", - sol::no_constructor + sol::no_constructor, + + "enable", [](gcomponent& c){ + c.owner().component>().remove(); + }, + + "disable", [](gcomponent& c){ + c.owner().component>().ensure(); + }, + + "enabled", sol::property( + [](const gcomponent& c) -> bool { + return !c.owner().component>().exists(); + }, + [](gcomponent& c, bool yesno){ + if ( yesno ) { + c.owner().component>().remove(); + } else { + c.owner().component>().ensure(); + } + } + ), + + "disabled", sol::property( + [](const gcomponent& c) -> bool { + return c.owner().component>().exists(); + }, + [](gcomponent& c, bool yesno){ + if ( yesno ) { + c.owner().component>().ensure(); + } else { + c.owner().component>().remove(); + } + } + ), + + "radius", sol::property( + [](const gcomponent& c) -> f32 { + return c->radius(); + }, + [](gcomponent& c, f32 v){ + c->radius(v); + }), + + "pivot", sol::property( + [](const gcomponent& c) -> v2f { + return c->pivot(); + }, + [](gcomponent& c, const v2f& v){ + c->pivot(v); + }) ); } void bind_polygon_collider(sol::state& l) { l.new_usertype>("polygon_collider", - sol::no_constructor + sol::no_constructor, + + "enable", [](gcomponent& c){ + c.owner().component>().remove(); + }, + + "disable", [](gcomponent& c){ + c.owner().component>().ensure(); + }, + + "enabled", sol::property( + [](const gcomponent& c) -> bool { + return !c.owner().component>().exists(); + }, + [](gcomponent& c, bool yesno){ + if ( yesno ) { + c.owner().component>().remove(); + } else { + c.owner().component>().ensure(); + } + } + ), + + "disabled", sol::property( + [](const gcomponent& c) -> bool { + return c.owner().component>().exists(); + }, + [](gcomponent& c, bool yesno){ + if ( yesno ) { + c.owner().component>().ensure(); + } else { + c.owner().component>().remove(); + } + } + ), + + "points", sol::property( + [](const gcomponent& c) -> vector { + return c->points(); + }, + [](gcomponent& c, vector v){ + c->points(std::move(v)); + }), + + "pivot", sol::property( + [](const gcomponent& c) -> v2f { + return c->pivot(); + }, + [](gcomponent& c, const v2f& v){ + c->pivot(v); + }) ); } } @@ -35,7 +186,7 @@ namespace namespace e2d::bindings::high { void bind_colliders(sol::state& l) { - bind_box_collider(l); + bind_rect_collider(l); bind_circle_collider(l); bind_polygon_collider(l); } diff --git a/sources/enduro2d/high/bindings/high_binds/gobject_binds.cpp b/sources/enduro2d/high/bindings/high_binds/gobject_binds.cpp index f3bb9b5f..bf8e8c28 100644 --- a/sources/enduro2d/high/bindings/high_binds/gobject_binds.cpp +++ b/sources/enduro2d/high/bindings/high_binds/gobject_binds.cpp @@ -42,7 +42,7 @@ namespace e2d::bindings::high "actor", sol::property([](gobject& go){ return component_wrapper{go}; }), "behaviour", sol::property([](gobject& go){ return component_wrapper{go}; }), "camera", sol::property([](gobject& go){ return component_wrapper{go}; }), - "box_collider", sol::property([](gobject& go){ return component_wrapper{go}; }), + "rect_collider", sol::property([](gobject& go){ return component_wrapper{go}; }), "circle_collider", sol::property([](gobject& go){ return component_wrapper{go}; }), "polygon_collider", sol::property([](gobject& go){ return component_wrapper{go}; }), "flipbook_player", sol::property([](gobject& go){ return component_wrapper{go}; }), diff --git a/sources/enduro2d/high/components/colliders.cpp b/sources/enduro2d/high/components/colliders.cpp index a0bac18c..65249cbb 100644 --- a/sources/enduro2d/high/components/colliders.cpp +++ b/sources/enduro2d/high/components/colliders.cpp @@ -8,23 +8,42 @@ namespace e2d { - const char* factory_loader::schema_source = R"json({ + const char* factory_loader::schema_source = R"json({ "type" : "object", "required" : [], "additionalProperties" : false, "properties" : { + "size" : { "$ref": "#/common_definitions/v2" }, + "pivot" : { "$ref": "#/common_definitions/v2" } } })json"; - bool factory_loader::operator()( - box_collider& component, + bool factory_loader::operator()( + rect_collider& component, const fill_context& ctx) const { - E2D_UNUSED(component, ctx); + if ( ctx.root.HasMember("size") ) { + v2f size = component.size(); + if ( !json_utils::try_parse_value(ctx.root["size"], size) ) { + the().error("RECT_COLLIDER: Incorrect formatting of 'size' property"); + return false; + } + component.size(size); + } + + if ( ctx.root.HasMember("pivot") ) { + v2f pivot = component.pivot(); + if ( !json_utils::try_parse_value(ctx.root["pivot"], pivot) ) { + the().error("RECT_COLLIDER: Incorrect formatting of 'pivot' property"); + return false; + } + component.pivot(pivot); + } + return true; } - bool factory_loader::operator()( + bool factory_loader::operator()( asset_dependencies& dependencies, const collect_context& ctx) const { @@ -41,6 +60,8 @@ namespace e2d "required" : [], "additionalProperties" : false, "properties" : { + "radius" : { "type" : "number" }, + "pivot" : { "$ref": "#/common_definitions/v2" } } })json"; @@ -48,7 +69,24 @@ namespace e2d circle_collider& component, const fill_context& ctx) const { - E2D_UNUSED(component, ctx); + if ( ctx.root.HasMember("radius") ) { + f32 radius = component.radius(); + if ( !json_utils::try_parse_value(ctx.root["radius"], radius) ) { + the().error("CIRCLE_COLLIDER: Incorrect formatting of 'radius' property"); + return false; + } + component.radius(radius); + } + + if ( ctx.root.HasMember("pivot") ) { + v2f pivot = component.pivot(); + if ( !json_utils::try_parse_value(ctx.root["pivot"], pivot) ) { + the().error("CIRCLE_COLLIDER: Incorrect formatting of 'pivot' property"); + return false; + } + component.pivot(pivot); + } + return true; } @@ -68,6 +106,14 @@ namespace e2d "required" : [], "additionalProperties" : false, "properties" : { + "points" : { "$ref": "#/definitions/points" }, + "pivot" : { "$ref": "#/common_definitions/v2" } + }, + "definitions" : { + "points" : { + "type" : "array", + "items" : { "$ref": "#/common_definitions/v2" } + } } })json"; @@ -75,7 +121,24 @@ namespace e2d polygon_collider& component, const fill_context& ctx) const { - E2D_UNUSED(component, ctx); + if ( ctx.root.HasMember("points") ) { + vector points = component.points(); + if ( !json_utils::try_parse_value(ctx.root["points"], points) ) { + the().error("POLYGON_COLLIDER: Incorrect formatting of 'points' property"); + return false; + } + component.points(std::move(points)); + } + + if ( ctx.root.HasMember("pivot") ) { + v2f pivot = component.pivot(); + if ( !json_utils::try_parse_value(ctx.root["pivot"], pivot) ) { + the().error("POLYGON_COLLIDER: Incorrect formatting of 'pivot' property"); + return false; + } + component.pivot(pivot); + } + return true; } diff --git a/sources/enduro2d/high/starter.cpp b/sources/enduro2d/high/starter.cpp index 29b018b1..7d5f637d 100644 --- a/sources/enduro2d/high/starter.cpp +++ b/sources/enduro2d/high/starter.cpp @@ -182,7 +182,7 @@ namespace e2d .register_component("actor") .register_component("behaviour") .register_component("camera") - .register_component("box_collider") + .register_component("rect_collider") .register_component("circle_collider") .register_component("polygon_collider") .register_component("flipbook_player")