76 lines
2.5 KiB
C++
76 lines
2.5 KiB
C++
#include "KCircle.h"
|
|
|
|
#include "KRect.h"
|
|
#include "Utils.h"
|
|
|
|
namespace KapitanGame {
|
|
|
|
|
|
KCircle::KCircle(const KVector2D& position, const KVector2D& velocity, const float& radius, const KTexture& texture) : KShape(position, velocity, texture),
|
|
Radius(radius) {
|
|
}
|
|
|
|
bool KCircle::IsCollision(const KCircle& other) const {
|
|
return (Position - other.Position).Length() < Radius + other.Radius;
|
|
}
|
|
|
|
bool KCircle::IsCollision(const KRect& other) const {
|
|
const auto f = KVector2D(Utils::Clamp(Position.X, other.GetPosition().X - other.GetWidth() / 2, other.GetPosition().X + other.GetWidth() / 2),
|
|
Utils::Clamp(Position.Y, other.GetPosition().Y - other.GetHeight() / 2, other.GetPosition().Y + other.GetHeight() / 2));
|
|
|
|
return (Position - f).Length() < Radius;
|
|
}
|
|
|
|
KVector2D KCircle::GetSeparationVector(const KCircle& other) const {
|
|
const KVector2D centerDiff = Position - other.Position;
|
|
const float centerDiffLength = centerDiff.Length();
|
|
return centerDiff / centerDiffLength * (Radius + other.Radius - centerDiffLength);
|
|
}
|
|
|
|
KVector2D KCircle::GetSeparationVector(const KRect& other) const {
|
|
const float l = other.GetPosition().X - other.GetWidth() / 2;
|
|
const float r = other.GetPosition().X + other.GetWidth() / 2;
|
|
const float t = other.GetPosition().Y - other.GetHeight() / 2;
|
|
const float b = other.GetPosition().Y + other.GetHeight() / 2;
|
|
const auto f = KVector2D(Utils::Clamp(Position.X, l, r),
|
|
Utils::Clamp(Position.Y, t, b));
|
|
|
|
if (Position == f) {
|
|
const auto left = Position.X - l + Radius;
|
|
const auto right = r - Position.X + Radius;
|
|
const auto top = Position.Y - t + Radius;
|
|
const auto bottom = b - Position.Y + Radius;
|
|
return KRect::GetSeparationVector(left, right, top, bottom);
|
|
}
|
|
return (Position - f) / (Position - f).Length() * (Radius - (Position - f).Length());
|
|
}
|
|
|
|
void KCircle::CollisionDetectionWithMapStep(const SDL_Rect& map) {
|
|
|
|
if (Position.X - map.x - Radius < 0)
|
|
{
|
|
Position.X += -(Position.X - map.x - Radius);
|
|
Velocity = Velocity.Reflect({ -1.f, 0.f });
|
|
}
|
|
if (Position.X + Radius - map.w > 0)
|
|
{
|
|
Velocity = Velocity.Reflect({ 1.f, 0.f });
|
|
Position.X += -(Position.X - map.w + Radius);
|
|
}
|
|
if (Position.Y - Radius - map.y < 0) {
|
|
Position.Y += -(Position.Y - map.y - Radius);
|
|
Velocity = Velocity.Reflect({ 0.f, 1.f });
|
|
}
|
|
if (Position.Y + Radius - map.h > 0) {
|
|
Position.Y += -(Position.Y - map.h + Radius);
|
|
Velocity = Velocity.Reflect({ 0.f, -1.f });
|
|
}
|
|
}
|
|
|
|
float KCircle::GetRadius() const {
|
|
return Radius;
|
|
}
|
|
|
|
}
|
|
|