From 6610b847b86c30132da9fb533190cd8fe69f7335 Mon Sep 17 00:00:00 2001 From: Sara Date: Wed, 8 Jan 2025 16:42:38 +0100 Subject: [PATCH] feat: added viewport transformation --- src/core/assets/asset_db.cpp | 1 + src/core/canvas_engine.cpp | 6 +++++- src/core/canvas_engine.hpp | 13 +++++++------ src/core/collidable_node.cpp | 22 ++++++++++++++++++++++ src/core/collidable_node.hpp | 9 +++++++++ src/core/collision_shape.cpp | 35 ++++++++++++++++++++++++----------- src/core/collision_shape.hpp | 20 ++++++++++---------- src/core/level.cpp | 22 +++++++++++++++++++++- src/core/level.hpp | 8 ++++++++ src/core/math/transform.cpp | 24 ++++++++++++++++++++---- src/core/math/transform.hpp | 4 ++++ src/core/math/vector.cpp | 5 ++++- src/core/math/vector.hpp | 3 +++ src/core/node.cpp | 30 +++++++++++++++++++++++++----- src/core/node.hpp | 16 ++++++++++++---- src/core/node2d.cpp | 4 ++-- src/core/node2d.hpp | 2 +- src/core/sprite.cpp | 13 ++++++++----- src/core/sprite.hpp | 2 +- src/level_1.cpp | 15 ++++++++++----- src/main.cpp | 3 ++- src/player.cpp | 16 ++++++++++++++++ src/player.hpp | 19 +++++++++++++++++++ src/test_node.cpp | 5 ++--- src/test_node.hpp | 8 +++++--- 25 files changed, 241 insertions(+), 64 deletions(-) create mode 100644 src/player.cpp create mode 100644 src/player.hpp diff --git a/src/core/assets/asset_db.cpp b/src/core/assets/asset_db.cpp index 537d7a0..6fbc03e 100644 --- a/src/core/assets/asset_db.cpp +++ b/src/core/assets/asset_db.cpp @@ -31,6 +31,7 @@ void AssetDB::load(std::string asset_name) { void AssetDB::index_assets() { SDL_Log("Indexing assets"); for(std::filesystem::directory_entry const &itr : std::filesystem::recursive_directory_iterator("resources")) { + SDL_Log("Indexing %s", itr.path().c_str()); if(itr.is_directory()) continue; else if(!itr.path().has_extension()) diff --git a/src/core/canvas_engine.cpp b/src/core/canvas_engine.cpp index 21e74ec..6150458 100644 --- a/src/core/canvas_engine.cpp +++ b/src/core/canvas_engine.cpp @@ -99,6 +99,10 @@ AssetDB &CanvasEngine::get_assets() { return this->assets; } +CollisionWorld &CanvasEngine::get_collision_world() { + return this->collision_world; +} + InputMap &CanvasEngine::get_input_map() { return this->input_map; } @@ -132,7 +136,7 @@ void CanvasEngine::process_event(SDL_Event const &evt) { void CanvasEngine::tick(double delta_time) { this->level->propagate_tick(delta_time); - this->physics_world.check_collisions(); + this->collision_world.check_collisions(); } void CanvasEngine::draw(SDL_Renderer *render) { diff --git a/src/core/canvas_engine.hpp b/src/core/canvas_engine.hpp index bad6013..a7481ec 100644 --- a/src/core/canvas_engine.hpp +++ b/src/core/canvas_engine.hpp @@ -1,17 +1,17 @@ #ifndef CANVAS_ENGINE_HPP #define CANVAS_ENGINE_HPP +#include "assets/asset_db.hpp" #include "core/collision.hpp" #include "core/level.hpp" -#include "node.hpp" -#include "assets/asset_db.hpp" #include "input/input_map.hpp" -#include -#include -#include +#include "node.hpp" #include #include #include +#include +#include +#include #include namespace ce { @@ -22,7 +22,7 @@ private: SDL_Renderer *render{nullptr}; //!< primary application window's renderer SDL_Texture *render_target{nullptr}; AssetDB assets{}; - CollisionWorld physics_world{}; + CollisionWorld collision_world{}; InputMap input_map{}; //!< map of inputs to input callback objects std::unique_ptr level; Uint64 last_frame_start_time{}; //!< time at start of last frame @@ -42,6 +42,7 @@ public: void request_close(); void set_target_delta_time(double target); AssetDB &get_assets(); + CollisionWorld &get_collision_world(); InputMap &get_input_map(); SDL_Renderer *get_render(); private: diff --git a/src/core/collidable_node.cpp b/src/core/collidable_node.cpp index 1ca328b..b2beab3 100644 --- a/src/core/collidable_node.cpp +++ b/src/core/collidable_node.cpp @@ -2,6 +2,12 @@ #include "collision_shape.hpp" namespace ce { +CollidableNode::CollidableNode(std::string const &name, CollisionMask layers, CollisionMask mask) +: ce::Node2D(name) { + this->layers = layers; + this->mask = mask; +} + void CollidableNode::_tick(double const &delta) { // find nodes that were overlapping last frame but not this frame std::map::iterator iterator{this->overlapped_nodes.begin()}; @@ -23,4 +29,20 @@ void CollidableNode::add_overlap(CollisionShape *shape, CollisionShape *other_sh this->shape_overlaps.insert(other_shape); ++this->overlapped_nodes[other_shape->get_owner()]; } + +void CollidableNode::set_mask(CollisionMask mask) { + this->mask = mask; +} + +CollisionMask CollidableNode::get_mask() const { + return this->mask; +} + +void CollidableNode::set_layers(CollisionMask layers) { + this->layers = layers; +} + +CollisionMask CollidableNode::get_layers() const { + return this->layers; +} } diff --git a/src/core/collidable_node.hpp b/src/core/collidable_node.hpp index c576d4f..6fc81a6 100644 --- a/src/core/collidable_node.hpp +++ b/src/core/collidable_node.hpp @@ -7,18 +7,27 @@ #include namespace ce { +typedef uint64_t CollisionMask; class CollisionShape; class CollidableNode : public Node2D { std::set shape_overlaps{}; std::map overlapped_nodes{}; + CollisionMask mask{~0x0u /* all layers by default */}; + CollisionMask layers{0x1u /* only the first layer is enabled by default */}; public: // collision(local_shape, other_node, other_shape) Signal overlap_enter{}; Signal overlap_exit{}; public: + CollidableNode(std::string const &name, CollisionMask layers, CollisionMask mask); virtual void _tick(double const &delta) override; void add_overlap(CollisionShape *shape, CollisionShape *other); + + void set_mask(CollisionMask mask); + CollisionMask get_mask() const; + void set_layers(CollisionMask layers); + CollisionMask get_layers() const; }; }; diff --git a/src/core/collision_shape.cpp b/src/core/collision_shape.cpp index ff2a3bc..a1ca256 100644 --- a/src/core/collision_shape.cpp +++ b/src/core/collision_shape.cpp @@ -1,5 +1,6 @@ #include "collision_shape.hpp" #include "collidable_node.hpp" +#include "core/canvas_engine.hpp" #include #include @@ -24,14 +25,17 @@ Shape Shape::make_box(float h_extent, float v_extent) { } CollisionShape::CollisionShape(std::string const &name, Node *owner, Shape shape) -: Node2D(name) { +: Node2D(name) +, world{CanvasEngine::get_singleton()->get_collision_world()} { this->shape = shape; } -void CollisionShape::_added(Node *parent) { +void CollisionShape::_added() { + Node *parent{this->get_parent()}; while(parent != nullptr) { if(CollidableNode *as_collidable{dynamic_cast(parent)}) { this->owner = as_collidable; + this->register_with_world(); return; } } @@ -39,13 +43,20 @@ void CollisionShape::_added(Node *parent) { #ifdef DEBUG abort(); #endif + if(this->is_registered) + this->deregister_with_world(); +} + +void CollisionShape::_removed() { + if(this->is_registered) + this->deregister_with_world(); } bool CollisionShape::can_collide(CollisionShape const *lhs, CollisionShape const *rhs) { return lhs->owner != nullptr && rhs->owner != nullptr && lhs->owner != rhs->owner - && ((lhs->mask & rhs->layers) != 0x0u - || (rhs->mask & lhs->layers) != 0x0u); + && ((lhs->get_mask() & rhs->get_layers()) != 0x0u + || (rhs->get_mask() & lhs->get_layers()) != 0x0u); } bool CollisionShape::shapes_overlap(CollisionShape const *lhs, CollisionShape const *rhs) { @@ -110,19 +121,21 @@ Shape const &CollisionShape::get_shape() const { return this->shape; } -void CollisionShape::set_mask(CollisionMask mask) { - this->mask = mask; +CollisionMask CollisionShape::get_layers() const { + return this->owner ? this->owner->get_layers() : 0x0u; } CollisionMask CollisionShape::get_mask() const { - return this->mask; + return this->owner ? this->owner->get_mask() : 0x0u; } -void CollisionShape::set_layers(CollisionMask layers) { - this->layers = layers; +void CollisionShape::register_with_world() { + this->world.add_collision_shape(this); + this->is_registered = true; } -CollisionMask CollisionShape::get_layers() const { - return this->layers; +void CollisionShape::deregister_with_world() { + this->world.remove_collision_shape(this); + this->is_registered = false; } } diff --git a/src/core/collision_shape.hpp b/src/core/collision_shape.hpp index dad4f10..2debd46 100644 --- a/src/core/collision_shape.hpp +++ b/src/core/collision_shape.hpp @@ -1,13 +1,12 @@ #ifndef COLLISION_SHAPE_HPP #define COLLISION_SHAPE_HPP -#include "core/math/transform.hpp" +#include "collidable_node.hpp" +#include "math/transform.hpp" #include "node2d.hpp" namespace ce { -class CollidableNode; class CollisionWorld; -typedef uint64_t CollisionMask; struct ShapeCircle { float radius; }; struct ShapeAABB { float h_extent, v_extent; }; @@ -27,13 +26,13 @@ struct Shape { class CollisionShape : public Node2D { CollidableNode *owner{nullptr}; Shape shape{.shape=Shape::CIRCLE, .circle={.radius=1.f}}; - CollisionWorld *world{nullptr}; - CollisionMask mask{~0x0u /* all layers by default */}; - CollisionMask layers{0x1u /* only the first layer is enabled by default */}; + CollisionWorld &world; + bool is_registered{false}; public: CollisionShape(std::string const &name, Node *owner, Shape shape); - virtual void _added(Node *parent) override; + virtual void _added() override; + virtual void _removed() override; static bool can_collide(CollisionShape const *lhs, CollisionShape const *rhs); static bool shapes_overlap(CollisionShape const *lhs, CollisionShape const *rhs); @@ -44,10 +43,11 @@ public: CollidableNode *get_owner() const; void set_shape(Shape const &shape); Shape const &get_shape() const; - void set_mask(CollisionMask mask); - CollisionMask get_mask() const; - void set_layers(CollisionMask layers); CollisionMask get_layers() const; + CollisionMask get_mask() const; +private: + void register_with_world(); + void deregister_with_world(); }; } diff --git a/src/core/level.cpp b/src/core/level.cpp index 14948a9..1b1526f 100644 --- a/src/core/level.cpp +++ b/src/core/level.cpp @@ -1,12 +1,32 @@ #include "level.hpp" +#include "core/math/transform.hpp" +#include +#include +#include namespace ce { +void Level::deinstantiate() { + this->root.reset(); +} + void Level::propagate_tick(double const &delta_time) { this->root->propagate_tick(delta_time); } void Level::propagate_draw(SDL_Renderer *render) { - this->root->propagate_draw(render); + int w, h; + SDL_Window *window{SDL_RenderGetWindow(render)}; + SDL_GetWindowSize(window, &w, &h); + ce::Transform const screen_transform{ + .position = ce::Vecf::ZERO, + .rotation = 0.f, + .scale = ce::Vecf::ONE * float(w), + }; + float const ratio{float(h)/float(w)}; + this->root->propagate_draw(render, Transform().translated({ + 0.5f / this->view_transform.scale.x, + 0.5f / this->view_transform.scale.y * ratio + }) * this->view_transform * screen_transform); } Node *Level::get_root() { diff --git a/src/core/level.hpp b/src/core/level.hpp index 4c40ee2..d7fd0d3 100644 --- a/src/core/level.hpp +++ b/src/core/level.hpp @@ -7,14 +7,22 @@ namespace ce { class Level { protected: Node::OwnedPtr root{nullptr}; + ce::Transform view_transform{ + .position = ce::Vecf::ZERO, + .rotation = 0.f, + .scale = {1.f/10.f, 1.f/10.f}, + }; public: virtual ~Level() = default; virtual void instantiate() = 0; + void deinstantiate(); void propagate_tick(double const &delta_time); void propagate_draw(SDL_Renderer *render); Node *get_root(); bool is_instantiated() const; + void set_view_transform(ce::Transform transform); + ce::Transform get_view_transform() const; protected: Node::OwnedPtr &get_owned_root(); }; diff --git a/src/core/math/transform.cpp b/src/core/math/transform.cpp index 92c5e55..ddbebc8 100644 --- a/src/core/math/transform.cpp +++ b/src/core/math/transform.cpp @@ -14,6 +14,24 @@ void Transform::scale_by(Vecf const &factors) { this->scale.scale(factors); } +Transform Transform::translated(Vecf const &translation) const { + Transform out{*this}; + out.translate_by(translation); + return out; +} + +Transform Transform::rotated(float rotation) const { + Transform out{*this}; + out.rotate_by(rotation); + return out; +} + +Transform Transform::scaled(Vecf const &factors) const { + Transform out{*this}; + out.scale_by(factors); + return out; +} + Vecf Transform::right() const { return Vecf::RIGHT.rotated(this->rotation); } @@ -24,7 +42,7 @@ Vecf Transform::up() const { Transform operator *(Transform const &lhs, Transform const &rhs) { Transform t{ - .position = rhs.position + lhs.position.rotated(rhs.rotation), + .position = rhs.position + lhs.position.rotated(rhs.rotation).scaled(rhs.scale), .rotation = rhs.rotation + lhs.rotation, .scale = lhs.scale.scaled(rhs.scale) }; @@ -33,9 +51,7 @@ Transform operator *(Transform const &lhs, Transform const &rhs) { } Transform &operator *=(Transform &lhs, Transform const &rhs) { - lhs.position += lhs.position.rotated(rhs.rotation); - lhs.rotation += rhs.rotation; - lhs.scale.scale(rhs.scale); + lhs = lhs * rhs; assert(lhs.scale.x != 0.f || lhs.scale.y != 0.f); // !!! return lhs; } diff --git a/src/core/math/transform.hpp b/src/core/math/transform.hpp index 049298a..7418d5b 100644 --- a/src/core/math/transform.hpp +++ b/src/core/math/transform.hpp @@ -8,9 +8,13 @@ struct Transform { Vecf position{0.f, 0.f}; double rotation{0.0}; Vecf scale{1.f, 1.f}; + void translate_by(Vecf const &translation); void rotate_by(double rotation); void scale_by(Vecf const &factors); + Transform translated(Vecf const &translation) const; + Transform rotated(float rotation) const; + Transform scaled(Vecf const &factors) const; Vecf right() const; Vecf up() const; diff --git a/src/core/math/vector.cpp b/src/core/math/vector.cpp index 9d518fd..f6a8cc5 100644 --- a/src/core/math/vector.cpp +++ b/src/core/math/vector.cpp @@ -80,9 +80,12 @@ void Vecf::scale(Vecf const &factors) { } Vecf Vecf::scaled(Vecf const &factors) const { - return Vecf(this->x * factors.x, this->y * factors.y); + return Vecf{this->x * factors.x, this->y * factors.y}; } Vecf const Vecf::RIGHT{1.f, 0.f}; Vecf const Vecf::UP{0.f, 1.f}; +Vecf const Vecf::ONE{1.f, 1.f}; +Vecf const Vecf::ZERO{0.f, 0.f}; +Vecf const Vecf::POSITIVE_INFINITY{INFINITY, INFINITY}; } diff --git a/src/core/math/vector.hpp b/src/core/math/vector.hpp index 96672d9..a299ad9 100644 --- a/src/core/math/vector.hpp +++ b/src/core/math/vector.hpp @@ -45,6 +45,9 @@ struct Vecf { static Vecf const RIGHT; static Vecf const UP; + static Vecf const ONE; + static Vecf const POSITIVE_INFINITY; + static Vecf const ZERO; }; static inline diff --git a/src/core/node.cpp b/src/core/node.cpp index 976b66b..3efdbd2 100644 --- a/src/core/node.cpp +++ b/src/core/node.cpp @@ -1,6 +1,7 @@ #include "node.hpp" #include #include +#include #include #include @@ -16,7 +17,7 @@ void Node::add_child(Node::OwnedPtr &child) { Node *added{this->children.insert({child->get_name(), std::move(child)}).first->second.get()}; added->parent = this; this->child_added.invoke(added); - added->_added(this); + added->propagate_added(); } // specialize to skip dynamic_cast template <> Node *Node::get_child(std::string const &name) { @@ -68,6 +69,19 @@ bool Node::is_ticking() const { return this->tick; } +ce::Level *Node::get_level() const { + return this->level; +} + +void Node::set_level(ce::Level *level) { + // parent level needs to match + assert(this->parent == nullptr || this->parent->get_level() == level); + this->level = level; + for(std::pair> &pair : this->children) { + pair.second->set_level(level); + } +} + std::optional Node::remove_child(Node *node) { if(this != node->get_parent()) return std::nullopt; @@ -84,7 +98,7 @@ std::optional Node::remove_child(Node *node) { Node::OwnedPtr owned{std::move(child->second)}; this->children.erase(child); // notify both former child and any listeners that the child has been removed - owned->_removed(); + owned->propagate_removed(); this->child_removed.invoke(child->second.get()); // return optional containing owned pointer to former child return std::optional(std::move(owned)); @@ -117,18 +131,24 @@ void Node::propagate_post_tick() { pair.second->propagate_post_tick(); } +void Node::propagate_added() { + this->_added(); + for(std::pair &pair : this->children) + pair.second->propagate_added(); +} + void Node::propagate_removed() { for(std::pair &pair : this->children) pair.second->propagate_removed(); this->_removed(); } -void Node::propagate_draw(SDL_Renderer *render) { +void Node::propagate_draw(SDL_Renderer *render, ce::Transform const &view_transform) { this->_update_transform(); if(this->visible) { - this->_draw(render); + this->_draw(render, view_transform); for(std::pair &pair : this->children) - pair.second->propagate_draw(render); + pair.second->propagate_draw(render, view_transform); } } diff --git a/src/core/node.hpp b/src/core/node.hpp index ae951d7..8bd3c2b 100644 --- a/src/core/node.hpp +++ b/src/core/node.hpp @@ -1,14 +1,17 @@ #ifndef CANVAS_NODE_HPP #define CANVAS_NODE_HPP +#include "core/math/transform.hpp" #include "core/signal.hpp" -#include #include +#include #include #include struct SDL_Renderer; namespace ce { +class Level; + class Node { public: friend class Level; @@ -22,6 +25,7 @@ private: ChildrenMap children{}; bool visible{true}; bool tick{true}; + ce::Level *level{nullptr}; public: Signal<> destroyed{}; //!< Signal invoked by the destructor Signal child_removed{}; //!< Signal invoked when a child is removed. @@ -30,11 +34,11 @@ public: Node(std::string name); virtual ~Node(); protected: - virtual void _added(Node *parent [[maybe_unused]]) {} //!< called the moment after the object is added as a child to another node + virtual void _added() {} //!< called the moment after the object is added as a child to another node virtual void _first_tick() {} //!< called the first frame this object is active virtual void _tick(double const &delta_time [[maybe_unused]]) {} //!< called every frame virtual void _removed() {} //!< called the moment before the object is removed as a child to another node - virtual void _draw(SDL_Renderer *render [[maybe_unused]]) {} + virtual void _draw(SDL_Renderer *render [[maybe_unused]], ce::Transform const &view_transform [[maybe_unused]]) {} virtual void _update_transform() {} public: template TNode *get_child(std::string const &name); //!< get a non-owning pointer to a child @@ -50,18 +54,22 @@ public: bool is_visible() const; void set_tick(bool value); bool is_ticking() const; + ce::Level *get_level() const; private: + void set_level(ce::Level *level); std::optional remove_child(Node *child); //!< remove a child, the caller now owns the pointer void propagate_tick(double const &delta_time); void propagate_post_tick(); + void propagate_added(); void propagate_removed(); - void propagate_draw(SDL_Renderer *render); + void propagate_draw(SDL_Renderer *render, ce::Transform const &view_transform); bool rename_child(std::string const &old_name, std::string const &new_name); }; template TNode *Node::get_child(std::string const &name) { return children.contains(name) ? dynamic_cast(children.at(name).get()) : nullptr; } + template TNode *Node::create_child(Args... cargs) { OwnedPtr owned{std::make_unique(cargs...)}; TNode *referenced{dynamic_cast(owned.get())}; diff --git a/src/core/node2d.cpp b/src/core/node2d.cpp index d87eb14..aa9b9ce 100644 --- a/src/core/node2d.cpp +++ b/src/core/node2d.cpp @@ -4,8 +4,8 @@ namespace ce { Node2D::Node2D(std::string name) : Node(name) {} -void Node2D::_added(Node *parent) { - this->parent_node2d = dynamic_cast(parent); +void Node2D::_added() { + this->parent_node2d = dynamic_cast(this->get_parent()); } void Node2D::_update_transform() { diff --git a/src/core/node2d.hpp b/src/core/node2d.hpp index 0037cc6..bb2c306 100644 --- a/src/core/node2d.hpp +++ b/src/core/node2d.hpp @@ -11,7 +11,7 @@ class Node2D : public Node { Node2D *parent_node2d{nullptr}; public: Node2D(std::string name); - virtual void _added(Node *parent) override; + virtual void _added() override; Node2D *get_parent_node2d() const; virtual void _update_transform() override; void set_transform(Transform const &transform); diff --git a/src/core/sprite.cpp b/src/core/sprite.cpp index 9243065..838505f 100644 --- a/src/core/sprite.cpp +++ b/src/core/sprite.cpp @@ -2,16 +2,18 @@ #include "core/canvas_engine.hpp" #include "core/math/transform.hpp" #include +#include #include namespace ce { Sprite::Sprite(std::string name, std::string texture) : Node2D(name) { - std::optional> asset = CanvasEngine::get_singleton()->get_assets().get_asset(texture); - this->texture = asset.value(); + std::optional> asset{CanvasEngine::get_singleton()->get_assets().get_asset(texture)}; + if(asset.has_value()) + this->texture = asset.value(); } -void Sprite::_draw(SDL_Renderer *render) { +void Sprite::_draw(SDL_Renderer *render, ce::Transform const &view_transform) { if(this->texture == nullptr) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "No texture assigned"); this->set_visible(false); @@ -19,9 +21,10 @@ void Sprite::_draw(SDL_Renderer *render) { } int w, h; SDL_QueryTexture(this->texture->get(), NULL, NULL, &w, &h); - Transform transform{this->get_global_transform()}; + Transform transform{this->get_global_transform() * view_transform}; assert(transform.scale.x != 0 && transform.scale.y != 0); // !!! - float fw{w * transform.scale.x}, fh{h * transform.scale.y}; + float fw{transform.scale.x * (w > h ? float(w) / float(h) : 1.f)}; + float fh{transform.scale.y * (w < h ? float(h) / float(w) : 1.f)}; assert(fw != 0.f && fh != 0.f); //float fw(w), fh(h); SDL_Rect src{0, 0, w, h}; diff --git a/src/core/sprite.hpp b/src/core/sprite.hpp index 16d5ae1..8b294e0 100644 --- a/src/core/sprite.hpp +++ b/src/core/sprite.hpp @@ -9,7 +9,7 @@ class Sprite : public Node2D { std::shared_ptr texture{nullptr}; public: Sprite(std::string name, std::string texture); - virtual void _draw(SDL_Renderer *render) override; + virtual void _draw(SDL_Renderer *render, ce::Transform const &view_transform) override; }; } diff --git a/src/level_1.cpp b/src/level_1.cpp index 8ad5e3a..f43293e 100644 --- a/src/level_1.cpp +++ b/src/level_1.cpp @@ -1,10 +1,15 @@ #include "level_1.hpp" #include "core/node.hpp" -#include "test_node.hpp" +#include "core/node2d.hpp" +#include "core/sprite.hpp" +#include "player.hpp" void Level1::instantiate() { - ce::Node::OwnedPtr &root_ptr{this->get_owned_root()}; - root_ptr.reset(new ce::Node("root")); - ce::Node::OwnedPtr node{std::make_unique()}; - root->add_child(node); + root.reset(new ce::Node2D("root")); + root->create_child("background", "background")->set_global_transform({ + .position = ce::Vecf::ZERO, + .rotation = 0.f, + .scale = ce::Vecf::ONE * 10.f + }); + root->create_child(); } diff --git a/src/main.cpp b/src/main.cpp index 6e45dcb..a96628c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,9 @@ #include "core/canvas_engine.hpp" #include "level_1.hpp" +ce::CanvasEngine engine{}; + int main(int argc [[maybe_unused]], char* argv [[maybe_unused]][]) { - ce::CanvasEngine engine{}; std::unique_ptr level{std::make_unique()}; engine.run(level); } diff --git a/src/player.cpp b/src/player.cpp new file mode 100644 index 0000000..76f1532 --- /dev/null +++ b/src/player.cpp @@ -0,0 +1,16 @@ +#include "player.hpp" +#include "core/collidable_node.hpp" +#include "core/collision_shape.hpp" +#include "core/math/transform.hpp" +#include "core/sprite.hpp" + +Player::Player() +: ce::CollidableNode("player", 0x1u, 0x1u) { + this->sprite = this->create_child("bike", "bike"); + this->shape = this->create_child("PlayerShape", this, ce::Shape::make_box(5.f, 10.f)); + ce::Transform trans{this->get_global_transform()}; + this->set_global_transform(trans); +} + +void Player::_tick(double const &delta) { +} diff --git a/src/player.hpp b/src/player.hpp new file mode 100644 index 0000000..9a2982a --- /dev/null +++ b/src/player.hpp @@ -0,0 +1,19 @@ +#ifndef PLAYER_HPP +#define PLAYER_HPP + +#include "core/collidable_node.hpp" + +namespace ce { +class CollisionShape; +class Sprite; +}; + +class Player : public ce::CollidableNode { + ce::CollisionShape *shape{nullptr}; + ce::Sprite *sprite{nullptr}; +public: + Player(); + virtual void _tick(double const &delta) override; +}; + +#endif // !PLAYER_HPP diff --git a/src/test_node.cpp b/src/test_node.cpp index 4f61595..9172ad8 100644 --- a/src/test_node.cpp +++ b/src/test_node.cpp @@ -5,7 +5,7 @@ #include TestNode::TestNode() -: ce::Node2D("TestNode") { +: ce::CollidableNode("TestNode", 0x1u, 0x1u) { this->sprite = this->create_child("neocat", "neocat"); } @@ -24,8 +24,7 @@ void TestNode::_tick(double const &delta) { this->set_transform(trans); } -void TestNode::_draw(SDL_Renderer *render) { - ce::Node2D::_draw(render); +void TestNode::_draw(SDL_Renderer *render, ce::Transform const &view_transform) { ce::Transform trans{this->get_global_transform()}; SDL_SetRenderDrawColor(render, 255, 255, 255, 255); SDL_FRect rect{trans.position.x-101.f, trans.position.y-101.f, 202.f, 202.f}; diff --git a/src/test_node.hpp b/src/test_node.hpp index 0803385..b1f20bb 100644 --- a/src/test_node.hpp +++ b/src/test_node.hpp @@ -1,17 +1,19 @@ #ifndef TEST_NODE_HPP #define TEST_NODE_HPP -#include "core/node2d.hpp" +#include "core/collidable_node.hpp" +#include "core/collision_shape.hpp" #include "core/sprite.hpp" -class TestNode : public ce::Node2D { +class TestNode : public ce::CollidableNode { private: ce::Sprite *sprite{nullptr}; + ce::CollisionShape *shape{nullptr}; public: TestNode(); virtual void _first_tick() override; virtual void _tick(double const &delta) override; - virtual void _draw(SDL_Renderer *render) override; + virtual void _draw(SDL_Renderer *render, ce::Transform const &view_transform) override; }; #endif // !TEST_NODE_HPP