Skip to content

Commit

Permalink
Cleanup in the moving platform path code
Browse files Browse the repository at this point in the history
  • Loading branch information
mmatyas committed May 25, 2024
1 parent c7e1d89 commit 81ee3d7
Show file tree
Hide file tree
Showing 7 changed files with 199 additions and 234 deletions.
228 changes: 94 additions & 134 deletions src/common/MovingPlatformPaths.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +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;
}

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 /= 2.f;
m_endPos /= 2.f;
m_speed /= 2.f;
}

pPlatform = NULL;
}

void MovingPlatformPath::Reset()
{
//advance the spawn test platform
// advance the spawn test platform
if (game_values.spawnstyle == SpawnStyle::Door) {
for (short i = 0; i < 36; i++)
Move(1);
Expand All @@ -57,53 +44,41 @@ 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, std::move(startPos), std::move(endPos), preview)
{
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);
float width = m_endPos.x - m_startPos.x;
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;
m_steps = (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];

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_velocity[type];
m_currentStep[type]++;

if (m_currentStep[type] >= m_steps) {
m_currentStep[type] = 0;
m_currentPos[type] = *m_goalPoint[type];
m_goalPoint[type] = (m_goalPoint[type] == &m_endPos) ? &m_startPos : &m_endPos;
SetVelocity(type);
}

Expand All @@ -112,31 +87,27 @@ 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_goalPoint[type] == &m_startPos) {
m_velocity[type] *= -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];

iGoalPoint[type] = 1;
m_currentStep[type] = 0;
m_currentPos[type] = m_startPos;
m_goalPoint[type] = &m_endPos;
SetVelocity(type);
}

Expand All @@ -148,49 +119,45 @@ 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, std::move(startPos), Vec2f::zero(), preview)
{
dAngle = angle;
m_angle = angle;

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

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

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

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

float dx = dCurrentX[type] - (float)pPlatform->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)pPlatform->iHalfHeight < 0.0f)
dCurrentY[type] += dEdgeY + (float)pPlatform->iHeight;
else if (dCurrentY[type] - (float)pPlatform->iHalfHeight >= dEdgeY)
dCurrentY[type] -= dEdgeY + (float)pPlatform->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 @@ -199,59 +166,53 @@ 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 centerPos, bool preview)
: MovingPlatformPath(speed, std::move(centerPos), Vec2f::zero(), preview)
, m_radius(std::move(radius))
, m_startAngle(angle)
{
dStartAngle = angle;

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

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

bool EllipsePath::Move(short type)
{
float dOldCurrentX = dCurrentX[type];
float dOldCurrentY = dCurrentY[type];
Vec2f oldPos = m_currentPos[type];

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] = m_currentPos[type] - oldPos;

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] = m_startAngle;
SetPosition(type);
}

Expand All @@ -262,39 +223,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), Vec2f::zero(), false)
{}

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

if (pPlatform->fy - pPlatform->iHalfHeight >= App::screenHeight) {
//If a player is standing on this platform, clear him off
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 == pPlatform) {
player->platform = NULL;
player->vely = dVelY[type];
if (player->platform == m_platform) {
player->platform = nullptr;
player->vely = m_velocity[type].y;
}
}

pPlatform->fDead = true;
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 81ee3d7

Please sign in to comment.