9 #include <physics_manager/physics_manager.hpp>
10 #include "main/timer.hpp"
12 static bool singleton_initialized =
false;
20 if (singleton_initialized) {
21 throw std::runtime_error(
"The phsyics manager cannot be initialized more than once!");
23 singleton_initialized =
true;
25 gMessage_bus.
subscribe(SET_GRAVITY, &msg_sub);
26 gMessage_bus.
subscribe(SET_FRICTION, &msg_sub);
27 gMessage_bus.
subscribe(SET_FLOOR, &msg_sub);
28 gMessage_bus.
subscribe(PAUSE_PHYSICS, &msg_sub);
29 gMessage_bus.
subscribe(UNPAUSE_PHYSICS, &msg_sub);
38 void physics_manager::process_horizontal(std::vector<ST::entity *> *entities, int8_t friction) {
39 for (uint64_t k = 0; k < entities->size(); ++k) {
40 auto &entity = entities->operator[](k);
42 if (entity->velocity_x > 0) {
43 for (
int j = 0; j < entity->velocity_x; ++j) {
45 entity->velocity_x = entity_set_x(entity->x + 1, k, entities) *
48 for (
int j = 0; j < friction && entity->velocity_x > 0; ++j) {
49 entity->velocity_x =
static_cast<int8_t
>(entity->velocity_x - 1);
51 }
else if (entity->velocity_x < 0) {
52 for (
int j = 0; j > entity->velocity_x; --j) {
54 entity->velocity_x = entity_set_x(entity->x - 1, k, entities) *
57 for (
int j = 0; j < friction && entity->velocity_x < 0; ++j) {
58 entity->velocity_x =
static_cast<int8_t
>(entity->velocity_x + 1);
64 physics_manager::~physics_manager() {
65 singleton_initialized =
false;
71 void physics_manager::process_vertical(std::vector<ST::entity *> *entities, int8_t gravity, int32_t level_floor) {
72 for (uint64_t k = 0; k < entities->size(); ++k) {
73 auto &entity = entities->operator[](k);
75 const int8_t objectVelocity = entity->velocity_y + gravity;
76 for (
int j = 0; j > objectVelocity && entity_set_y(entity->y - 1, k, entities) != 0; --j);
77 for (
int j = 0; j < objectVelocity; ++j) {
78 if (entity->y + entity->get_col_y_offset() < level_floor) {
79 if (entity_set_y(entity->y + 1, k, entities) == 0) {
85 int8_t realVelocity = objectVelocity - gravity;
87 (realVelocity < 0) * static_cast<int8_t>(realVelocity + 2) + (realVelocity >= 0) * entity->velocity_y;
95 void physics_manager::handle_messages() {
97 while (temp !=
nullptr) {
98 switch (temp->msg_name) {
100 gravity =
static_cast<int8_t
>(temp->base_data0);
103 level_floor =
static_cast<int32_t
>(temp->base_data0);
106 friction =
static_cast<int8_t
>(temp->base_data0);
109 physics_paused =
true;
111 case UNPAUSE_PHYSICS:
112 physics_paused =
false;
127 uint8_t physics_manager::entity_set_x(int32_t X, uint64_t ID, std::vector<ST::entity *> *entities) {
128 ST::entity *entity = entities->operator[](ID);
129 int32_t old_x = entity->x;
131 uint8_t collision = check_collision(ID, entities);
132 entity->x = collision * old_x + !collision * entity->x;
143 uint8_t physics_manager::entity_set_y(int32_t Y, uint64_t ID, std::vector<ST::entity *> *entities) {
144 ST::entity *entity = entities->operator[](ID);
145 int32_t old_y = entity->y;
147 uint8_t collision = check_collision(ID, entities);
148 entity->y = collision * old_y + !collision * entity->y;
158 int physics_manager::check_collision(uint64_t ID, std::vector<ST::entity *> *entities) {
160 for (
size_t i = 0; i < entities->size() && result == 0; i++) {
162 result = temp->is_affected_by_physics() && i != ID && temp->
collides(*entities->operator[](ID));
173 if (!physics_paused) [[likely]] {
174 if (entities_ref.size() != level.physics_objects_count) {
175 entities_ref.clear();
176 entities_ref.reserve(level.physics_objects_count);
179 for (uint64_t i = 0; i < level.entities.size(); i++) {
180 if (level.entities.operator[](i).is_affected_by_physics()) {
181 entities_ref.emplace_back(&level.entities.operator[](i));
185 process_horizontal(&entities_ref, friction);
186 process_vertical(&entities_ref, gravity, level_floor);
This class represents all static or dynamic objects in the game (excluding text, see ST::text)
bool collides(const entity &) const
This object contains all the data for a level and provides functions for loading and unloading a leve...
The central messaging system of the engine. All subsystem make extensive use of it.
void subscribe(uint8_t msg, subscriber *sub)
A message object passed around in the message bus. Holds anything created with make_data<>().
void update(ST::level &level)
physics_manager(message_bus &gMessageBus)
message * get_next_message()