如何解决使用 Box2D 的 Raycast 进行激光镜像
在我正在编写的游戏中,我想借助从 b2RayCastCallback 继承的类来实现 Box2d 的激光。 我有一个方形盒子,里面有一个对角镜,我希望激光从镜子返回一个与原始光束成 45 度方向的新激光束。
我添加了一个大小和角度都合适的对角线夹具,但仍然效果不佳。 有时是激光工作,有时是因为镜子损坏角度错误而重新光束,有时会得到想要的结果。
我该怎么办?
b2polygonShape polygonShape;
b2FixtureDef myFixtureDef;
myFixtureDef.shape = &polygonShape;
myFixtureDef.density = 1;
myFixtureDef.friction = 2.5f;
myFixtureDef.isSensor = true;
polygonShape.SetAsBox((CELL_DIMENSIONS.x * HALF_RATIO * EIGHTH_RATIO) / PIXEL_METER_RATIO,CELL_DIMENSIONS.y / PIXEL_METER_RATIO,b2Vec2(0,0),-((b2_pi /180)* 45));
b2Fixture* mirrorFixture = getBody()->CreateFixture(&myFixtureDef);
mirrorFixture->SetUserData((void*)2);
///////////////////////////////////////////////////////////////////////////////////////////////
class RaysCastCallback : public b2RayCastCallback
{
public:
RaysCastCallback() : m_fixture(NULL),m_fraction(0){}
virtual float ReportFixture(b2Fixture* fixture,const b2Vec2& point,const b2Vec2& normal,float fraction) override
{
m_fixture = fixture;
m_point = point;
m_normal = normal;
m_fraction = fraction;
if (m_fixture)
{
if (auto body = m_fixture->GetBody())
{
auto object = static_cast<GameObject*>(body->GetUserData());
if ((object->getobjectType() == object::mirrorBox && int(m_fixture->GetUserData()) != 2) ||
(object->getobjectType() == object::gate && m_fixture->IsSensor()))
{
m_fraction = -1;
}
}
}
return m_fraction;
}
b2Fixture* m_fixture;
b2Vec2 m_point;
b2Vec2 m_normal;
float m_fraction;
};
////////////////////////////////////////////////////////////////////////////////////////
void LaserSource::laserRayCast(b2Vec2 p1,b2Vec2 p2,b2World& world)
{
sf::VertexArray laserRay(sf::Lines,2);
sf::VertexArray laserRayGlow(sf::Quads,4);
laserRay[0].color = sf::Color::Yellow;
laserRay[1].color = sf::Color::Yellow;
laserRayGlow[0].color = sf::Color(255,255,60);
laserRayGlow[1].color = sf::Color(255,60);
laserRayGlow[2].color = sf::Color(255,60);
laserRayGlow[3].color = sf::Color(255,60);
RaysCastCallback callback;
world.RayCast(&callback,p1,p2);
if (callback.m_fixture)
{
laserRay[0].position = sf::Vector2f(p1.x * PIXEL_METER_RATIO,p1.y * PIXEL_METER_RATIO);
laserRay[1].position = sf::Vector2f(callback.m_point.x * PIXEL_METER_RATIO,callback.m_point.y * PIXEL_METER_RATIO);
laserRayGlow[0].position = sf::Vector2f(p1.x * PIXEL_METER_RATIO,(p1.y * PIXEL_METER_RATIO) - DIFF);
laserRayGlow[1].position = sf::Vector2f(callback.m_point.x * PIXEL_METER_RATIO,(callback.m_point.y * PIXEL_METER_RATIO) - DIFF);
laserRayGlow[2].position = sf::Vector2f(callback.m_point.x * PIXEL_METER_RATIO,(callback.m_point.y * PIXEL_METER_RATIO) + DIFF);
laserRayGlow[3].position = sf::Vector2f(p1.x * PIXEL_METER_RATIO,(p1.y * PIXEL_METER_RATIO) + DIFF);
}
m_laserRay.emplace_back(laserRay);
m_laserRayGlow.emplace_back(laserRayGlow);
if (callback.m_fixture)
{
auto object = static_cast<GameObject*>(callback.m_fixture->GetBody()->GetUserData());
if (object->getobjectType() == object::laserDestination)
{
auto laserDestination = static_cast<LaserDestination*>(object);
laserDestination->activateControlledobject();
}
if (object->getobjectType() == object::mirrorBox)
{
b2Vec2 remainingRay = (p2 - callback.m_point);
b2Vec2 projectedOntonormal = b2Dot(remainingRay,callback.m_normal) * callback.m_normal;
b2Vec2 nextp2 = p2 - 2 * projectedOntonormal;
laserRayCast(callback.m_point,nextp2,world);
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。