// 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 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(); // Friction velocity -= velocity * friction * delta; // Solid Collision Check glm::vec2 moveAmount; if(myCollider == nullptr) { moveAmount = velocity; } else { // Perform sweep auto allColliders = getScene()->findComponents(); 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(); 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(velocity.x) <= 0.001f) velocity.x = 0; if(mathAbs(velocity.y) <= 0.001f) velocity.y = 0; }, getScene()->eventSceneUpdate); }