123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- /*
- * 2D Game Engine
- * Collision.h:
- * Based on pikuma.com 2D game engine in C++ and Lua course
- * Copyright (c) 2021 986-Studio. All rights reserved.
- *
- * Created by Manoël Trapier on 15/02/2021.
- */
- #ifndef GAMEENGINE_COLLISION_H
- #define GAMEENGINE_COLLISION_H
- #include <SDL.h>
- #include <ECS.h>
- #include <Logger.h>
- #include <EventBus.h>
- #include <Components/Transform.h>
- #include <Components/BoxCollider.h>
- #include <Events/Collision.h>
- class CollisionSystem: public System
- {
- class BoxRect
- {
- double x0, y0, x1, y1;
- public:
- BoxRect(TransformComponent tc, BoxColliderComponent bc)
- {
- this->x0 = tc.position.x + bc.offset.x;
- this->x1 = this->x0 + bc.width;
- this->y0 = tc.position.y + bc.offset.y;
- this->y1 = this->y0 + bc.height;
- }
- bool collideWith(BoxRect &b) const
- {
- return ((this->x0 < b.x1) && (this->x1 > b.x0) && (this->y0 < b.y1) && (this->y1 > b.y0));
- }
- };
- public:
- CollisionSystem()
- {
- this->requireComponent<TransformComponent>();
- this->requireComponent<BoxColliderComponent>();
- }
- void update(std::unique_ptr<EventBus> &eventBus)
- {
- auto entities = this->getSystemEntities();
- for(auto entity: entities)
- {
- auto &collider = entity.getComponent<BoxColliderComponent>();
- collider.isColliding = false;
- }
- for(auto i = entities.begin(); i != entities.end(); i++)
- {
- for(auto j = (i + 1); j != entities.end(); j++)
- {
- auto &collideA = i->getComponent<BoxColliderComponent>();
- auto &collideB = j->getComponent<BoxColliderComponent>();
- BoxRect boxA = BoxRect(i->getComponent<TransformComponent>(), collideA);
- BoxRect boxB = BoxRect(j->getComponent<TransformComponent>(), collideB);
- if (boxA.collideWith(boxB))
- {
- //Logger::Debug("Entity #%d collided with #%d!", i->getId(), j->getId());
- collideB.isColliding = true;
- collideA.isColliding = true;
- eventBus->emitEvent<CollisionEvent>(*i, *j);
- }
- }
- }
- }
- void debugRender(SDL_Renderer *renderer, SDL_Rect &camera)
- {
- for(auto entity: this->getSystemEntities())
- {
- auto collider = entity.getComponent<BoxColliderComponent>();
- auto transform = entity.getComponent<TransformComponent>();
- SDL_Rect rect;
- rect.x = static_cast<int>(transform.position.x + collider.offset.x - camera.x);
- rect.y = static_cast<int>(transform.position.y + collider.offset.y - camera.y);
- rect.w = static_cast<int>(collider.width * transform.scale.x);
- rect.h = static_cast<int>(collider.height * transform.scale.y);
- if (collider.isColliding)
- {
- SDL_SetRenderDrawColor(renderer, 255, 64, 16, 255);
- }
- else
- {
- SDL_SetRenderDrawColor(renderer, 64, 255, 21, 255);
- }
- SDL_RenderDrawRect(renderer, &rect);
- }
- }
- };
- #endif /* GAMEENGINE_COLLISION_H */
|