Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
mmatyas committed May 24, 2024
1 parent 194ca4f commit d399c47
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 134 deletions.
211 changes: 92 additions & 119 deletions src/common/MovingPlatformPaths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,21 @@ extern std::vector<CPlayer*> players;
// Moving Platform Path base class
//------------------------------------------------------------------------------

MovingPlatformPath::MovingPlatformPath(float vel, float startX, float startY, float endX, float endY, bool preview)
MovingPlatformPath::MovingPlatformPath(float speed, Vec2f startPos, Vec2f endPos, bool preview)
: m_startPos(std::move(startPos))
, m_endPos(std::move(endPos))
, m_speed(speed)
{
dVelocity = vel;

for (short type = 0; type < 2; type++) {
dVelX[type] = 0.0f;
dVelY[type] = 0.0f;
m_velocity[type] = {0.f, 0.f};
}

dPathPointX[0] = startX;
dPathPointY[0] = startY;
dPathPointX[1] = endX;
dPathPointY[1] = endY;

if (preview) {
dPathPointX[0] /= 2.0f;
dPathPointY[0] /= 2.0f;
dPathPointX[1] /= 2.0f;
dPathPointY[1] /= 2.0f;
dVelocity /= 2.0f;
m_startPos.x /= 2.f;
m_startPos.y /= 2.f;
m_endPos.x /= 2.f;
m_endPos.y /= 2.f;
m_speed /= 2.f;
}
}

Expand All @@ -54,53 +49,43 @@ void MovingPlatformPath::Reset()
//------------------------------------------------------------------------------
// Straight Path
//------------------------------------------------------------------------------

StraightPath::StraightPath(float vel, float startX, float startY, float endX, float endY, bool preview)
: MovingPlatformPath(vel, startX, startY, endX, endY, preview)
, iGoalPoint{0, 0}
StraightPath::StraightPath(float speed, Vec2f startPos, Vec2f endPos, bool preview)
: MovingPlatformPath(speed, startPos, endPos, preview)
, m_goalPos{m_endPos, m_endPos}
{
float dWidth = dPathPointX[1] - dPathPointX[0];
float dHeight = dPathPointY[1] - dPathPointY[0];
float dLength = 0.0f;

//Lock angle to vertical
if (dWidth == 0) {
if (dHeight > 0)
dAngle = HALF_PI;
else
dAngle = THREE_HALF_PI;

dLength = fabs(dHeight);
} else if (dHeight == 0) { //Lock angle to horizontal
if (dWidth > 0)
dAngle = 0.0f;
else
dAngle = PI;

dLength = fabs(dWidth);
const float width = m_endPos.x - m_startPos.x;
const float height = m_endPos.y - m_startPos.y;
float length = 0.f;

if (width == 0) {
//Lock angle to vertical
m_angle = (height > 0) ? HALF_PI : THREE_HALF_PI;
length = ::fabs(height);
} else if (height == 0) {
//Lock angle to horizontal
m_angle = (width > 0) ? 0.f: PI;
length = ::fabs(width);
} else {
dAngle = atan2(dHeight, dWidth);
dLength = sqrt(dHeight * dHeight + dWidth * dWidth);
m_angle = atan2(height, width);
length = sqrt(height * height + width * width);
}

iSteps = (short)(dLength / dVelocity) + 1;
iSteps = (short)(length / m_speed) + 1;

for (short type = 0; type < 2; type++)
SetVelocity(type);
}

bool StraightPath::Move(short type)
{
dCurrentX[type] += dVelX[type];
dCurrentY[type] += dVelY[type];
m_currentPos[type].x += m_velocity[type].x;
m_currentPos[type].y += m_velocity[type].y;

if (++iOnStep[type] >= iSteps) {
iOnStep[type] = 0;

dCurrentX[type] = dPathPointX[iGoalPoint[type]];
dCurrentY[type] = dPathPointY[iGoalPoint[type]];

iGoalPoint[type] = 1 - iGoalPoint[type];
m_currentPos[type] = m_movesForward[type] ? m_endPos : m_startPos;
m_movesForward[type] = !m_movesForward[type];

SetVelocity(type);
}
Expand All @@ -110,31 +95,30 @@ bool StraightPath::Move(short type)

void StraightPath::SetVelocity(short type)
{
if (iGoalPoint[type] == 1) {
dVelX[type] = dVelocity * cos(dAngle);
dVelY[type] = dVelocity * sin(dAngle);
} else {
dVelX[type] = -dVelocity * cos(dAngle);
dVelY[type] = -dVelocity * sin(dAngle);
m_velocity[type].x = m_speed * cos(m_angle);
m_velocity[type].y = m_speed * sin(m_angle);
if (!m_movesForward[type]) {
m_velocity[type].x *= -1.f;
m_velocity[type].y *= -1.f;
}

//Fix rounding errors
if (dVelX[type] < 0.01f && dVelX[type] > -0.01f)
dVelX[type] = 0.0f;
//Fix rounding errors
if (::fabs(m_velocity[type].x) < 0.01f)
m_velocity[type].x = 0.f;

if (dVelY[type] < 0.01f && dVelY[type] > -0.01f)
dVelY[type] = 0.0f;
if (::fabs(m_velocity[type].y) < 0.01f)
m_velocity[type].y = 0.f;
}

void StraightPath::Reset()
{
for (short type = 0; type < 2; type++) {
iOnStep[type] = 0;

dCurrentX[type] = dPathPointX[0];
dCurrentY[type] = dPathPointY[0];
m_currentPos[type] = m_startPos;
m_goalPos[type] = m_endPos;
m_movesForward[type] = true;

iGoalPoint[type] = 1;
SetVelocity(type);
}

Expand All @@ -146,49 +130,41 @@ void StraightPath::Reset()
// Straight Path Continuous
//------------------------------------------------------------------------------

StraightPathContinuous::StraightPathContinuous(float vel, float startX, float startY, float angle, bool preview) :
StraightPath(vel, startX, startY, 0.0f, 0.0f, preview)
StraightPathContinuous::StraightPathContinuous(float speed, Vec2f startPos, float angle, bool preview)
: StraightPath(speed, startPos, {0.f, 0.f}, preview)
, m_edge{App::screenWidth, App::screenHeight}
{
dAngle = angle;

for (short type = 0; type < 2; type++) {
iGoalPoint[type] = 1;
SetVelocity(type);
}

dEdgeX = App::screenWidth;
dEdgeY = App::screenHeight;
m_angle = angle;

if (preview) {
dEdgeX = App::screenWidth/2;
dEdgeY = App::screenHeight/2;
m_edge.x /= 2.f;
m_edge.y /= 2.f;
}
}

bool StraightPathContinuous::Move(short type)
{
dCurrentX[type] += dVelX[type];
dCurrentY[type] += dVelY[type];
m_currentPos[type].x += m_velocity[type].x;
m_currentPos[type].y += m_velocity[type].y;

float dx = dCurrentX[type] - (float)m_platform->iHalfWidth;
if (dx < 0.0f)
dCurrentX[type] += dEdgeX;
else if (dx >= dEdgeX)
dCurrentX[type] -= dEdgeX;
float dx = m_currentPos[type].x - (float)m_platform->iHalfWidth;
if (dx < 0.f)
m_currentPos[type].x += m_edge.x;
else if (dx >= m_edge.x)
m_currentPos[type].x -= m_edge.x;

if (dCurrentY[type] + (float)m_platform->iHalfHeight < 0.0f)
dCurrentY[type] += dEdgeY + (float)m_platform->iHeight;
else if (dCurrentY[type] - (float)m_platform->iHalfHeight >= dEdgeY)
dCurrentY[type] -= dEdgeY + (float)m_platform->iHeight;
if (m_currentPos[type].y + (float)m_platform->iHalfHeight < 0.f)
m_currentPos[type].y += m_edge.y + (float)m_platform->iHeight;
else if (m_currentPos[type].y - (float)m_platform->iHalfHeight >= m_edge.y)
m_currentPos[type].y -= m_edge.y + (float)m_platform->iHeight;

return false;
}

void StraightPathContinuous::Reset()
{
for (short type = 0; type < 2; type++) {
dCurrentX[type] = dPathPointX[0];
dCurrentY[type] = dPathPointY[0];
m_currentPos[type] = m_startPos;
}

MovingPlatformPath::Reset();
Expand All @@ -197,59 +173,57 @@ void StraightPathContinuous::Reset()
//------------------------------------------------------------------------------
// Ellipse Path
//------------------------------------------------------------------------------
EllipsePath::EllipsePath(float vel, float angle, float radiusx, float radiusy, float centerx, float centery, bool preview) :
MovingPlatformPath(vel, centerx, centery, 0.0f, 0.0f, preview)
EllipsePath::EllipsePath(float speed, float angle, Vec2f radius, Vec2f center, bool preview)
: MovingPlatformPath(speed, center, {0.f, 0.f}, preview)
, m_radius(std::move(radius))
, m_angle{angle, angle}
{
dStartAngle = angle;

if (preview) {
dRadiusX = radiusx / 2.0f;
dRadiusY = radiusy / 2.0f;
dVelocity *= 2.0f;
} else {
dRadiusX = radiusx;
dRadiusY = radiusy;
m_radius.x /= 2.f;
m_radius.y /= 2.f;
m_speed *= 2.f;
}

for (short type = 0; type < 2; type++) {
dAngle[type] = angle;
SetPosition(type);
}
}

bool EllipsePath::Move(short type)
{
float dOldCurrentX = dCurrentX[type];
float dOldCurrentY = dCurrentY[type];
float dOldCurrentX = m_currentPos[type].x;
float dOldCurrentY = m_currentPos[type].y;

dAngle[type] += dVelocity;
m_angle[type] += m_speed;

if (dVelocity < 0.0f) {
while (dAngle[type] < 0.0f)
dAngle[type] += TWO_PI;
if (m_speed < 0.f) {
while (m_angle[type] < 0.f)
m_angle[type] += TWO_PI;
} else {
while (dAngle[type] >= TWO_PI)
dAngle[type] -= TWO_PI;
while (m_angle[type] >= TWO_PI)
m_angle[type] -= TWO_PI;
}

SetPosition(type);

dVelX[type] = dCurrentX[type] - dOldCurrentX;
dVelY[type] = dCurrentY[type] - dOldCurrentY;
m_velocity[type].x = m_currentPos[type].x - dOldCurrentX;
m_velocity[type].y = m_currentPos[type].y - dOldCurrentY;

return false;
}

void EllipsePath::SetPosition(short type)
{
dCurrentX[type] = dRadiusX * cos(dAngle[type]) + dPathPointX[0];
dCurrentY[type] = dRadiusY * sin(dAngle[type]) + dPathPointY[0];
m_currentPos[type].x = m_radius.x * cos(m_angle[type]) + m_startPos.x;
m_currentPos[type].y = m_radius.y * sin(m_angle[type]) + m_startPos.y;
}

void EllipsePath::Reset()
{
for (short type = 0; type < 2; type++) {
dAngle[type] = dStartAngle;
m_angle[type] = dStartAngle;
SetPosition(type);
}

Expand All @@ -260,39 +234,38 @@ void EllipsePath::Reset()
// Falling path (for falling donut blocks)
//------------------------------------------------------------------------------

FallingPath::FallingPath(float startX, float startY) :
MovingPlatformPath(0.0f, startX, startY, 0.0f, 0.0f, false)
FallingPath::FallingPath(Vec2f startPos)
: MovingPlatformPath(0.f, std::move(startPos), {0.f, 0.f}, false)
{}

bool FallingPath::Move(short type)
{
dVelY[type] = CapFallingVelocity(dVelY[type] + GRAVITATION);
m_velocity[type].y = CapFallingVelocity(m_velocity[type].y + GRAVITATION);

if (m_platform->fy - m_platform->iHalfHeight >= App::screenHeight) {
//If a player is standing on this platform, clear him off
for (CPlayer* player : players) {
if (player->platform == m_platform) {
player->platform = NULL;
player->vely = dVelY[type];
player->vely = m_velocity[type].y;
}
}

m_platform->fDead = true;
}

dCurrentY[type] += dVelY[type];
m_currentPos[type].y += m_velocity[type].y;

return false;
}

void FallingPath::Reset()
{
for (short type = 0; type < 2; type++) {
dCurrentX[type] = dPathPointX[0];
dCurrentY[type] = dPathPointY[0];
m_currentPos[type] = m_startPos;
}

//Skip correctly setting the path "shadow" as a perf optimization
//This does have the risk of a player spawning inside a falling donut block by accident
//MovingPlatformPath::Reset();
//Skip correctly setting the path "shadow" as a perf optimization
//This does have the risk of a player spawning inside a falling donut block by accident
//MovingPlatformPath::Reset();
}
Loading

0 comments on commit d399c47

Please sign in to comment.