mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2023-12-30 21:52:56 +00:00
FT collision part3: cleanup.
This commit is contained in:
parent
ba470e8727
commit
4b86fe2aa7
@ -211,7 +211,10 @@ void DebugOverlay::DrawBallInfo()
|
|||||||
SDL_SetRenderDrawColor(winmain::Renderer, 0, 0, 255, 255);
|
SDL_SetRenderDrawColor(winmain::Renderer, 0, 0, 255, 255);
|
||||||
|
|
||||||
auto pt1 = proj::xform_to_2d(ballPosition);
|
auto pt1 = proj::xform_to_2d(ballPosition);
|
||||||
SDL_RenderDrawCircle(winmain::Renderer, pt1.X, pt1.Y, 10);
|
vector2 radVec1 = { 0, ballPosition.Y }, radVec2 = { ball->Radius, ballPosition.Y };
|
||||||
|
auto radVec1I = proj::xform_to_2d(radVec1), radVec2I = proj::xform_to_2d(radVec2);
|
||||||
|
auto radI = std::sqrt(maths::magnitudeSq(vector2i{ radVec1I.X - radVec2I.X ,radVec1I.Y - radVec2I.Y }));
|
||||||
|
SDL_RenderDrawCircle(winmain::Renderer, pt1.X, pt1.Y, static_cast<int>(std::round(radI)));
|
||||||
|
|
||||||
auto nextPos = ballPosition;
|
auto nextPos = ballPosition;
|
||||||
maths::vector_add(nextPos, maths::vector_mul(ball->Direction, ball->Speed / 10.0f));
|
maths::vector_add(nextPos, maths::vector_mul(ball->Direction, ball->Speed / 10.0f));
|
||||||
|
@ -41,7 +41,7 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
|
|||||||
groupIndex = loader::query_handle(ballGroupName);
|
groupIndex = loader::query_handle(ballGroupName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Offset = *loader::query_float_attribute(groupIndex, 0, 500);
|
Radius = *loader::query_float_attribute(groupIndex, 0, 500);
|
||||||
|
|
||||||
auto visualCount = loader::query_visual_states(groupIndex);
|
auto visualCount = loader::query_visual_states(groupIndex);
|
||||||
for (auto index = 0; index < visualCount; ++index)
|
for (auto index = 0; index < visualCount; ++index)
|
||||||
@ -53,8 +53,8 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
|
|||||||
VisualZArray[index] = zDepth;
|
VisualZArray[index] = zDepth;
|
||||||
}
|
}
|
||||||
RenderSprite = new render_sprite(VisualTypes::Ball, nullptr, nullptr, 0, 0, nullptr);
|
RenderSprite = new render_sprite(VisualTypes::Ball, nullptr, nullptr, 0, 0, nullptr);
|
||||||
PinballTable->CollisionCompOffset = Offset;
|
PinballTable->CollisionCompOffset = Radius;
|
||||||
Position.Z = Offset;
|
Position.Z = Radius;
|
||||||
GroupIndex = groupIndex;
|
GroupIndex = groupIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ void TBall::Repaint()
|
|||||||
Position.Z =
|
Position.Z =
|
||||||
CollisionOffset.X * Position.X +
|
CollisionOffset.X * Position.X +
|
||||||
CollisionOffset.Y * Position.Y +
|
CollisionOffset.Y * Position.Y +
|
||||||
Offset + CollisionOffset.Z;
|
Radius + CollisionOffset.Z;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pos2D = proj::xform_to_2d(Position);
|
auto pos2D = proj::xform_to_2d(Position);
|
||||||
@ -120,7 +120,7 @@ int TBall::Message(MessageCode code, float value)
|
|||||||
CollisionFlag = 0;
|
CollisionFlag = 0;
|
||||||
CollisionMask = 1;
|
CollisionMask = 1;
|
||||||
Direction.Y = 0.0;
|
Direction.Y = 0.0;
|
||||||
Position.Z = Offset;
|
Position.Z = Radius;
|
||||||
Direction.X = 0.0;
|
Direction.X = 0.0;
|
||||||
Speed = 0.0;
|
Speed = 0.0;
|
||||||
RayMaxDistance = 0.0;
|
RayMaxDistance = 0.0;
|
||||||
|
@ -32,10 +32,10 @@ public :
|
|||||||
bool EdgeCollisionResetFlag{};
|
bool EdgeCollisionResetFlag{};
|
||||||
vector3 CollisionOffset{};
|
vector3 CollisionOffset{};
|
||||||
int CollisionFlag;
|
int CollisionFlag;
|
||||||
float Offset;
|
float Radius;
|
||||||
bool HasGroupFlag;
|
bool HasGroupFlag;
|
||||||
int SomeCounter1 = 0;
|
int StuckCounter = 0;
|
||||||
int time_ticks1{}, time_ticks2{};
|
int LastActiveTime{};
|
||||||
float VisualZArray[50]{};
|
float VisualZArray[50]{};
|
||||||
bool AsEdgeCollisionFlag{};
|
bool AsEdgeCollisionFlag{};
|
||||||
};
|
};
|
||||||
|
@ -126,19 +126,19 @@ void TFlipper::UpdateSprite()
|
|||||||
SpriteSet(BmpIndex);
|
SpriteSet(BmpIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TFlipper::GetFlipperAngleDistance(float dt, float* dst) const
|
int TFlipper::GetFlipperStepAngle(float dt, float* dst) const
|
||||||
{
|
{
|
||||||
if (!MessageField)
|
if (!MessageField)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auto deltaAngle = FlipperEdge->flipper_angle_delta(dt);
|
auto deltaAngle = FlipperEdge->flipper_angle_delta(dt);
|
||||||
auto distance = std::fabs(std::ceil(FlipperEdge->DistanceDiv * deltaAngle * FlipperEdge->InvT1Radius));
|
auto step = std::fabs(std::ceil(FlipperEdge->DistanceDiv * deltaAngle * FlipperEdge->InvT1Radius));
|
||||||
if (distance > 3.0f)
|
if (step > 3.0f)
|
||||||
distance = 3.0f;
|
step = 3.0f;
|
||||||
if (distance >= 2.0f)
|
if (step >= 2.0f)
|
||||||
{
|
{
|
||||||
*dst = deltaAngle / distance;
|
*dst = deltaAngle / step;
|
||||||
return static_cast<int>(distance);
|
return static_cast<int>(step);
|
||||||
}
|
}
|
||||||
|
|
||||||
*dst = deltaAngle;
|
*dst = deltaAngle;
|
||||||
@ -152,7 +152,6 @@ void TFlipper::FlipperCollision(float deltaAngle)
|
|||||||
|
|
||||||
ray_type ray{}, rayDst{};
|
ray_type ray{}, rayDst{};
|
||||||
ray.MinDistance = 0.002f;
|
ray.MinDistance = 0.002f;
|
||||||
auto deltaAngleNeg = -deltaAngle;
|
|
||||||
bool collisionFlag = false;
|
bool collisionFlag = false;
|
||||||
for (auto ball : pb::MainTable->BallList)
|
for (auto ball : pb::MainTable->BallList)
|
||||||
{
|
{
|
||||||
@ -167,7 +166,7 @@ void TFlipper::FlipperCollision(float deltaAngle)
|
|||||||
|
|
||||||
float sin, cos;
|
float sin, cos;
|
||||||
auto ballPosRot = ray.Origin;
|
auto ballPosRot = ray.Origin;
|
||||||
maths::SinCos(deltaAngleNeg, sin, cos);
|
maths::SinCos(-deltaAngle, sin, cos);
|
||||||
maths::RotatePt(ballPosRot, sin, cos, FlipperEdge->RotOrigin);
|
maths::RotatePt(ballPosRot, sin, cos, FlipperEdge->RotOrigin);
|
||||||
ray.Direction.X = ballPosRot.X - ray.Origin.X;
|
ray.Direction.X = ballPosRot.X - ray.Origin.X;
|
||||||
ray.Direction.Y = ballPosRot.Y - ray.Origin.Y;
|
ray.Direction.Y = ballPosRot.Y - ray.Origin.Y;
|
||||||
@ -188,18 +187,13 @@ void TFlipper::FlipperCollision(float deltaAngle)
|
|||||||
auto angleAdvance = deltaAngle / (std::fabs(FlipperEdge->MoveSpeed) * 5.0f);
|
auto angleAdvance = deltaAngle / (std::fabs(FlipperEdge->MoveSpeed) * 5.0f);
|
||||||
FlipperEdge->CurrentAngle -= angleAdvance;
|
FlipperEdge->CurrentAngle -= angleAdvance;
|
||||||
FlipperEdge->AngleRemainder += std::fabs(angleAdvance);
|
FlipperEdge->AngleRemainder += std::fabs(angleAdvance);
|
||||||
if (FlipperEdge->AngleRemainder <= 0.0001f)
|
|
||||||
{
|
|
||||||
FlipperEdge->CurrentAngle = FlipperEdge->AngleDst;
|
|
||||||
FlipperEdge->FlipperFlag = MessageCode::TFlipperNull;
|
|
||||||
MessageField = 0;
|
|
||||||
}
|
|
||||||
FlipperEdge->ControlPointDirtyFlag = true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FlipperEdge->CurrentAngle += deltaAngle;
|
FlipperEdge->CurrentAngle += deltaAngle;
|
||||||
FlipperEdge->AngleRemainder -= std::fabs(deltaAngle);
|
FlipperEdge->AngleRemainder -= std::fabs(deltaAngle);
|
||||||
|
}
|
||||||
|
|
||||||
if (FlipperEdge->AngleRemainder <= 0.0001f)
|
if (FlipperEdge->AngleRemainder <= 0.0001f)
|
||||||
{
|
{
|
||||||
FlipperEdge->CurrentAngle = FlipperEdge->AngleDst;
|
FlipperEdge->CurrentAngle = FlipperEdge->AngleDst;
|
||||||
@ -208,4 +202,3 @@ void TFlipper::FlipperCollision(float deltaAngle)
|
|||||||
}
|
}
|
||||||
FlipperEdge->ControlPointDirtyFlag = true;
|
FlipperEdge->ControlPointDirtyFlag = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -14,7 +14,7 @@ public:
|
|||||||
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
|
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
|
||||||
TEdgeSegment* edge) override;
|
TEdgeSegment* edge) override;
|
||||||
void UpdateSprite();
|
void UpdateSprite();
|
||||||
int GetFlipperAngleDistance(float dt, float* dst) const;
|
int GetFlipperStepAngle(float dt, float* dst) const;
|
||||||
void FlipperCollision(float deltaAngle);
|
void FlipperCollision(float deltaAngle);
|
||||||
|
|
||||||
int BmpIndex;
|
int BmpIndex;
|
||||||
|
@ -133,23 +133,24 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float distance)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto someProduct = (NextBallPosition.Y - T1.Y) * (RotOrigin.X - T1.X) -
|
vector2 t1NextPos{NextBallPosition.X - T1.X, NextBallPosition.Y - T1.Y},
|
||||||
(NextBallPosition.X - T1.X) * (RotOrigin.Y - T1.Y);
|
t1RotOrigin{RotOrigin.X - T1.X, RotOrigin.Y - T1.Y};
|
||||||
|
auto crossProduct = maths::cross(t1RotOrigin, t1NextPos);
|
||||||
|
|
||||||
bool someFlag = false;
|
bool frontCollision = false;
|
||||||
if (someProduct <= 0)
|
if (crossProduct <= 0)
|
||||||
{
|
{
|
||||||
if (AngleMax > 0)
|
if (AngleMax > 0)
|
||||||
someFlag = true;
|
frontCollision = true;
|
||||||
}
|
}
|
||||||
else if (AngleMax <= 0)
|
else if (AngleMax <= 0)
|
||||||
{
|
{
|
||||||
someFlag = true;
|
frontCollision = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FlipperFlag == MessageCode::TFlipperRetract)
|
if (FlipperFlag == MessageCode::TFlipperRetract)
|
||||||
{
|
{
|
||||||
someFlag ^= true;
|
frontCollision ^= true;
|
||||||
CollisionLinePerp = LineB.PerpendicularC;
|
CollisionLinePerp = LineB.PerpendicularC;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -160,7 +161,7 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float distance)
|
|||||||
auto dx = NextBallPosition.X - RotOrigin.X;
|
auto dx = NextBallPosition.X - RotOrigin.X;
|
||||||
auto dy = NextBallPosition.Y - RotOrigin.Y;
|
auto dy = NextBallPosition.Y - RotOrigin.Y;
|
||||||
auto distanceSq = dy * dy + dx * dx;
|
auto distanceSq = dy * dy + dx * dx;
|
||||||
if (someFlag)
|
if (frontCollision)
|
||||||
{
|
{
|
||||||
float boost = 0;
|
float boost = 0;
|
||||||
if (circlebase.RadiusSq * 1.01f < distanceSq)
|
if (circlebase.RadiusSq * 1.01f < distanceSq)
|
||||||
@ -204,7 +205,7 @@ void TFlipperEdge::place_in_grid(RectF* aabb)
|
|||||||
|
|
||||||
TTableLayer::edges_insert_square(yMin, xMin, yMax, xMax, this, nullptr);
|
TTableLayer::edges_insert_square(yMin, xMin, yMax, xMax, this, nullptr);
|
||||||
|
|
||||||
auto offset = 1.0f / InvT1Radius + pb::ball_min_smth;
|
auto offset = 1.0f / InvT1Radius + pb::BallHalfRadius;
|
||||||
XMin = xMin - offset;
|
XMin = xMin - offset;
|
||||||
YMin = yMin - offset;
|
YMin = yMin - offset;
|
||||||
XMax = xMax + offset;
|
XMax = xMax + offset;
|
||||||
|
@ -611,7 +611,7 @@ TBall* TPinballTable::AddBall(float x, float y)
|
|||||||
if (ball != nullptr)
|
if (ball != nullptr)
|
||||||
{
|
{
|
||||||
ball->ActiveFlag = 1;
|
ball->ActiveFlag = 1;
|
||||||
ball->Position.Z = ball->Offset;
|
ball->Position.Z = ball->Radius;
|
||||||
ball->Direction = {};
|
ball->Direction = {};
|
||||||
ball->Speed = 0;
|
ball->Speed = 0;
|
||||||
ball->TimeDelta = 0;
|
ball->TimeDelta = 0;
|
||||||
@ -632,8 +632,8 @@ TBall* TPinballTable::AddBall(float x, float y)
|
|||||||
ball->Position.X = x;
|
ball->Position.X = x;
|
||||||
ball->Position.Y = y;
|
ball->Position.Y = y;
|
||||||
ball->PrevPosition = ball->Position;
|
ball->PrevPosition = ball->Position;
|
||||||
ball->SomeCounter1 = 0;
|
ball->StuckCounter = 0;
|
||||||
ball->time_ticks1 = ball->time_ticks2 = pb::time_ticks;
|
ball->LastActiveTime = pb::time_ticks;
|
||||||
|
|
||||||
return ball;
|
return ball;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ void TRamp::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
|
|||||||
ball->RampFieldForce.X = plane->FieldForce.X;
|
ball->RampFieldForce.X = plane->FieldForce.X;
|
||||||
ball->RampFieldForce.Y = plane->FieldForce.Y;
|
ball->RampFieldForce.Y = plane->FieldForce.Y;
|
||||||
ball->Position.Z = ball->Position.X * ball->CollisionOffset.X + ball->Position.Y * ball->CollisionOffset.Y +
|
ball->Position.Z = ball->Position.X * ball->CollisionOffset.X + ball->Position.Y * ball->CollisionOffset.Y +
|
||||||
ball->Offset + ball->CollisionOffset.Z;
|
ball->Radius + ball->CollisionOffset.Z;
|
||||||
ball->CollisionMask = CollisionGroup;
|
ball->CollisionMask = CollisionGroup;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -164,13 +164,13 @@ void TRamp::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
|
|||||||
{
|
{
|
||||||
ball->CollisionMask = Wall1CollisionGroup;
|
ball->CollisionMask = Wall1CollisionGroup;
|
||||||
if (BallZOffsetFlag)
|
if (BallZOffsetFlag)
|
||||||
ball->Position.Z = ball->Offset + Wall1BallOffset;
|
ball->Position.Z = ball->Radius + Wall1BallOffset;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ball->CollisionMask = Wall2CollisionGroup;
|
ball->CollisionMask = Wall2CollisionGroup;
|
||||||
if (BallZOffsetFlag)
|
if (BallZOffsetFlag)
|
||||||
ball->Position.Z = ball->Offset + Wall2BallOffset;
|
ball->Position.Z = ball->Radius + Wall2BallOffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "TPinballTable.h"
|
#include "TPinballTable.h"
|
||||||
#include "TBall.h"
|
#include "TBall.h"
|
||||||
|
#include "TDrain.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
TSink::TSink(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
TSink::TSink(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, true)
|
||||||
@ -59,7 +60,7 @@ void TSink::Collision(TBall* ball, vector2* nextPosition, vector2* direction, fl
|
|||||||
{
|
{
|
||||||
if (PinballTable->TiltLockFlag)
|
if (PinballTable->TiltLockFlag)
|
||||||
{
|
{
|
||||||
maths::basic_collision(ball, nextPosition, direction, Elasticity, Smoothness, 1000000000.0, 0.0);
|
PinballTable->Drain->Collision(ball, nextPosition, direction, distance, edge);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1063,13 +1063,13 @@ void control::cheat_bump_rank()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void control::BallThrowOrDisable(TBall& ball, int dt)
|
void control::UnstuckBall(TBall& ball, int dt)
|
||||||
{
|
{
|
||||||
if (!CheckBallInControlBounds(ball, *flip1) &&
|
if (!CheckBallInControlBounds(ball, *flip1) &&
|
||||||
!CheckBallInControlBounds(ball, *flip2) &&
|
!CheckBallInControlBounds(ball, *flip2) &&
|
||||||
!CheckBallInControlBounds(ball, *plunger))
|
!CheckBallInControlBounds(ball, *plunger))
|
||||||
{
|
{
|
||||||
if (ball.SomeCounter1 <= 20)
|
if (ball.StuckCounter <= 20)
|
||||||
{
|
{
|
||||||
vector3 throwDir{0.0f, -1.0f, 0.0f};
|
vector3 throwDir{0.0f, -1.0f, 0.0f};
|
||||||
ball.throw_ball(&throwDir, 90.0f, 1.0f, 0.0f);
|
ball.throw_ball(&throwDir, 90.0f, 1.0f, 0.0f);
|
||||||
|
@ -89,7 +89,7 @@ public:
|
|||||||
static void table_set_multiball(float time);
|
static void table_set_multiball(float time);
|
||||||
static void table_bump_ball_sink_lock();
|
static void table_bump_ball_sink_lock();
|
||||||
static void table_set_replay(float value);
|
static void table_set_replay(float value);
|
||||||
static void BallThrowOrDisable(TBall& ball, int dt);
|
static void UnstuckBall(TBall& ball, int dt);
|
||||||
static bool CheckBallInControlBounds(const TBall& ball, const TCollisionComponent& cmp);
|
static bool CheckBallInControlBounds(const TBall& ball, const TCollisionComponent& cmp);
|
||||||
static void cheat_bump_rank();
|
static void cheat_bump_rank();
|
||||||
static int SpecialAddScore(int score);
|
static int SpecialAddScore(int score);
|
||||||
|
@ -222,6 +222,11 @@ float maths::magnitudeSq(const vector2& vec)
|
|||||||
return vec.X * vec.X + vec.Y * vec.Y;
|
return vec.X * vec.X + vec.Y * vec.Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int maths::magnitudeSq(const vector2i& vec)
|
||||||
|
{
|
||||||
|
return vec.X * vec.X + vec.Y * vec.Y;
|
||||||
|
}
|
||||||
|
|
||||||
void maths::vector_add(vector2& vec1Dst, const vector2& vec2)
|
void maths::vector_add(vector2& vec1Dst, const vector2& vec2)
|
||||||
{
|
{
|
||||||
vec1Dst.X += vec2.X;
|
vec1Dst.X += vec2.X;
|
||||||
|
@ -53,7 +53,6 @@ struct ray_type
|
|||||||
float MaxDistance;
|
float MaxDistance;
|
||||||
float MinDistance;
|
float MinDistance;
|
||||||
float TimeNow;
|
float TimeNow;
|
||||||
float TimeDelta;
|
|
||||||
int CollisionMask;
|
int CollisionMask;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -115,6 +114,7 @@ public:
|
|||||||
static float cross(const vector2& vec1, const vector2& vec2);
|
static float cross(const vector2& vec1, const vector2& vec2);
|
||||||
static float magnitude(const vector3& vec);
|
static float magnitude(const vector3& vec);
|
||||||
static float magnitudeSq(const vector2& vec);
|
static float magnitudeSq(const vector2& vec);
|
||||||
|
static int magnitudeSq(const vector2i& vec);
|
||||||
static void vector_add(vector2& vec1Dst, const vector2& vec2);
|
static void vector_add(vector2& vec1Dst, const vector2& vec2);
|
||||||
static vector2 vector_sub(const vector2& vec1, const vector2& vec2);
|
static vector2 vector_sub(const vector2& vec1, const vector2& vec2);
|
||||||
static vector3 vector_sub(const vector3& vec1, const vector3& vec2);
|
static vector3 vector_sub(const vector3& vec1, const vector3& vec2);
|
||||||
|
@ -33,7 +33,7 @@ DatFile* pb::record_table = nullptr;
|
|||||||
int pb::time_ticks = 0;
|
int pb::time_ticks = 0;
|
||||||
GameModes pb::game_mode = GameModes::GameOver;
|
GameModes pb::game_mode = GameModes::GameOver;
|
||||||
float pb::time_now = 0, pb::time_next = 0, pb::time_ticks_remainder = 0;
|
float pb::time_now = 0, pb::time_next = 0, pb::time_ticks_remainder = 0;
|
||||||
float pb::ball_speed_limit, pb::ball_min_smth, pb::ball_inv_smth, pb::ball_collision_dist;
|
float pb::BallMaxSpeed, pb::BallHalfRadius, pb::ball_collision_dist;
|
||||||
bool pb::FullTiltMode = false, pb::FullTiltDemoMode = false, pb::cheat_mode = false, pb::demo_mode = false;
|
bool pb::FullTiltMode = false, pb::FullTiltDemoMode = false, pb::cheat_mode = false, pb::demo_mode = false;
|
||||||
std::string pb::DatFileName, pb::BasePath;
|
std::string pb::DatFileName, pb::BasePath;
|
||||||
ImU32 pb::TextBoxColor;
|
ImU32 pb::TextBoxColor;
|
||||||
@ -104,10 +104,9 @@ int pb::init()
|
|||||||
|
|
||||||
high_score::read();
|
high_score::read();
|
||||||
auto ball = MainTable->BallList.at(0);
|
auto ball = MainTable->BallList.at(0);
|
||||||
ball_speed_limit = ball->Offset * 200.0f;
|
BallMaxSpeed = ball->Radius * 200.0f;
|
||||||
ball_min_smth = ball->Offset * 0.5f;
|
BallHalfRadius = ball->Radius * 0.5f;
|
||||||
ball_inv_smth = 1.0f / ball_min_smth;
|
ball_collision_dist = (ball->Radius + BallHalfRadius) * 2.0f;
|
||||||
ball_collision_dist = (ball->Offset + ball_min_smth) * 2.0f;
|
|
||||||
|
|
||||||
int red = 255, green = 255, blue = 255;
|
int red = 255, green = 255, blue = 255;
|
||||||
auto fontColor = get_rc_string(Msg::TextBoxColor);
|
auto fontColor = get_rc_string(Msg::TextBoxColor);
|
||||||
@ -272,6 +271,7 @@ void pb::ballset(float dx, float dy)
|
|||||||
ball->Direction.X = dx * sensitivity;
|
ball->Direction.X = dx * sensitivity;
|
||||||
ball->Direction.Y = dy * sensitivity;
|
ball->Direction.Y = dy * sensitivity;
|
||||||
ball->Speed = maths::normalize_2d(ball->Direction);
|
ball->Speed = maths::normalize_2d(ball->Direction);
|
||||||
|
ball->LastActiveTime = time_ticks;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -320,115 +320,103 @@ void pb::frame(float dtMilliSec)
|
|||||||
|
|
||||||
void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls)
|
void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls)
|
||||||
{
|
{
|
||||||
vector2 vec1{}, vec2{};
|
|
||||||
|
|
||||||
for (auto ball : MainTable->BallList)
|
for (auto ball : MainTable->BallList)
|
||||||
{
|
{
|
||||||
if (!ball->ActiveFlag || ball->HasGroupFlag || ball->CollisionComp || ball->Speed >= 0.8f)
|
if (!ball->ActiveFlag || ball->HasGroupFlag || ball->CollisionComp || ball->Speed >= 0.8f)
|
||||||
{
|
{
|
||||||
if (ball->SomeCounter1 > 0)
|
if (ball->StuckCounter > 0)
|
||||||
{
|
{
|
||||||
vector2 dxy{ball->Position.X - ball->PrevPosition.X, ball->Position.Y - ball->PrevPosition.Y};
|
vector2 dist{ball->Position.X - ball->PrevPosition.X, ball->Position.Y - ball->PrevPosition.Y};
|
||||||
auto offsetX2 = ball->Offset * 2.0f;
|
auto radiusX2 = ball->Radius * 2.0f;
|
||||||
if (offsetX2 * offsetX2 < maths::magnitudeSq(dxy))
|
if (radiusX2 * radiusX2 < maths::magnitudeSq(dist))
|
||||||
ball->SomeCounter1 = 0;
|
ball->StuckCounter = 0;
|
||||||
}
|
}
|
||||||
ball->time_ticks1 = ball->time_ticks2 = time_ticks;
|
ball->LastActiveTime = time_ticks;
|
||||||
}
|
}
|
||||||
else if (time_ticks - ball->time_ticks2 > 500)
|
else if (time_ticks - ball->LastActiveTime > 500)
|
||||||
{
|
{
|
||||||
vector2 dxy{ball->Position.X - ball->PrevPosition.X, ball->Position.Y - ball->PrevPosition.Y};
|
vector2 dist{ball->Position.X - ball->PrevPosition.X, ball->Position.Y - ball->PrevPosition.Y};
|
||||||
auto offsetD2 = ball->Offset / 2.0f;
|
auto radiusD2 = ball->Radius / 2.0f;
|
||||||
ball->PrevPosition = ball->Position;
|
ball->PrevPosition = ball->Position;
|
||||||
if (offsetD2 * offsetD2 < maths::magnitudeSq(dxy))
|
if (radiusD2 * radiusD2 < maths::magnitudeSq(dist))
|
||||||
ball->SomeCounter1 = 0;
|
ball->StuckCounter = 0;
|
||||||
else
|
else
|
||||||
ball->SomeCounter1++;
|
ball->StuckCounter++;
|
||||||
control::BallThrowOrDisable(*ball, time_ticks - ball->time_ticks1);
|
control::UnstuckBall(*ball, time_ticks - ball->LastActiveTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int distanceCoefArray[20]{-1};
|
int ballSteps[20]{-1};
|
||||||
float distanceArray[20]{}, distanceArrayX[20]{}, distanceArrayY[20]{};
|
float ballStepsDistance[20]{};
|
||||||
int minDistanceCoef = -1;
|
int maxStep = -1;
|
||||||
for (auto index = 0u; index < MainTable->BallList.size(); index++)
|
for (auto index = 0u; index < MainTable->BallList.size(); index++)
|
||||||
{
|
{
|
||||||
auto ball = MainTable->BallList[index];
|
auto ball = MainTable->BallList[index];
|
||||||
if (ball->ActiveFlag != 0)
|
if (ball->ActiveFlag != 0)
|
||||||
{
|
{
|
||||||
|
vector2 vecDst{};
|
||||||
ball->TimeDelta = timeDelta;
|
ball->TimeDelta = timeDelta;
|
||||||
if (ball->TimeDelta > 0.01f && ball->Speed < 0.8f)
|
if (ball->TimeDelta > 0.01f && ball->Speed < 0.8f)
|
||||||
ball->TimeDelta = 0.01f;
|
ball->TimeDelta = 0.01f;
|
||||||
ball->AsEdgeCollisionFlag = false;
|
ball->AsEdgeCollisionFlag = false;
|
||||||
if (ball->CollisionComp)
|
if (ball->CollisionComp)
|
||||||
{
|
{
|
||||||
ball->CollisionComp->FieldEffect(ball, &vec1);
|
ball->CollisionComp->FieldEffect(ball, &vecDst);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (MainTable->ActiveFlag)
|
TTableLayer::edge_manager->FieldEffects(ball, &vecDst);
|
||||||
{
|
vecDst.X *= timeDelta;
|
||||||
vec2.X = 0.0;
|
vecDst.Y *= timeDelta;
|
||||||
vec2.Y = 0.0;
|
ball->Direction.X *= ball->Speed;
|
||||||
TTableLayer::edge_manager->FieldEffects(ball, &vec2);
|
ball->Direction.Y *= ball->Speed;
|
||||||
vec2.X = vec2.X * timeDelta;
|
maths::vector_add(ball->Direction, vecDst);
|
||||||
vec2.Y = vec2.Y * timeDelta;
|
|
||||||
ball->Direction.X = ball->Speed * ball->Direction.X;
|
|
||||||
ball->Direction.Y = ball->Speed * ball->Direction.Y;
|
|
||||||
maths::vector_add(ball->Direction, vec2);
|
|
||||||
ball->Speed = maths::normalize_2d(ball->Direction);
|
ball->Speed = maths::normalize_2d(ball->Direction);
|
||||||
if (ball->Speed > ball_speed_limit)
|
if (ball->Speed > BallMaxSpeed)
|
||||||
ball->Speed = ball_speed_limit;
|
ball->Speed = BallMaxSpeed;
|
||||||
|
|
||||||
distanceArray[index] = ball->Speed * ball->TimeDelta;
|
ballStepsDistance[index] = ball->Speed * ball->TimeDelta;
|
||||||
auto distanceCoef = static_cast<int>(std::ceil(distanceArray[index] * ball_inv_smth)) - 1;
|
auto ballStep = static_cast<int>(std::ceil(ballStepsDistance[index] / BallHalfRadius)) - 1;
|
||||||
distanceCoefArray[index] = distanceCoef;
|
ballSteps[index] = ballStep;
|
||||||
if (distanceCoef >= 0)
|
if (ballStep > maxStep)
|
||||||
{
|
maxStep = ballStep;
|
||||||
distanceArrayX[index] = ball->Direction.X * ball_min_smth;
|
|
||||||
distanceArrayY[index] = ball->Direction.Y * ball_min_smth;
|
|
||||||
if (distanceCoef > minDistanceCoef)
|
|
||||||
minDistanceCoef = distanceCoef;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float deltaAngle[4]{};
|
float deltaAngle[4]{};
|
||||||
|
int flipperSteps[4]{};
|
||||||
for (auto index = 0u; index < MainTable->FlipperList.size(); index++)
|
for (auto index = 0u; index < MainTable->FlipperList.size(); index++)
|
||||||
{
|
{
|
||||||
auto distanceCoef = MainTable->FlipperList[index]->GetFlipperAngleDistance(timeDelta, &deltaAngle[index]) - 1;
|
auto flipStep = MainTable->FlipperList[index]->GetFlipperStepAngle(timeDelta, &deltaAngle[index]) - 1;
|
||||||
distanceArrayY[index] = static_cast<float>(distanceCoef);
|
flipperSteps[index] = flipStep;
|
||||||
if (distanceCoef > minDistanceCoef)
|
if (flipStep > maxStep)
|
||||||
minDistanceCoef = distanceCoef;
|
maxStep = flipStep;
|
||||||
}
|
}
|
||||||
|
|
||||||
ray_type ray{};
|
ray_type ray{};
|
||||||
ray.MinDistance = 0.002f;
|
ray.MinDistance = 0.002f;
|
||||||
for (auto index4 = 0; index4 <= minDistanceCoef; index4++)
|
for (auto step = 0; step <= maxStep; step++)
|
||||||
{
|
{
|
||||||
for (auto index5 = 0u; index5 < MainTable->BallList.size(); index5++)
|
for (auto ballIndex = 0u; ballIndex < MainTable->BallList.size(); ballIndex++)
|
||||||
{
|
{
|
||||||
auto ball = MainTable->BallList[index5];
|
auto ball = MainTable->BallList[ballIndex];
|
||||||
if (!ball->AsEdgeCollisionFlag && index4 <= distanceCoefArray[index5])
|
if (!ball->AsEdgeCollisionFlag && step <= ballSteps[ballIndex])
|
||||||
{
|
{
|
||||||
float distanceSum = 0.0f;
|
|
||||||
ray.CollisionMask = ball->CollisionMask;
|
ray.CollisionMask = ball->CollisionMask;
|
||||||
ball->TimeNow = timeNow;
|
ball->TimeNow = timeNow;
|
||||||
if (ball_min_smth > 0.0f)
|
|
||||||
{
|
for (auto distanceSum = 0.0f; distanceSum < BallHalfRadius;)
|
||||||
while (true)
|
|
||||||
{
|
{
|
||||||
ray.Origin = ball->Position;
|
ray.Origin = ball->Position;
|
||||||
ray.Direction = ball->Direction;
|
ray.Direction = ball->Direction;
|
||||||
if (index4 >= distanceCoefArray[index5])
|
if (step >= ballSteps[ballIndex])
|
||||||
{
|
{
|
||||||
ray.MaxDistance = distanceArray[index5] - distanceCoefArray[index5] * ball_min_smth;
|
ray.MaxDistance = ballStepsDistance[ballIndex] - ballSteps[ballIndex] * BallHalfRadius;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ray.MaxDistance = ball_min_smth;
|
ray.MaxDistance = BallHalfRadius;
|
||||||
}
|
}
|
||||||
ray.TimeNow = ball->TimeNow;
|
ray.TimeNow = ball->TimeNow;
|
||||||
|
|
||||||
@ -456,22 +444,17 @@ void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls)
|
|||||||
}
|
}
|
||||||
|
|
||||||
edge->EdgeCollision(ball, distance);
|
edge->EdgeCollision(ball, distance);
|
||||||
if (distance > 0.0f && !ball->AsEdgeCollisionFlag)
|
if (distance <= 0.0f || ball->AsEdgeCollisionFlag)
|
||||||
{
|
|
||||||
distanceSum += distance;
|
|
||||||
if (distanceSum < ball_min_smth)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
distanceSum += distance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto index = 0u; index < MainTable->FlipperList.size(); index++)
|
for (auto flipIndex = 0u; flipIndex < MainTable->FlipperList.size(); flipIndex++)
|
||||||
{
|
{
|
||||||
if (distanceArrayY[index] >= index4)
|
if (flipperSteps[flipIndex] >= step)
|
||||||
MainTable->FlipperList[index]->FlipperCollision(deltaAngle[index]);
|
MainTable->FlipperList[flipIndex]->FlipperCollision(deltaAngle[flipIndex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -744,50 +727,6 @@ bool pb::chk_highscore()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float pb::collide(float timeNow, float timeDelta, TBall* ball)
|
|
||||||
{
|
|
||||||
ray_type ray{};
|
|
||||||
vector2 positionMod{};
|
|
||||||
|
|
||||||
if (ball->ActiveFlag && !ball->CollisionComp)
|
|
||||||
{
|
|
||||||
if (ball_speed_limit < ball->Speed)
|
|
||||||
ball->Speed = ball_speed_limit;
|
|
||||||
|
|
||||||
auto maxDistance = timeDelta * ball->Speed;
|
|
||||||
ball->TimeDelta = timeDelta;
|
|
||||||
ball->RayMaxDistance = maxDistance;
|
|
||||||
ball->TimeNow = timeNow;
|
|
||||||
|
|
||||||
ray.Origin = ball->Position;
|
|
||||||
ray.Direction = ball->Direction;
|
|
||||||
ray.MaxDistance = maxDistance;
|
|
||||||
ray.CollisionMask = ball->CollisionMask;
|
|
||||||
ray.TimeNow = timeNow;
|
|
||||||
ray.TimeDelta = timeDelta;
|
|
||||||
ray.MinDistance = 0.0020000001f;
|
|
||||||
|
|
||||||
TEdgeSegment* edge = nullptr;
|
|
||||||
auto distance = TTableLayer::edge_manager->FindCollisionDistance(&ray, ball, &edge);
|
|
||||||
ball->EdgeCollisionCount = 0;
|
|
||||||
if (distance >= 1000000000.0f)
|
|
||||||
{
|
|
||||||
maxDistance = timeDelta * ball->Speed;
|
|
||||||
ball->RayMaxDistance = maxDistance;
|
|
||||||
positionMod.X = maxDistance * ball->Direction.X;
|
|
||||||
positionMod.Y = maxDistance * ball->Direction.Y;
|
|
||||||
maths::vector_add(ball->Position, positionMod);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
edge->EdgeCollision(ball, distance);
|
|
||||||
if (ball->Speed > 0.000000001f)
|
|
||||||
return fabs(distance / ball->Speed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return timeDelta;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pb::PushCheat(const std::string& cheat)
|
void pb::PushCheat(const std::string& cheat)
|
||||||
{
|
{
|
||||||
for (auto ch : cheat)
|
for (auto ch : cheat)
|
||||||
|
@ -43,7 +43,7 @@ class pb
|
|||||||
public:
|
public:
|
||||||
static int time_ticks;
|
static int time_ticks;
|
||||||
static float time_now, time_next, time_ticks_remainder;
|
static float time_now, time_next, time_ticks_remainder;
|
||||||
static float ball_speed_limit, ball_min_smth, ball_inv_smth, ball_collision_dist;
|
static float BallMaxSpeed, BallHalfRadius, ball_collision_dist;
|
||||||
static GameModes game_mode;
|
static GameModes game_mode;
|
||||||
static bool cheat_mode;
|
static bool cheat_mode;
|
||||||
static DatFile* record_table;
|
static DatFile* record_table;
|
||||||
@ -74,7 +74,6 @@ public:
|
|||||||
static void high_scores();
|
static void high_scores();
|
||||||
static void tilt_no_more();
|
static void tilt_no_more();
|
||||||
static bool chk_highscore();
|
static bool chk_highscore();
|
||||||
static float collide(float timeNow, float timeDelta, TBall* ball);
|
|
||||||
static void PushCheat(const std::string& cheat);
|
static void PushCheat(const std::string& cheat);
|
||||||
static LPCSTR get_rc_string(Msg uID);
|
static LPCSTR get_rc_string(Msg uID);
|
||||||
static int get_rc_int(Msg uID, int* dst);
|
static int get_rc_int(Msg uID, int* dst);
|
||||||
|
@ -786,6 +786,7 @@ void winmain::RenderUi()
|
|||||||
ShowExitPopup = false;
|
ShowExitPopup = false;
|
||||||
pause(false);
|
pause(false);
|
||||||
ImGui::OpenPopup(exitText);
|
ImGui::OpenPopup(exitText);
|
||||||
|
ImGui::SetNextWindowPos(ImGui::GetMainViewport()->GetCenter(), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||||
}
|
}
|
||||||
if (ImGui::BeginPopupModal(exitText, nullptr, ImGuiWindowFlags_AlwaysAutoResize))
|
if (ImGui::BeginPopupModal(exitText, nullptr, ImGuiWindowFlags_AlwaysAutoResize))
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user