mirror of
https://github.com/k4zmu2a/SpaceCadetPinball.git
synced 2024-11-27 02:50:19 +01:00
FT collision part4: ball to ball collision.
TBall uses multiple inheritance, interesting.
This commit is contained in:
parent
f521a03322
commit
c5acdcd524
15 changed files with 132 additions and 38 deletions
|
@ -11,7 +11,8 @@
|
||||||
#include "TPinballTable.h"
|
#include "TPinballTable.h"
|
||||||
#include "TTableLayer.h"
|
#include "TTableLayer.h"
|
||||||
|
|
||||||
TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
|
TBall::TBall(TPinballTable* table, int groupIndex) : TCollisionComponent(table, groupIndex, false),
|
||||||
|
TEdgeSegment(this, &ActiveFlag, 0)
|
||||||
{
|
{
|
||||||
visualStruct visual{};
|
visualStruct visual{};
|
||||||
char ballGroupName[10]{"ball"};
|
char ballGroupName[10]{"ball"};
|
||||||
|
@ -22,19 +23,29 @@ TBall::TBall(TPinballTable* table) : TPinballComponent(table, -1, false)
|
||||||
CollisionComp = nullptr;
|
CollisionComp = nullptr;
|
||||||
EdgeCollisionCount = 0;
|
EdgeCollisionCount = 0;
|
||||||
TimeDelta = 0.0;
|
TimeDelta = 0.0;
|
||||||
CollisionMask = 1;
|
|
||||||
CollisionFlag = 0;
|
CollisionFlag = 0;
|
||||||
Speed = 0.0;
|
Speed = 0.0;
|
||||||
Direction.Y = 0.0;
|
Direction.Y = 0.0;
|
||||||
Direction.X = 0.0;
|
Direction.X = 0.0;
|
||||||
Position.X = 0.0;
|
|
||||||
Position.Y = 0.0;
|
|
||||||
HasGroupFlag = false;
|
|
||||||
|
|
||||||
ListBitmap = new std::vector<SpriteData>();
|
ListBitmap = new std::vector<SpriteData>();
|
||||||
|
|
||||||
|
if (groupIndex == -1)
|
||||||
|
{
|
||||||
|
HasGroupFlag = false;
|
||||||
|
Position = {0, 0, 0};
|
||||||
|
CollisionMask = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HasGroupFlag = true;
|
||||||
|
loader::query_visual(groupIndex, 0, &visual);
|
||||||
|
CollisionMask = visual.CollisionGroup;
|
||||||
|
auto floatArr = loader::query_float_attribute(groupIndex, 0, 408);
|
||||||
|
Position = {floatArr[0], floatArr[1], floatArr[3]};
|
||||||
|
}
|
||||||
|
|
||||||
/*Full tilt: ball is ballN, where N[0,2] resolution*/
|
/*Full tilt: ball is ballN, where N[0,2] resolution*/
|
||||||
auto groupIndex = loader::query_handle(ballGroupName);
|
groupIndex = loader::query_handle(ballGroupName);
|
||||||
if (groupIndex < 0)
|
if (groupIndex < 0)
|
||||||
{
|
{
|
||||||
ballGroupName[4] = '0' + fullscrn::GetResolution();
|
ballGroupName[4] = '0' + fullscrn::GetResolution();
|
||||||
|
@ -70,7 +81,7 @@ void TBall::Repaint()
|
||||||
|
|
||||||
auto pos2D = proj::xform_to_2d(Position);
|
auto pos2D = proj::xform_to_2d(Position);
|
||||||
auto zDepth = proj::z_distance(Position);
|
auto zDepth = proj::z_distance(Position);
|
||||||
|
|
||||||
auto index = 0u;
|
auto index = 0u;
|
||||||
for (; index < ListBitmap->size() - 1; ++index)
|
for (; index < ListBitmap->size() - 1; ++index)
|
||||||
{
|
{
|
||||||
|
@ -112,7 +123,7 @@ int TBall::Message(MessageCode code, float value)
|
||||||
{
|
{
|
||||||
if (code == MessageCode::Reset)
|
if (code == MessageCode::Reset)
|
||||||
{
|
{
|
||||||
SpriteSetBall(-1, { 0,0 }, 0.0f);
|
SpriteSetBall(-1, {0, 0}, 0.0f);
|
||||||
Position.X = 0.0;
|
Position.X = 0.0;
|
||||||
CollisionComp = nullptr;
|
CollisionComp = nullptr;
|
||||||
Position.Y = 0.0;
|
Position.Y = 0.0;
|
||||||
|
@ -139,6 +150,47 @@ void TBall::throw_ball(vector3* direction, float angleMult, float speedMult1, fl
|
||||||
Speed = (1.0f - (rnd + rnd)) * (speedMult1 * speedMult2) + speedMult1;
|
Speed = (1.0f - (rnd + rnd)) * (speedMult1 * speedMult2) + speedMult1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TBall::EdgeCollision(TBall* ball, float distance)
|
||||||
|
{
|
||||||
|
ball->AsEdgeCollisionFlag = true;
|
||||||
|
vector2 nextPos{
|
||||||
|
ball->Position.X + ball->Direction.X * distance,
|
||||||
|
ball->Position.Y + ball->Direction.Y * distance
|
||||||
|
},
|
||||||
|
collDir{nextPos.X - Position.X, nextPos.Y - Position.Y};
|
||||||
|
maths::normalize_2d(collDir);
|
||||||
|
vector2 invCollDir{ -collDir.X, -collDir.Y };
|
||||||
|
|
||||||
|
ball->Position.X = nextPos.X;
|
||||||
|
ball->Position.Y = nextPos.Y;
|
||||||
|
ball->Direction.X *= ball->Speed;
|
||||||
|
ball->Direction.Y *= ball->Speed;
|
||||||
|
Direction.X *= Speed;
|
||||||
|
Direction.Y *= Speed;
|
||||||
|
|
||||||
|
auto coef = -maths::DotProduct(ball->Direction, collDir);
|
||||||
|
vector2 v44{collDir.X * coef, collDir.Y * coef};
|
||||||
|
vector2 v13{ball->Direction.X + v44.X, ball->Direction.Y + v44.Y};
|
||||||
|
|
||||||
|
coef = -maths::DotProduct(Direction, invCollDir);
|
||||||
|
vector2 v11{invCollDir.X * coef, invCollDir.Y * coef};
|
||||||
|
vector2 v10{Direction.X + v11.X, Direction.Y + v11.Y};
|
||||||
|
|
||||||
|
ball->Direction.X = -v11.X + v13.X;
|
||||||
|
ball->Direction.Y = -v11.Y + v13.Y;
|
||||||
|
ball->Speed = maths::normalize_2d(ball->Direction);
|
||||||
|
Direction.X = -v44.X + v10.X;
|
||||||
|
Direction.Y = -v44.Y + v10.Y;
|
||||||
|
Speed = maths::normalize_2d(Direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
float TBall::FindCollisionDistance(const ray_type& ray)
|
||||||
|
{
|
||||||
|
// Original inherits TCircle and aliases position.
|
||||||
|
const circle_type ballCircle{{Position.X, Position.Y}, Radius * Radius * 4.0f};
|
||||||
|
return maths::ray_intersect_circle(ray, ballCircle);
|
||||||
|
}
|
||||||
|
|
||||||
vector2 TBall::get_coordinates()
|
vector2 TBall::get_coordinates()
|
||||||
{
|
{
|
||||||
return TTableLayer::edge_manager->NormalizeBox(Position);
|
return TTableLayer::edge_manager->NormalizeBox(Position);
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "maths.h"
|
#include "maths.h"
|
||||||
#include "TPinballComponent.h"
|
#include "TCollisionComponent.h"
|
||||||
|
#include "TEdgeSegment.h"
|
||||||
|
|
||||||
class TCollisionComponent;
|
class TBall : public TCollisionComponent, public TEdgeSegment
|
||||||
class TEdgeSegment;
|
|
||||||
|
|
||||||
class TBall : public TPinballComponent
|
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
TBall(TPinballTable* table);
|
TBall(TPinballTable* table, int groupIndex);
|
||||||
void Repaint();
|
void Repaint();
|
||||||
void not_again(TEdgeSegment* edge);
|
void not_again(TEdgeSegment* edge);
|
||||||
bool already_hit(TEdgeSegment* edge);
|
bool already_hit(TEdgeSegment* edge);
|
||||||
|
@ -16,6 +14,9 @@ public :
|
||||||
vector2 get_coordinates() override;
|
vector2 get_coordinates() override;
|
||||||
void Disable();
|
void Disable();
|
||||||
void throw_ball(vector3* direction, float angleMult, float speedMult1, float speedMult2);
|
void throw_ball(vector3* direction, float angleMult, float speedMult1, float speedMult2);
|
||||||
|
void place_in_grid(RectF* aabb) override {}
|
||||||
|
void EdgeCollision(TBall* ball, float distance) override;
|
||||||
|
float FindCollisionDistance(const ray_type& ray) override;
|
||||||
|
|
||||||
vector3 Position{};
|
vector3 Position{};
|
||||||
vector3 PrevPosition{};
|
vector3 PrevPosition{};
|
||||||
|
|
|
@ -12,9 +12,9 @@ TCircle::TCircle(TCollisionComponent* collComp, char* activeFlag, unsigned colli
|
||||||
Circle.Center = *center;
|
Circle.Center = *center;
|
||||||
}
|
}
|
||||||
|
|
||||||
float TCircle::FindCollisionDistance(ray_type* ray)
|
float TCircle::FindCollisionDistance(const ray_type& ray)
|
||||||
{
|
{
|
||||||
return maths::ray_intersect_circle(*ray, Circle);
|
return maths::ray_intersect_circle(ray, Circle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCircle::EdgeCollision(TBall* ball, float distance)
|
void TCircle::EdgeCollision(TBall* ball, float distance)
|
||||||
|
|
|
@ -10,7 +10,7 @@ public:
|
||||||
|
|
||||||
TCircle(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup, vector2* center,
|
TCircle(TCollisionComponent* collComp, char* activeFlag, unsigned int collisionGroup, vector2* center,
|
||||||
float radius);
|
float radius);
|
||||||
float FindCollisionDistance(ray_type* ray) override;
|
float FindCollisionDistance(const ray_type& ray) override;
|
||||||
void EdgeCollision(TBall* ball, float distance) override;
|
void EdgeCollision(TBall* ball, float distance) override;
|
||||||
void place_in_grid(RectF* aabb) override;
|
void place_in_grid(RectF* aabb) override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -76,7 +76,7 @@ int TEdgeManager::TestGridBox(int x, int y, float* distPtr, TEdgeSegment** edgeD
|
||||||
for (auto it = edgeBox->EdgeList.rbegin(); it != edgeBox->EdgeList.rend(); ++it)
|
for (auto it = edgeBox->EdgeList.rbegin(); it != edgeBox->EdgeList.rend(); ++it)
|
||||||
{
|
{
|
||||||
auto edge = *it;
|
auto edge = *it;
|
||||||
if (!edge->ProcessedFlag && *edge->ActiveFlag && (edge->CollisionGroup & ray->CollisionMask))
|
if (!edge->ProcessedFlag && *edge->ActiveFlagPtr && (edge->CollisionGroup & ray->CollisionMask))
|
||||||
{
|
{
|
||||||
if (!ball->already_hit(edge))
|
if (!ball->already_hit(edge))
|
||||||
{
|
{
|
||||||
|
@ -84,7 +84,7 @@ int TEdgeManager::TestGridBox(int x, int y, float* distPtr, TEdgeSegment** edgeD
|
||||||
*edgePtr = edge;
|
*edgePtr = edge;
|
||||||
++edgePtr;
|
++edgePtr;
|
||||||
edge->ProcessedFlag = 1;
|
edge->ProcessedFlag = 1;
|
||||||
auto dist = edge->FindCollisionDistance(ray);
|
auto dist = edge->FindCollisionDistance(*ray);
|
||||||
if (dist < *distPtr)
|
if (dist < *distPtr)
|
||||||
{
|
{
|
||||||
*distPtr = dist;
|
*distPtr = dist;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
TEdgeSegment::TEdgeSegment(TCollisionComponent* collComp, char* activeFlag, unsigned collisionGroup)
|
TEdgeSegment::TEdgeSegment(TCollisionComponent* collComp, char* activeFlag, unsigned collisionGroup)
|
||||||
{
|
{
|
||||||
CollisionComponent = collComp;
|
CollisionComponent = collComp;
|
||||||
ActiveFlag = activeFlag;
|
ActiveFlagPtr = activeFlag;
|
||||||
CollisionGroup = collisionGroup;
|
CollisionGroup = collisionGroup;
|
||||||
ProcessedFlag = 0;
|
ProcessedFlag = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ class TEdgeSegment
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TCollisionComponent* CollisionComponent;
|
TCollisionComponent* CollisionComponent;
|
||||||
char* ActiveFlag;
|
char* ActiveFlagPtr;
|
||||||
char ProcessedFlag;
|
char ProcessedFlag;
|
||||||
void* WallValue{};
|
void* WallValue{};
|
||||||
unsigned int CollisionGroup;
|
unsigned int CollisionGroup;
|
||||||
|
@ -26,7 +26,7 @@ public:
|
||||||
virtual void EdgeCollision(TBall* ball, float distance) = 0;
|
virtual void EdgeCollision(TBall* ball, float distance) = 0;
|
||||||
virtual void port_draw();
|
virtual void port_draw();
|
||||||
virtual void place_in_grid(RectF* aabb) = 0;
|
virtual void place_in_grid(RectF* aabb) = 0;
|
||||||
virtual float FindCollisionDistance(ray_type* ray) = 0;
|
virtual float FindCollisionDistance(const ray_type& ray) = 0;
|
||||||
|
|
||||||
static TEdgeSegment* install_wall(float* floatArr, TCollisionComponent* collComp, char* activeFlagPtr,
|
static TEdgeSegment* install_wall(float* floatArr, TCollisionComponent* collComp, char* activeFlagPtr,
|
||||||
unsigned int collisionGroup, float offset, size_t wallValue);
|
unsigned int collisionGroup, float offset, size_t wallValue);
|
||||||
|
|
|
@ -104,12 +104,12 @@ void TFlipperEdge::port_draw()
|
||||||
set_control_points(CurrentAngle);
|
set_control_points(CurrentAngle);
|
||||||
}
|
}
|
||||||
|
|
||||||
float TFlipperEdge::FindCollisionDistance(ray_type* ray)
|
float TFlipperEdge::FindCollisionDistance(const ray_type& ray)
|
||||||
{
|
{
|
||||||
ray_type dstRay{};
|
ray_type dstRay{};
|
||||||
if (ControlPointDirtyFlag)
|
if (ControlPointDirtyFlag)
|
||||||
set_control_points(CurrentAngle);
|
set_control_points(CurrentAngle);
|
||||||
auto distance = maths::distance_to_flipper(this, *ray, dstRay);
|
auto distance = maths::distance_to_flipper(this, ray, dstRay);
|
||||||
if (distance >= 1e9f)
|
if (distance >= 1e9f)
|
||||||
return 1e9f;
|
return 1e9f;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ public:
|
||||||
vector3* origin, vector3* vecT1, vector3* vecT2, float extendSpeed, float retractSpeed, float collMult,
|
vector3* origin, vector3* vecT1, vector3* vecT2, float extendSpeed, float retractSpeed, float collMult,
|
||||||
float elasticity, float smoothness);
|
float elasticity, float smoothness);
|
||||||
void port_draw() override;
|
void port_draw() override;
|
||||||
float FindCollisionDistance(ray_type* ray) override;
|
float FindCollisionDistance(const ray_type& ray) override;
|
||||||
void EdgeCollision(TBall* ball, float distance) override;
|
void EdgeCollision(TBall* ball, float distance) override;
|
||||||
void place_in_grid(RectF* aabb) override;
|
void place_in_grid(RectF* aabb) override;
|
||||||
void set_control_points(float angle);
|
void set_control_points(float angle);
|
||||||
|
|
|
@ -36,9 +36,9 @@ void TLine::Offset(float offset)
|
||||||
maths::line_init(Line, X0, Y0, X1, Y1);
|
maths::line_init(Line, X0, Y0, X1, Y1);
|
||||||
}
|
}
|
||||||
|
|
||||||
float TLine::FindCollisionDistance(ray_type* ray)
|
float TLine::FindCollisionDistance(const ray_type& ray)
|
||||||
{
|
{
|
||||||
return maths::ray_intersect_line(*ray, Line);
|
return maths::ray_intersect_line(ray, Line);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TLine::EdgeCollision(TBall* ball, float distance)
|
void TLine::EdgeCollision(TBall* ball, float distance)
|
||||||
|
|
|
@ -11,7 +11,7 @@ public:
|
||||||
TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collisionGroup, float x0, float y0, float x1, float y1);
|
TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collisionGroup, float x0, float y0, float x1, float y1);
|
||||||
TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collisionGroup, const vector2& start, const vector2& end);
|
TLine(TCollisionComponent* collCmp, char* activeFlag, unsigned int collisionGroup, const vector2& start, const vector2& end);
|
||||||
void Offset(float offset);
|
void Offset(float offset);
|
||||||
float FindCollisionDistance(ray_type* ray) override;
|
float FindCollisionDistance(const ray_type& ray) override;
|
||||||
void EdgeCollision(TBall* ball, float distance) override;
|
void EdgeCollision(TBall* ball, float distance) override;
|
||||||
void place_in_grid(RectF* aabb) override;
|
void place_in_grid(RectF* aabb) override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -625,7 +625,7 @@ TBall* TPinballTable::AddBall(float x, float y)
|
||||||
{
|
{
|
||||||
if (BallList.size() >= 20)
|
if (BallList.size() >= 20)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
ball = new TBall(this);
|
ball = new TBall(this, -1);
|
||||||
BallList.push_back(ball);
|
BallList.push_back(ball);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,6 +655,16 @@ int TPinballTable::BallCountInRect(const RectF& rect)
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TPinballTable::BallCountInRect(const vector2& pos, float margin)
|
||||||
|
{
|
||||||
|
RectF rect{};
|
||||||
|
rect.XMin = pos.X - margin;
|
||||||
|
rect.XMax = pos.X + margin;
|
||||||
|
rect.YMin = pos.Y - margin;
|
||||||
|
rect.YMax = pos.Y + margin;
|
||||||
|
return BallCountInRect(rect);
|
||||||
|
}
|
||||||
|
|
||||||
void TPinballTable::EndGame_timeout(int timerId, void* caller)
|
void TPinballTable::EndGame_timeout(int timerId, void* caller)
|
||||||
{
|
{
|
||||||
auto table = static_cast<TPinballTable*>(caller);
|
auto table = static_cast<TPinballTable*>(caller);
|
||||||
|
|
|
@ -37,6 +37,7 @@ public:
|
||||||
int Message(MessageCode code, float value) override;
|
int Message(MessageCode code, float value) override;
|
||||||
TBall* AddBall(float x, float y);
|
TBall* AddBall(float x, float y);
|
||||||
int BallCountInRect(const RectF& rect);
|
int BallCountInRect(const RectF& rect);
|
||||||
|
int BallCountInRect(const vector2& pos, float margin);
|
||||||
|
|
||||||
static void EndGame_timeout(int timerId, void* caller);
|
static void EndGame_timeout(int timerId, void* caller);
|
||||||
static void LightShow_timeout(int timerId, void* caller);
|
static void LightShow_timeout(int timerId, void* caller);
|
||||||
|
|
|
@ -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::BallMaxSpeed, pb::BallHalfRadius, pb::ball_collision_dist;
|
float pb::BallMaxSpeed, pb::BallHalfRadius, pb::BallToBallCollisionDistance;
|
||||||
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;
|
||||||
|
@ -106,7 +106,7 @@ int pb::init()
|
||||||
auto ball = MainTable->BallList.at(0);
|
auto ball = MainTable->BallList.at(0);
|
||||||
BallMaxSpeed = ball->Radius * 200.0f;
|
BallMaxSpeed = ball->Radius * 200.0f;
|
||||||
BallHalfRadius = ball->Radius * 0.5f;
|
BallHalfRadius = ball->Radius * 0.5f;
|
||||||
ball_collision_dist = (ball->Radius + BallHalfRadius) * 2.0f;
|
BallToBallCollisionDistance = (ball->Radius + BallHalfRadius) * 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);
|
||||||
|
@ -424,8 +424,7 @@ void pb::timed_frame(float timeNow, float timeDelta, bool drawBalls)
|
||||||
auto distance = TTableLayer::edge_manager->FindCollisionDistance(&ray, ball, &edge);
|
auto distance = TTableLayer::edge_manager->FindCollisionDistance(&ray, ball, &edge);
|
||||||
if (distance > 0.0f)
|
if (distance > 0.0f)
|
||||||
{
|
{
|
||||||
// Todo: ball to ball collision
|
distance = BallToBallCollision(ray, *ball, &edge, distance);
|
||||||
//distance = ball_to_ball_collision();
|
|
||||||
}
|
}
|
||||||
if (ball->EdgeCollisionResetFlag)
|
if (ball->EdgeCollisionResetFlag)
|
||||||
{
|
{
|
||||||
|
@ -605,9 +604,13 @@ void pb::InputDown(GameInput input)
|
||||||
switch (input.Value)
|
switch (input.Value)
|
||||||
{
|
{
|
||||||
case 'b':
|
case 'b':
|
||||||
if (MainTable->AddBall(6.0f, 7.0f))
|
{
|
||||||
MainTable->MultiballCount++;
|
vector2 pos{6.0f, 7.0f};
|
||||||
break;
|
if (!MainTable->BallCountInRect(pos, MainTable->CollisionCompOffset * 1.2f) && MainTable->AddBall(
|
||||||
|
pos.X, pos.Y))
|
||||||
|
MainTable->MultiballCount++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'h':
|
case 'h':
|
||||||
{
|
{
|
||||||
high_score_struct entry{{0}, 1000000000};
|
high_score_struct entry{{0}, 1000000000};
|
||||||
|
@ -754,3 +757,27 @@ void pb::ShowMessageBox(Uint32 flags, LPCSTR title, LPCSTR message)
|
||||||
fprintf(flags == SDL_MESSAGEBOX_ERROR ? stderr : stdout, "BL error: %s\n%s\n", title, message);
|
fprintf(flags == SDL_MESSAGEBOX_ERROR ? stderr : stdout, "BL error: %s\n%s\n", title, message);
|
||||||
SDL_ShowSimpleMessageBox(flags, title, message, winmain::MainWindow);
|
SDL_ShowSimpleMessageBox(flags, title, message, winmain::MainWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float pb::BallToBallCollision(const ray_type& ray, const TBall& ball, TEdgeSegment** edge, float collisionDistance)
|
||||||
|
{
|
||||||
|
for (auto curBall : MainTable->BallList)
|
||||||
|
{
|
||||||
|
if (curBall->ActiveFlagPtr && curBall != &ball && (curBall->CollisionMask & ball.CollisionMask) != 0 &&
|
||||||
|
std::abs(curBall->Position.X - ball.Position.X) < BallToBallCollisionDistance &&
|
||||||
|
std::abs(curBall->Position.Y - ball.Position.Y) < BallToBallCollisionDistance)
|
||||||
|
{
|
||||||
|
auto distance = curBall->FindCollisionDistance(ray);
|
||||||
|
if (distance < 1e9f)
|
||||||
|
{
|
||||||
|
distance = std::max(0.0f, distance - 0.002f);
|
||||||
|
if (collisionDistance > distance)
|
||||||
|
{
|
||||||
|
collisionDistance = distance;
|
||||||
|
*edge = curBall;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return collisionDistance;
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "high_score.h"
|
#include "high_score.h"
|
||||||
|
|
||||||
|
class TEdgeSegment;
|
||||||
|
struct ray_type;
|
||||||
struct GameInput;
|
struct GameInput;
|
||||||
class TPinballTable;
|
class TPinballTable;
|
||||||
class DatFile;
|
class DatFile;
|
||||||
|
@ -43,7 +45,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 BallMaxSpeed, BallHalfRadius, ball_collision_dist;
|
static float BallMaxSpeed, BallHalfRadius, BallToBallCollisionDistance;
|
||||||
static GameModes game_mode;
|
static GameModes game_mode;
|
||||||
static bool cheat_mode;
|
static bool cheat_mode;
|
||||||
static DatFile* record_table;
|
static DatFile* record_table;
|
||||||
|
@ -81,4 +83,5 @@ public:
|
||||||
static void ShowMessageBox(Uint32 flags, LPCSTR title, LPCSTR message);
|
static void ShowMessageBox(Uint32 flags, LPCSTR title, LPCSTR message);
|
||||||
private:
|
private:
|
||||||
static bool demo_mode;
|
static bool demo_mode;
|
||||||
|
static float BallToBallCollision(const ray_type& ray, const TBall& ball, TEdgeSegment** edge, float collisionDistance);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue