mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-12-18 10:37:53 +01:00
Code from FT: simplified TFlipper sprite update.
TFlipperEdge moving geometry stored in object.
This commit is contained in:
parent
7feba1e947
commit
acd1ad34b2
9 changed files with 113 additions and 175 deletions
|
@ -296,11 +296,10 @@ void DebugOverlay::DrawEdge(TEdgeSegment* edge)
|
|||
if (flip)
|
||||
{
|
||||
flip->set_control_points(pb::time_now);
|
||||
flip->build_edges_in_motion();
|
||||
|
||||
DrawLineType(TFlipperEdge::lineA);
|
||||
DrawLineType(TFlipperEdge::lineB);
|
||||
DrawCicleType(TFlipperEdge::circlebase);
|
||||
DrawCicleType(TFlipperEdge::circleT1);
|
||||
DrawLineType(flip->lineA);
|
||||
DrawLineType(flip->lineB);
|
||||
DrawCicleType(flip->circlebase);
|
||||
DrawCicleType(flip->circleT1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,19 +18,11 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
|
|||
HardHitSoundId = visual.SoundIndex4;
|
||||
SoftHitSoundId = visual.SoundIndex3;
|
||||
Elasticity = visual.Elasticity;
|
||||
Timer = 0;
|
||||
Smoothness = visual.Smoothness;
|
||||
|
||||
auto collMult = *loader::query_float_attribute(groupIndex, 0, 803);
|
||||
auto retractTime = *loader::query_float_attribute(groupIndex, 0, 805);
|
||||
auto extendTime = *loader::query_float_attribute(groupIndex, 0, 804);
|
||||
|
||||
/*Full tilt hack: different flipper speed*/
|
||||
if (pb::FullTiltMode)
|
||||
{
|
||||
retractTime = 0.08f;
|
||||
extendTime = 0.04f;
|
||||
}
|
||||
auto vecT2 = reinterpret_cast<vector3*>(loader::query_float_attribute(groupIndex, 0, 802));
|
||||
auto vecT1 = reinterpret_cast<vector3*>(loader::query_float_attribute(groupIndex, 0, 801));
|
||||
auto origin = reinterpret_cast<vector3*>(loader::query_float_attribute(groupIndex, 0, 800));
|
||||
|
@ -49,75 +41,53 @@ TFlipper::TFlipper(TPinballTable* table, int groupIndex) : TCollisionComponent(t
|
|||
Smoothness);
|
||||
|
||||
FlipperEdge = flipperEdge;
|
||||
if (flipperEdge)
|
||||
{
|
||||
ExtendAnimationFrameTime = flipperEdge->ExtendTime / static_cast<float>(ListBitmap->size() - 1);
|
||||
RetractAnimationFrameTime = flipperEdge->RetractTime / static_cast<float>(ListBitmap->size() - 1);
|
||||
}
|
||||
BmpIndex = 0;
|
||||
InputTime = 0.0;
|
||||
if (table)
|
||||
table->FlipperList.push_back(this);
|
||||
}
|
||||
|
||||
TFlipper::~TFlipper()
|
||||
{
|
||||
delete FlipperEdge;
|
||||
if (PinballTable)
|
||||
{
|
||||
auto& flippers = PinballTable->FlipperList;
|
||||
auto position = std::find(flippers.begin(), flippers.end(), this);
|
||||
if (position != flippers.end())
|
||||
flippers.erase(position);
|
||||
}
|
||||
}
|
||||
|
||||
int TFlipper::Message(int code, float value)
|
||||
{
|
||||
if (code == 1 || code == 2 || (code > 1008 && code <= 1011) || code == 1022)
|
||||
{
|
||||
float timerTime;
|
||||
int command = code;
|
||||
if (code == 1)
|
||||
{
|
||||
control::handler(1, this);
|
||||
TimerTime = ExtendAnimationFrameTime;
|
||||
loader::play_sound(HardHitSoundId, this, "TFlipper1");
|
||||
}
|
||||
else if (code == 2)
|
||||
{
|
||||
TimerTime = RetractAnimationFrameTime;
|
||||
loader::play_sound(SoftHitSoundId, this, "TFlipper2");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Retract for all non-input messages
|
||||
command = 2;
|
||||
TimerTime = RetractAnimationFrameTime;
|
||||
code = 2;
|
||||
}
|
||||
|
||||
if (MessageField)
|
||||
{
|
||||
// Message arrived before animation is finished
|
||||
auto inputDt = value - FlipperEdge->InputTime;
|
||||
timerTime = inputDt - floor(inputDt / TimerTime) * TimerTime;
|
||||
if (timerTime < 0.0f)
|
||||
timerTime = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
timerTime = TimerTime;
|
||||
}
|
||||
|
||||
MessageField = command;
|
||||
InputTime = value;
|
||||
if (Timer)
|
||||
timer::kill(Timer);
|
||||
Timer = timer::set(timerTime, this, TimerExpired);
|
||||
FlipperEdge->SetMotion(command, value);
|
||||
MessageField = FlipperEdge->SetMotion(code, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (code == 1020 || code == 1024)
|
||||
{
|
||||
if (MessageField)
|
||||
{
|
||||
if (Timer)
|
||||
timer::kill(Timer);
|
||||
BmpIndex = -1;
|
||||
MessageField = 2;
|
||||
TimerExpired(Timer, this);
|
||||
FlipperEdge->SetMotion(code, value);
|
||||
MessageField = 0;
|
||||
FlipperEdge->SetMotion(1024, value);
|
||||
UpdateSprite(0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -132,53 +102,22 @@ void TFlipper::Collision(TBall* ball, vector2* nextPosition, vector2* direction,
|
|||
{
|
||||
}
|
||||
|
||||
void TFlipper::TimerExpired(int timerId, void* caller)
|
||||
void TFlipper::UpdateSprite(float timeNow)
|
||||
{
|
||||
auto flip = static_cast<TFlipper*>(caller);
|
||||
int bmpCountSub1 = flip->ListBitmap->size() - 1;
|
||||
int bmpCountSub1 = ListBitmap->size() - 1;
|
||||
|
||||
auto newBmpIndex = static_cast<int>(floor(flip->FlipperEdge->flipper_angle(pb::time_now) / flip->FlipperEdge->AngleMax * bmpCountSub1 + 0.5));
|
||||
if (newBmpIndex > bmpCountSub1)
|
||||
newBmpIndex = bmpCountSub1;
|
||||
if (newBmpIndex < 0)
|
||||
newBmpIndex = 0;
|
||||
auto newBmpIndex = static_cast<int>(floor(FlipperEdge->flipper_angle(timeNow) / FlipperEdge->AngleMax * bmpCountSub1 + 0.5f));
|
||||
newBmpIndex = Clamp(newBmpIndex, 0, bmpCountSub1);
|
||||
if (BmpIndex == newBmpIndex)
|
||||
return;
|
||||
|
||||
bool bmpIndexOutOfBounds = false;
|
||||
if (flip->MessageField == 1)
|
||||
{
|
||||
flip->BmpIndex = newBmpIndex;
|
||||
if (flip->BmpIndex >= bmpCountSub1)
|
||||
{
|
||||
flip->BmpIndex = bmpCountSub1;
|
||||
bmpIndexOutOfBounds = true;
|
||||
}
|
||||
}
|
||||
if (flip->MessageField == 2)
|
||||
{
|
||||
flip->BmpIndex = newBmpIndex;
|
||||
if (flip->BmpIndex <= 0)
|
||||
{
|
||||
flip->BmpIndex = 0;
|
||||
bmpIndexOutOfBounds = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (bmpIndexOutOfBounds)
|
||||
{
|
||||
flip->MessageField = 0;
|
||||
flip->Timer = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
flip->Timer = timer::set(flip->TimerTime, flip, TimerExpired);
|
||||
}
|
||||
|
||||
auto bmp = flip->ListBitmap->at(flip->BmpIndex);
|
||||
auto zMap = flip->ListZMap->at(flip->BmpIndex);
|
||||
BmpIndex = newBmpIndex;
|
||||
auto bmp = ListBitmap->at(BmpIndex);
|
||||
auto zMap = ListZMap->at(BmpIndex);
|
||||
render::sprite_set(
|
||||
flip->RenderSprite,
|
||||
RenderSprite,
|
||||
bmp,
|
||||
zMap,
|
||||
bmp->XPosition - flip->PinballTable->XOffset,
|
||||
bmp->YPosition - flip->PinballTable->YOffset);
|
||||
bmp->XPosition - PinballTable->XOffset,
|
||||
bmp->YPosition - PinballTable->YOffset);
|
||||
}
|
||||
|
|
|
@ -13,14 +13,8 @@ public:
|
|||
void port_draw() override;
|
||||
void Collision(TBall* ball, vector2* nextPosition, vector2* direction, float distance,
|
||||
TEdgeSegment* edge) override;
|
||||
|
||||
static void TimerExpired(int timerId, void* caller);
|
||||
void UpdateSprite(float timeNow);
|
||||
|
||||
int BmpIndex;
|
||||
TFlipperEdge* FlipperEdge;
|
||||
int Timer;
|
||||
float ExtendAnimationFrameTime{};
|
||||
float RetractAnimationFrameTime{};
|
||||
float TimerTime{};
|
||||
float InputTime;
|
||||
};
|
||||
|
|
|
@ -2,14 +2,11 @@
|
|||
#include "TFlipperEdge.h"
|
||||
|
||||
|
||||
#include "pb.h"
|
||||
#include "TLine.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TTableLayer.h"
|
||||
|
||||
float TFlipperEdge::flipper_sin_angle, TFlipperEdge::flipper_cos_angle;
|
||||
vector2 TFlipperEdge::A1, TFlipperEdge::A2, TFlipperEdge::B1, TFlipperEdge::B2, TFlipperEdge::T1;
|
||||
line_type TFlipperEdge::lineA, TFlipperEdge::lineB;
|
||||
circle_type TFlipperEdge::circlebase, TFlipperEdge::circleT1;
|
||||
|
||||
TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup, TPinballTable* table,
|
||||
vector3* origin, vector3* vecT1, vector3* vecT2, float extendTime, float retractTime,
|
||||
|
@ -19,8 +16,6 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
|
|||
|
||||
Elasticity = elasticity;
|
||||
Smoothness = smoothness;
|
||||
ExtendTime = extendTime;
|
||||
RetractTime = retractTime;
|
||||
CollisionMult = collMult;
|
||||
|
||||
T1Src = static_cast<vector2>(*vecT1);
|
||||
|
@ -51,7 +46,19 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
|
|||
if (crossProd.Z < 0.0f)
|
||||
AngleMax = -AngleMax;
|
||||
FlipperFlag = 0;
|
||||
Angle1 = 0.0;
|
||||
AngleDst = 0.0;
|
||||
|
||||
// 3DPB and FT have different formats for flipper speed:
|
||||
// 3DPB: Time it takes for flipper to go from source to destination, in sec.
|
||||
// FT: Flipper movement speed, in radians per sec.
|
||||
if (pb::FullTiltMode)
|
||||
{
|
||||
auto angleMax = std::abs(AngleMax);
|
||||
retractTime = angleMax / retractTime;
|
||||
extendTime = angleMax / extendTime;
|
||||
}
|
||||
ExtendTime = extendTime;
|
||||
RetractTime = retractTime;
|
||||
|
||||
auto dirX1 = vecDir1.X;
|
||||
auto dirY1 = -vecDir1.Y;
|
||||
|
@ -87,13 +94,12 @@ TFlipperEdge::TFlipperEdge(TCollisionComponent* collComp, char* activeFlag, unsi
|
|||
InputTime = 0.0;
|
||||
CollisionFlag1 = 0;
|
||||
AngleStopTime = 0.0;
|
||||
AngleMult = 0.0;
|
||||
AngleAdvanceTime = 0.0;
|
||||
}
|
||||
|
||||
void TFlipperEdge::port_draw()
|
||||
{
|
||||
set_control_points(InputTime);
|
||||
build_edges_in_motion();
|
||||
}
|
||||
|
||||
float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
||||
|
@ -112,7 +118,6 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||
CollisionFlag1 = 0;
|
||||
CollisionFlag2 = 0;
|
||||
set_control_points(ogRay->TimeNow);
|
||||
build_edges_in_motion();
|
||||
auto ballInside = is_ball_inside(ogRay->Origin.X, ogRay->Origin.Y);
|
||||
srcRay.MinDistance = ogRay->MinDistance;
|
||||
if (ballInside == 0)
|
||||
|
@ -120,7 +125,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||
srcRay.Direction = ogRay->Direction;
|
||||
srcRay.MaxDistance = ogRay->MaxDistance;
|
||||
srcRay.Origin = ogRay->Origin;
|
||||
auto distance = maths::distance_to_flipper(srcRay, dstRay);
|
||||
auto distance = maths::distance_to_flipper(this, srcRay, dstRay);
|
||||
if (distance == 0.0f)
|
||||
{
|
||||
NextBallPosition = dstRay.Origin;
|
||||
|
@ -166,14 +171,14 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||
srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f;
|
||||
srcRay.Origin.Y = ogRay->Origin.Y - srcRay.Direction.Y * 5.0f;
|
||||
srcRay.MaxDistance = ogRay->MaxDistance + 10.0f;
|
||||
if (maths::distance_to_flipper(srcRay, dstRay) >= 1e+09f)
|
||||
if (maths::distance_to_flipper(this, srcRay, dstRay) >= 1e+09f)
|
||||
{
|
||||
srcRay.Direction.X = RotOrigin.X - ogRay->Origin.X;
|
||||
srcRay.Direction.Y = RotOrigin.Y - ogRay->Origin.Y;
|
||||
maths::normalize_2d(srcRay.Direction);
|
||||
srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f;
|
||||
srcRay.Origin.Y = ogRay->Origin.Y - srcRay.Direction.Y * 5.0f;
|
||||
if (maths::distance_to_flipper(srcRay, dstRay) >= 1e+09f)
|
||||
if (maths::distance_to_flipper(this, srcRay, dstRay) >= 1e+09f)
|
||||
{
|
||||
return 1e+09;
|
||||
}
|
||||
|
@ -196,7 +201,6 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||
while (timeNow < stopTime)
|
||||
{
|
||||
set_control_points(timeNow);
|
||||
build_edges_in_motion();
|
||||
auto ballInside = is_ball_inside(posX, posY);
|
||||
if (ballInside != 0)
|
||||
{
|
||||
|
@ -220,7 +224,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||
srcRay.Origin.X = posX - srcRay.Direction.X * 5.0f;
|
||||
srcRay.Origin.Y = posY - srcRay.Direction.Y * 5.0f;
|
||||
srcRay.MaxDistance = ogRay->MaxDistance + 10.0f;
|
||||
if (maths::distance_to_flipper(srcRay, dstRay) >= 1e+09f)
|
||||
if (maths::distance_to_flipper(this, srcRay, dstRay) >= 1e+09f)
|
||||
{
|
||||
NextBallPosition.X = posX;
|
||||
NextBallPosition.Y = posY;
|
||||
|
@ -249,7 +253,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||
srcRay.Origin.X = ogRay->Origin.X - srcRay.Direction.X * 5.0f;
|
||||
srcRay.Origin.Y = ogRay->Origin.Y - srcRay.Direction.Y * 5.0f;
|
||||
srcRay.MaxDistance = ogRay->MaxDistance + 10.0f;
|
||||
auto distance = maths::distance_to_flipper(srcRay, dstRay);
|
||||
auto distance = maths::distance_to_flipper(this, srcRay, dstRay);
|
||||
CollisionDirection = dstRay.Direction;
|
||||
if (distance >= 1e+09f)
|
||||
{
|
||||
|
@ -265,7 +269,7 @@ float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
|||
srcRay.MinDistance = ogRay->MinDistance;
|
||||
srcRay.Origin = ogRay->Origin;
|
||||
srcRay.MaxDistance = rayMaxDistance;
|
||||
auto distance = maths::distance_to_flipper(srcRay, dstRay);
|
||||
auto distance = maths::distance_to_flipper(this, srcRay, dstRay);
|
||||
if (distance < 1e+09f)
|
||||
{
|
||||
NextBallPosition = dstRay.Origin;
|
||||
|
@ -312,7 +316,7 @@ void TFlipperEdge::EdgeCollision(TBall* ball, float distance)
|
|||
if (circlebase.RadiusSq * 1.01f < distanceSq)
|
||||
{
|
||||
float v11;
|
||||
float v20 = sqrt(distanceSq / DistanceDivSq) * (fabs(AngleMax) / AngleMult);
|
||||
float v20 = sqrt(distanceSq / DistanceDivSq) * (fabs(AngleMax) / AngleAdvanceTime);
|
||||
float dot1 = maths::DotProduct(CollisionLinePerp, CollisionDirection);
|
||||
if (dot1 >= 0.0f)
|
||||
v11 = dot1 * v20;
|
||||
|
@ -389,46 +393,39 @@ void TFlipperEdge::place_in_grid()
|
|||
|
||||
void TFlipperEdge::set_control_points(float timeNow)
|
||||
{
|
||||
maths::SinCos(flipper_angle(timeNow), flipper_sin_angle, flipper_cos_angle);
|
||||
float sin, cos;
|
||||
maths::SinCos(flipper_angle(timeNow), sin, cos);
|
||||
A1 = A1Src;
|
||||
A2 = A2Src;
|
||||
B1 = B1Src;
|
||||
B2 = B2Src;
|
||||
T1 = T1Src;
|
||||
maths::RotatePt(A1, flipper_sin_angle, flipper_cos_angle, RotOrigin);
|
||||
maths::RotatePt(A2, flipper_sin_angle, flipper_cos_angle, RotOrigin);
|
||||
maths::RotatePt(T1, flipper_sin_angle, flipper_cos_angle, RotOrigin);
|
||||
maths::RotatePt(B1, flipper_sin_angle, flipper_cos_angle, RotOrigin);
|
||||
maths::RotatePt(B2, flipper_sin_angle, flipper_cos_angle, RotOrigin);
|
||||
}
|
||||
|
||||
void TFlipperEdge::build_edges_in_motion()
|
||||
{
|
||||
maths::RotatePt(A1, sin, cos, RotOrigin);
|
||||
maths::RotatePt(A2, sin, cos, RotOrigin);
|
||||
maths::RotatePt(T1, sin, cos, RotOrigin);
|
||||
maths::RotatePt(B1, sin, cos, RotOrigin);
|
||||
maths::RotatePt(B2, sin, cos, RotOrigin);
|
||||
maths::line_init(lineA, A1.X, A1.Y, A2.X, A2.Y);
|
||||
maths::line_init(lineB, B1.X, B1.Y, B2.X, B2.Y);
|
||||
circlebase.RadiusSq = CirclebaseRadiusSq;
|
||||
circlebase.Center.X = RotOrigin.X;
|
||||
circlebase.Center.Y = RotOrigin.Y;
|
||||
circleT1.RadiusSq = CircleT1RadiusSq;
|
||||
circleT1.Center.X = T1.X;
|
||||
circleT1.Center.Y = T1.Y;
|
||||
circlebase = {RotOrigin, CirclebaseRadiusSq};
|
||||
circleT1 = {T1, CircleT1RadiusSq};
|
||||
}
|
||||
|
||||
float TFlipperEdge::flipper_angle(float timeNow)
|
||||
{
|
||||
// When not moving, flipper is at destination angle.
|
||||
if (!FlipperFlag)
|
||||
return Angle1;
|
||||
return AngleDst;
|
||||
|
||||
float currentAngleDuration = fabsf((Angle1 - Angle2) / AngleMax * AngleMult);
|
||||
float currentAngleRatio;
|
||||
// How much time it takes to go from source to destination angle, in sec.
|
||||
auto arcDuration = std::abs((AngleDst - AngleSrc) / AngleMax * AngleAdvanceTime);
|
||||
|
||||
if (currentAngleDuration >= 0.0000001f)
|
||||
currentAngleRatio = (timeNow - InputTime) / currentAngleDuration;
|
||||
else
|
||||
currentAngleRatio = 1.0;
|
||||
// How close the flipper is to destination, in [0, 1] range.
|
||||
auto t = arcDuration >= 0.0000001f ? (timeNow - InputTime) / arcDuration : 1.0f;
|
||||
t = Clamp(t, 0.0f, 1.0f);
|
||||
|
||||
currentAngleRatio = std::min(1.0f, std::max(currentAngleRatio, 0.0f));
|
||||
return currentAngleRatio * (Angle1 - Angle2) + Angle2;
|
||||
// Result = linear interpolation between source and destination angle.
|
||||
return AngleSrc + t * (AngleDst - AngleSrc);
|
||||
}
|
||||
|
||||
int TFlipperEdge::is_ball_inside(float x, float y)
|
||||
|
@ -459,28 +456,32 @@ int TFlipperEdge::is_ball_inside(float x, float y)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void TFlipperEdge::SetMotion(int code, float value)
|
||||
int TFlipperEdge::SetMotion(int code, float value)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case 1:
|
||||
Angle2 = flipper_angle(value);
|
||||
Angle1 = AngleMax;
|
||||
AngleMult = ExtendTime;
|
||||
AngleSrc = flipper_angle(value);
|
||||
AngleDst = AngleMax;
|
||||
AngleAdvanceTime = ExtendTime;
|
||||
break;
|
||||
case 2:
|
||||
Angle2 = flipper_angle(value);
|
||||
Angle1 = 0.0;
|
||||
AngleMult = RetractTime;
|
||||
AngleSrc = flipper_angle(value);
|
||||
AngleDst = 0.0f;
|
||||
AngleAdvanceTime = RetractTime;
|
||||
break;
|
||||
case 1024:
|
||||
FlipperFlag = 0;
|
||||
Angle1 = 0.0;
|
||||
return;
|
||||
AngleSrc = 0.0f;
|
||||
AngleDst = 0.0f;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (AngleSrc == AngleDst)
|
||||
code = 0;
|
||||
|
||||
InputTime = value;
|
||||
FlipperFlag = code;
|
||||
AngleStopTime = AngleMult + InputTime;
|
||||
AngleStopTime = AngleAdvanceTime + InputTime;
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -15,10 +15,9 @@ public:
|
|||
void EdgeCollision(TBall* ball, float distance) override;
|
||||
void place_in_grid() override;
|
||||
void set_control_points(float timeNow);
|
||||
void build_edges_in_motion();
|
||||
float flipper_angle(float timeNow);
|
||||
int is_ball_inside(float x, float y);
|
||||
void SetMotion(int code, float value);
|
||||
int SetMotion(int code, float value);
|
||||
|
||||
int FlipperFlag;
|
||||
float Elasticity;
|
||||
|
@ -31,8 +30,8 @@ public:
|
|||
float CirclebaseRadiusMSq;
|
||||
float CircleT1RadiusMSq;
|
||||
float AngleMax;
|
||||
float Angle2{};
|
||||
float Angle1;
|
||||
float AngleSrc{};
|
||||
float AngleDst;
|
||||
int CollisionFlag1;
|
||||
int CollisionFlag2{};
|
||||
vector2 CollisionLinePerp{};
|
||||
|
@ -49,13 +48,11 @@ public:
|
|||
int EdgeCollisionFlag;
|
||||
float InputTime;
|
||||
float AngleStopTime;
|
||||
float AngleMult;
|
||||
float AngleAdvanceTime;
|
||||
float ExtendTime;
|
||||
float RetractTime;
|
||||
vector2 NextBallPosition{};
|
||||
|
||||
static float flipper_sin_angle, flipper_cos_angle;
|
||||
static vector2 A1, A2, B1, B2, T1;
|
||||
static line_type lineA, lineB;
|
||||
static circle_type circlebase, circleT1;
|
||||
vector2 A1, A2, B1, B2, T1;
|
||||
line_type lineA, lineB;
|
||||
circle_type circlebase, circleT1;
|
||||
};
|
||||
|
|
|
@ -67,6 +67,7 @@ public:
|
|||
int Height{};
|
||||
std::vector<TPinballComponent*> ComponentList;
|
||||
std::vector<TBall*> BallList;
|
||||
std::vector<TFlipper*> FlipperList;
|
||||
TLightGroup* LightGroup;
|
||||
float GravityDirVectMult{};
|
||||
float GravityAngleX{};
|
||||
|
|
|
@ -300,29 +300,29 @@ void maths::RotatePt(vector2& point, float sin, float cos, const vector2& origin
|
|||
|
||||
// Return the distance from ray1 origin to the intersection point with the closest flipper feature.
|
||||
// Sets ray2 origin to intersection point, direction to collision direction
|
||||
float maths::distance_to_flipper(const ray_type& ray1, ray_type& ray2)
|
||||
float maths::distance_to_flipper(TFlipperEdge* flipper, const ray_type& ray1, ray_type& ray2)
|
||||
{
|
||||
auto distance = 1000000000.0f;
|
||||
auto distanceType = FlipperIntersect::none;
|
||||
auto newDistance = ray_intersect_line(ray1, TFlipperEdge::lineA);
|
||||
auto newDistance = ray_intersect_line(ray1, flipper->lineA);
|
||||
if (newDistance < distance)
|
||||
{
|
||||
distance = newDistance;
|
||||
distanceType = FlipperIntersect::lineA;
|
||||
}
|
||||
newDistance = ray_intersect_circle(ray1, TFlipperEdge::circlebase);
|
||||
newDistance = ray_intersect_circle(ray1, flipper->circlebase);
|
||||
if (newDistance < distance)
|
||||
{
|
||||
distance = newDistance;
|
||||
distanceType = FlipperIntersect::circlebase;
|
||||
}
|
||||
newDistance = ray_intersect_circle(ray1, TFlipperEdge::circleT1);
|
||||
newDistance = ray_intersect_circle(ray1, flipper->circleT1);
|
||||
if (newDistance < distance)
|
||||
{
|
||||
distance = newDistance;
|
||||
distanceType = FlipperIntersect::circleT1;
|
||||
}
|
||||
newDistance = ray_intersect_line(ray1, TFlipperEdge::lineB);
|
||||
newDistance = ray_intersect_line(ray1, flipper->lineB);
|
||||
if (newDistance < distance)
|
||||
{
|
||||
distance = newDistance;
|
||||
|
@ -332,19 +332,19 @@ float maths::distance_to_flipper(const ray_type& ray1, ray_type& ray2)
|
|||
switch (distanceType)
|
||||
{
|
||||
case FlipperIntersect::lineA:
|
||||
ray2.Direction = TFlipperEdge::lineA.PerpendicularC;
|
||||
ray2.Origin = TFlipperEdge::lineA.RayIntersect;
|
||||
ray2.Direction = flipper->lineA.PerpendicularC;
|
||||
ray2.Origin = flipper->lineA.RayIntersect;
|
||||
break;
|
||||
case FlipperIntersect::lineB:
|
||||
ray2.Direction = TFlipperEdge::lineB.PerpendicularC;
|
||||
ray2.Origin = TFlipperEdge::lineB.RayIntersect;
|
||||
ray2.Direction = flipper->lineB.PerpendicularC;
|
||||
ray2.Origin = flipper->lineB.RayIntersect;
|
||||
break;
|
||||
case FlipperIntersect::circlebase:
|
||||
case FlipperIntersect::circleT1:
|
||||
ray2.Origin.X = distance * ray1.Direction.X + ray1.Origin.X;
|
||||
ray2.Origin.Y = distance * ray1.Direction.Y + ray1.Origin.Y;
|
||||
ray2.Direction = vector_sub(ray2.Origin, distanceType == FlipperIntersect::circlebase ?
|
||||
TFlipperEdge::circlebase.Center : TFlipperEdge::circleT1.Center);
|
||||
flipper->circlebase.Center : flipper->circleT1.Center);
|
||||
normalize_2d(ray2.Direction);
|
||||
break;
|
||||
case FlipperIntersect::none:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
class TBall;
|
||||
class TFlipperEdge;
|
||||
|
||||
struct vector2
|
||||
{
|
||||
|
@ -118,7 +119,7 @@ public:
|
|||
static float Distance(const vector2& vec1, const vector2& vec2);
|
||||
static void SinCos(float angle, float& sinOut, float& cosOut);
|
||||
static void RotatePt(vector2& point, float sin, float cos, const vector2& origin);
|
||||
static float distance_to_flipper(const ray_type& ray1, ray_type& ray2);
|
||||
static float distance_to_flipper(TFlipperEdge* flipper, const ray_type& ray1, ray_type& ray2);
|
||||
static void RotateVector(vector2& vec, float angle);
|
||||
static void find_closest_edge(ramp_plane_type* plane, int planeCount, wall_point_type* wall, vector2& lineEnd,
|
||||
vector2& lineStart);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "GroupData.h"
|
||||
#include "partman.h"
|
||||
#include "score.h"
|
||||
#include "TFlipper.h"
|
||||
#include "TPinballTable.h"
|
||||
#include "TTextBox.h"
|
||||
|
||||
|
@ -329,6 +330,11 @@ void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls)
|
|||
}
|
||||
}
|
||||
|
||||
for (auto flipper : MainTable->FlipperList)
|
||||
{
|
||||
flipper->UpdateSprite(timeNow);
|
||||
}
|
||||
|
||||
if (drawBalls)
|
||||
{
|
||||
for (auto ball : MainTable->BallList)
|
||||
|
|
Loading…
Reference in a new issue