92 lines
2.5 KiB
C++
92 lines
2.5 KiB
C++
// Copyright (c) 2023 Dominic Masters
|
|
//
|
|
// This software is released under the MIT License.
|
|
// https://opensource.org/licenses/MIT
|
|
|
|
#include "CharacterController2D.hpp"
|
|
|
|
using namespace Dawn;
|
|
|
|
CharacterController2D::CharacterController2D(std::weak_ptr<SceneItem> i) :
|
|
SceneItemComponent(i)
|
|
{
|
|
}
|
|
|
|
void CharacterController2D::onStart() {
|
|
useEvent([&](float_t delta){
|
|
// if(velocity == glm::vec2(0, 0)) return;
|
|
|
|
// Common variables
|
|
auto item = this->item.lock();
|
|
auto myCollider = item->getComponent<Collider2D>();
|
|
|
|
// Friction
|
|
velocity -= velocity * friction * delta;
|
|
|
|
// Solid Collision Check
|
|
glm::vec2 moveAmount;
|
|
if(myCollider == nullptr) {
|
|
moveAmount = velocity;
|
|
} else {
|
|
// Perform sweep
|
|
auto allColliders = getScene()->findComponents<SolidController2D>();
|
|
auto itColliders = allColliders.begin();
|
|
|
|
struct CharacterController2DCollisionEventInfo info;
|
|
bool_t result = false;
|
|
|
|
// Check for collisions, definitely not working 100% yet
|
|
while(itColliders != allColliders.end()) {
|
|
auto c = *itColliders;
|
|
++itColliders;
|
|
auto cItem = c->item.lock();
|
|
if(cItem == item || cItem->isChildOf(item)) continue;
|
|
result = c->getCollidingResult(
|
|
velocity,
|
|
myCollider,
|
|
info.normal,
|
|
info.entryTime,
|
|
info.exitTime,
|
|
info.entryPoint,
|
|
info.exitPoint
|
|
) && info.entryTime <= delta;
|
|
|
|
if(result) {
|
|
info.collider = c;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(result) {
|
|
moveAmount = glm::vec2(0, 0);
|
|
velocity = glm::vec2(0, 0);
|
|
this->eventCollision.invoke(info);
|
|
} else {
|
|
moveAmount = velocity;
|
|
}
|
|
}
|
|
|
|
if(moveAmount != glm::vec2(0, 0)) {
|
|
item->setLocalPosition(
|
|
item->getLocalPosition() + (glm::vec3(moveAmount.x, 0, moveAmount.y) * delta)
|
|
);
|
|
}
|
|
|
|
// Now perform trigger collision check
|
|
auto allTriggers = getScene()->findComponents<TriggerController2D>();
|
|
auto itTriggers = allTriggers.begin();
|
|
while(itTriggers != allTriggers.end()) {
|
|
auto c = *itTriggers;
|
|
++itTriggers;
|
|
auto cItem = c->item.lock();
|
|
if(cItem == item || cItem->isChildOf(item)) continue;
|
|
if(c->getCollidingResult(myCollider)) {
|
|
c->eventTriggerEnter.invoke(this);
|
|
}
|
|
}
|
|
|
|
// Stop velocity near zero.
|
|
if(mathAbs<float_t>(velocity.x) <= 0.001f) velocity.x = 0;
|
|
if(mathAbs<float_t>(velocity.y) <= 0.001f) velocity.y = 0;
|
|
}, getScene()->eventSceneUpdate);
|
|
} |