SPARK  0.1.0
A general purpose game engine written in C++.
Loading...
Searching...
No Matches
Collider.h
1#pragma once
2
3#include "spark/core/Component.h"
4#include "spark/core/GameObject.h"
5#include "spark/core/components/Transform.h"
6
7#include "spark/math/Rectangle.h"
8#include "spark/math/Vector4.h"
9#include "spark/patterns/Signal.h"
10#include "spark/patterns/Traverser.h"
11#include "spark/rtti/HasRtti.h"
12
13#include "glm/gtc/matrix_transform.hpp"
14
15namespace spark::core::components
16{
21 class Collider : public Component
22 {
23 DECLARE_SPARK_RTTI(Collider, Component)
24 SPARK_ALLOW_PRIVATE_SERIALIZATION
25
26 public:
31 [[nodiscard]] math::Vector4<float> bounds() const
32 {
33 // Get the transform matrix of [0,0] of the rectangle
34 auto matrix = gameObject()->transform()->matrix();
35 matrix = glm::translate(matrix, {m_rectangle.position.x, m_rectangle.position.y, 0});
36
37 // Get the transform matrix of [3,3] of the rectangle
38 auto matrix4 = glm::translate(matrix, {m_rectangle.extent.x, m_rectangle.extent.y, 0});
39
40 // Return the bounds of the rectangle
41 return {matrix[3][0], matrix[3][1], matrix4[3][0], matrix4[3][1]};
42 }
43
49 [[nodiscard]] bool collidesWith(const Collider& other) const
50 {
51 const math::Vector4<float> this_bounds = bounds();
52 const math::Vector4<float> other_bounds = other.bounds();
53
54 // Check if the colliders are colliding using this formula:
55 // - x1 <= x2 + w2 && x1 + w1 >= x2 && y1 <= y2 + h2 && y1 + h1 >= y2)
56 if (this_bounds.x <= other_bounds.z && this_bounds.z >= other_bounds.x && this_bounds.y <= other_bounds.w && this_bounds.w >= other_bounds.y)
57 return true;
58 return false;
59 }
60
61 protected:
62 explicit Collider(GameObject* parent, math::Rectangle<float> rectangle)
63 : Component(parent), m_rectangle(std::move(rectangle)) {}
64
65 private:
66 math::Rectangle<float> m_rectangle;
67 };
68
72 class StaticCollider final : public Collider
73 {
74 DECLARE_SPARK_RTTI(StaticCollider, Collider)
75
76 public:
77 explicit StaticCollider(GameObject* parent)
78 : Collider(parent, {}) {}
79
80 explicit StaticCollider(GameObject* parent, math::Rectangle<float> rectangle)
81 : Collider(parent, std::move(rectangle)) {}
82 };
83
87 class DynamicCollider final : public Collider
88 {
89 DECLARE_SPARK_RTTI(DynamicCollider, Collider)
90
91 public:
94
95 public:
96 explicit DynamicCollider(GameObject* parent)
97 : Collider(parent, {}) {}
98
99 explicit DynamicCollider(GameObject* parent, math::Rectangle<float> rectangle)
100 : Collider(parent, std::move(rectangle)) {}
101
102 void onUpdate(float /*dt*/) override
103 {
104 // Check for collision with each collider and trigger the onCollision signal if a collision is detected
105 for (const auto* collider : allColliders())
106 if (collider != this)
107 if (collidesWith(*collider))
108 onCollision.emit(*collider);
109 }
110
111 private:
116 [[nodiscard]] std::vector<const Collider*> allColliders()
117 {
118 std::vector<const Collider*> colliders;
119 auto traverser = patterns::make_traverser<GameObject>([&](const GameObject* obj)
120 {
121 for (const auto* component : obj->components())
122 if (&component->rttiInstance() == &StaticCollider::classRtti() || &component->rttiInstance() == &DynamicCollider::classRtti())
123 colliders.push_back(static_cast<const Collider*>(component));
124 });
125 patterns::traverse_tree(gameObject()->root(), traverser);
126 return colliders;
127 }
128 };
129}
130
131IMPLEMENT_SPARK_RTTI(spark::core::components::Collider)
132
133IMPLEMENT_SPARK_RTTI(spark::core::components::StaticCollider)
134
A component that can be attached to a GameObject to provide additional functionality.
Definition Component.h:20
GameObject * gameObject()
Gets the GameObject that the component is attached to.
Definition Component.cpp:19
A GameObject is any object in the game. It contains a list of components that provides functionality ...
Definition GameObject.h:26
components::Transform * transform() const
Gets the transform component of the GameObject.
Definition GameObject.cpp:63
A component representing a square collider.
Definition Collider.h:22
bool collidesWith(const Collider &other) const
Checks if the collider is colliding with another collider.
Definition Collider.h:49
math::Vector4< float > bounds() const
Gets the bounds of the rectangle in screen space.
Definition Collider.h:31
A square collider that moves and checks for collisions with other colliders.
Definition Collider.h:88
void onUpdate(float) override
Method called on every frame.
Definition Collider.h:102
patterns::Signal< const Collider & > onCollision
Signal emitted when a collision is detected.
Definition Collider.h:93
A square collider that does not move and is only used for collision detection.
Definition Collider.h:73
glm::mat4 matrix() const
Gets the transformation matrix of the transform.
Definition Transform.h:40
Represents a rectangle in 2D space.
Definition Rectangle.h:15
A vector with four components.
Definition Vector4.h:13
A signal is a class used to emit events.
Definition Slot.h:10
virtual RttiBase & rttiInstance() const =0