Add physics::Joints

This commit is contained in:
Nomango 2019-10-28 17:25:06 +08:00
parent ae5d985238
commit 0484446bc1
12 changed files with 746 additions and 55 deletions

View File

@ -112,6 +112,12 @@ namespace kiwano
}
}
Point Body::GetPosition() const
{
KGE_ASSERT(body_ && world_);
return world_->World2Stage(body_->GetPosition());
}
Point Body::GetLocalPoint(Point const& world) const
{
KGE_ASSERT(body_ && world_);

View File

@ -65,6 +65,12 @@ namespace kiwano
// »ñÈ¡ÖÊÁ¿
float GetMass() const { KGE_ASSERT(body_); return body_->GetMass(); }
// »ñÈ¡Ðýת½Ç¶È
float GetRotation() const { KGE_ASSERT(body_); return math::Radian2Angle(body_->GetAngle()); }
// »ñȡλÖÃ
Point GetPosition() const;
Point GetLocalPoint(Point const& world) const;
Point GetWorldPoint(Point const& local) const;

View File

@ -48,6 +48,8 @@ namespace kiwano
world_ = world;
if (world_)
{
world_->AddJoint(this);
b2Joint* joint = world_->GetB2World()->CreateJoint(joint_def);
SetB2Joint(joint);
}
@ -92,11 +94,13 @@ namespace kiwano
DistanceJoint::DistanceJoint()
: Joint()
, raw_joint_(nullptr)
{
}
DistanceJoint::DistanceJoint(World* world, b2DistanceJointDef* def)
: Joint(world, def)
, raw_joint_(nullptr)
{
}
@ -105,14 +109,279 @@ namespace kiwano
KGE_ASSERT(param.body_a && param.body_b);
b2DistanceJointDef def;
def.bodyA = param.body_a->GetB2Body();
def.bodyB = param.body_b->GetB2Body();
def.localAnchorA = world->Stage2World(param.local_anchor_a);
def.localAnchorB = world->Stage2World(param.local_anchor_b);
def.length = world->Stage2World((param.body_a->GetWorldPoint(param.local_anchor_a) - param.body_b->GetWorldPoint(param.local_anchor_b)).Length());
def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.local_anchor_a), world->Stage2World(param.local_anchor_b));
def.frequencyHz = param.frequency_hz;
def.dampingRatio = param.damping_ratio;
DistanceJointPtr joint = new DistanceJoint(world, &def);
joint->raw_joint_ = static_cast<b2DistanceJoint*>(joint->GetB2Joint());
return joint;
}
void DistanceJoint::SetLength(float length)
{
KGE_ASSERT(raw_joint_ && world_);
raw_joint_->SetLength(world_->Stage2World(length));
}
float DistanceJoint::GetLength() const
{
KGE_ASSERT(raw_joint_ && world_);
return world_->World2Stage(raw_joint_->GetLength());
}
//
// FrictionJoint
//
FrictionJoint::FrictionJoint()
: Joint()
, raw_joint_(nullptr)
{
}
FrictionJoint::FrictionJoint(World* world, b2FrictionJointDef* def)
: Joint(world, def)
, raw_joint_(nullptr)
{
}
FrictionJointPtr FrictionJoint::Create(World* world, Param const& param)
{
KGE_ASSERT(param.body_a && param.body_b);
b2FrictionJointDef def;
def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.anchor));
def.maxForce = param.max_force;
def.maxTorque = world->Stage2World(param.max_torque);
FrictionJointPtr joint = new FrictionJoint(world, &def);
joint->raw_joint_ = static_cast<b2FrictionJoint*>(joint->GetB2Joint());
return joint;
}
void FrictionJoint::SetMaxForce(float length)
{
KGE_ASSERT(raw_joint_);
raw_joint_->SetMaxForce(length);
}
float FrictionJoint::GetMaxForce() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->GetMaxForce();
}
void FrictionJoint::SetMaxTorque(float length)
{
KGE_ASSERT(raw_joint_ && world_);
raw_joint_->SetMaxTorque(world_->Stage2World(length));
}
float FrictionJoint::GetMaxTorque() const
{
KGE_ASSERT(raw_joint_ && world_);
return world_->World2Stage(raw_joint_->GetMaxTorque());
}
//
// GearJoint
//
GearJoint::GearJoint()
: Joint()
, raw_joint_(nullptr)
{
}
GearJoint::GearJoint(World* world, b2GearJointDef* def)
: Joint(world, def)
, raw_joint_(nullptr)
{
}
GearJointPtr GearJoint::Create(World* world, Param const& param)
{
KGE_ASSERT(param.joint_a && param.joint_b);
b2GearJointDef def;
def.joint1 = param.joint_a->GetB2Joint();
def.joint2 = param.joint_b->GetB2Joint();
def.ratio = param.ratio;
GearJointPtr joint = new GearJoint(world, &def);
joint->raw_joint_ = static_cast<b2GearJoint*>(joint->GetB2Joint());
return joint;
}
void GearJoint::SetRatio(float ratio)
{
KGE_ASSERT(raw_joint_);
raw_joint_->SetRatio(ratio);
}
float GearJoint::GetRatio() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->GetRatio();
}
//
// MotorJoint
//
MotorJoint::MotorJoint()
: Joint()
, raw_joint_(nullptr)
{
}
MotorJoint::MotorJoint(World* world, b2MotorJointDef* def)
: Joint(world, def)
, raw_joint_(nullptr)
{
}
MotorJointPtr MotorJoint::Create(World* world, Param const& param)
{
KGE_ASSERT(param.body_a && param.body_b);
b2MotorJointDef def;
def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body());
def.maxForce = param.max_force;
def.maxTorque = world->Stage2World(param.max_torque);
MotorJointPtr joint = new MotorJoint(world, &def);
joint->raw_joint_ = static_cast<b2MotorJoint*>(joint->GetB2Joint());
return joint;
}
void MotorJoint::SetMaxForce(float length)
{
KGE_ASSERT(raw_joint_);
raw_joint_->SetMaxForce(length);
}
float MotorJoint::GetMaxForce() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->GetMaxForce();
}
void MotorJoint::SetMaxTorque(float length)
{
KGE_ASSERT(raw_joint_ && world_);
raw_joint_->SetMaxTorque(world_->Stage2World(length));
}
float MotorJoint::GetMaxTorque() const
{
KGE_ASSERT(raw_joint_ && world_);
return world_->World2Stage(raw_joint_->GetMaxTorque());
}
//
// WheelJoint
//
WheelJoint::WheelJoint()
: Joint()
, raw_joint_(nullptr)
{
}
WheelJoint::WheelJoint(World* world, b2WheelJointDef* def)
: Joint(world, def)
, raw_joint_(nullptr)
{
}
WheelJointPtr WheelJoint::Create(World* world, Param const& param)
{
KGE_ASSERT(param.body_a && param.body_b);
b2WheelJointDef def;
def.Initialize(param.body_a->GetB2Body(), param.body_b->GetB2Body(), world->Stage2World(param.anchor), world->Stage2World(param.axis));
def.enableMotor = param.enable_motor;
def.maxMotorTorque = world->Stage2World(param.max_motor_torque);
def.motorSpeed = world->Stage2World(param.motor_speed);
def.frequencyHz = param.frequency_hz;
def.dampingRatio = param.damping_ratio;
WheelJointPtr joint = new WheelJoint(world, &def);
joint->raw_joint_ = static_cast<b2WheelJoint*>(joint->GetB2Joint());
return joint;
}
float WheelJoint::GetJointTranslation() const
{
KGE_ASSERT(raw_joint_ && world_);
return world_->World2Stage(raw_joint_->GetJointTranslation());
}
float WheelJoint::GetJointLinearSpeed() const
{
KGE_ASSERT(raw_joint_ && world_);
return world_->World2Stage(raw_joint_->GetJointLinearSpeed());
}
void WheelJoint::SetMaxMotorTorque(float torque)
{
KGE_ASSERT(raw_joint_ && world_);
raw_joint_->SetMaxMotorTorque(world_->Stage2World(torque));
}
float WheelJoint::GetMaxMotorTorque() const
{
KGE_ASSERT(raw_joint_ && world_);
return world_->World2Stage(raw_joint_->GetMaxMotorTorque());
}
//
// MouseJoint
//
MouseJoint::MouseJoint()
: Joint()
, raw_joint_(nullptr)
{
}
MouseJoint::MouseJoint(World* world, b2MouseJointDef* def)
: Joint(world, def)
, raw_joint_(nullptr)
{
}
MouseJointPtr MouseJoint::Create(World* world, Param const& param)
{
KGE_ASSERT(param.body_a && param.body_b);
KGE_ASSERT(param.body_a->GetWorld() && param.body_a->GetWorld() == param.body_b->GetWorld());
b2MouseJointDef def;
def.bodyA = param.body_a->GetB2Body();
def.bodyB = param.body_b->GetB2Body();
def.target = param.body_a->GetWorld()->Stage2World(param.target);
def.maxForce = param.max_force;
def.frequencyHz = param.frequency_hz;
def.dampingRatio = param.damping_ratio;
MouseJointPtr joint = new MouseJoint(world, &def);
joint->raw_joint_ = static_cast<b2MouseJoint*>(joint->GetB2Joint());
return joint;
}
void MouseJoint::SetMaxForce(float length)
{
KGE_ASSERT(raw_joint_);
raw_joint_->SetMaxForce(length);
}
float MouseJoint::GetMaxForce() const
{
KGE_ASSERT(raw_joint_);
return raw_joint_->GetMaxForce();
}
}
}

View File

@ -27,6 +27,14 @@ namespace kiwano
namespace physics
{
KGE_DECLARE_SMART_PTR(Joint);
KGE_DECLARE_SMART_PTR(DistanceJoint);
KGE_DECLARE_SMART_PTR(FrictionJoint);
KGE_DECLARE_SMART_PTR(GearJoint);
KGE_DECLARE_SMART_PTR(MotorJoint);
KGE_DECLARE_SMART_PTR(WheelJoint);
KGE_DECLARE_SMART_PTR(MouseJoint);
// 关节
class KGE_API Joint
: public ObjectBase
{
@ -77,7 +85,8 @@ namespace kiwano
Type type_;
};
KGE_DECLARE_SMART_PTR(DistanceJoint);
// 固定距离关节
class KGE_API DistanceJoint
: public Joint
{
@ -86,15 +95,33 @@ namespace kiwano
{
Point local_anchor_a;
Point local_anchor_b;
float frequency_hz;
float damping_ratio;
Param(Body* body_a, Body* body_b, Point const& local_anchor_a, Point const& local_anchor_b)
Param(
Body* body_a,
Body* body_b,
Point const& local_anchor_a,
Point const& local_anchor_b,
float frequency_hz = 0.f,
float damping_ratio = 0.f
)
: ParamBase(body_a, body_b)
, local_anchor_a(local_anchor_a)
, local_anchor_b(local_anchor_b)
, frequency_hz(frequency_hz)
, damping_ratio(damping_ratio)
{}
Param(BodyPtr body_a, BodyPtr body_b, Point const& local_anchor_a, Point const& local_anchor_b)
: Param(body_a.get(), body_b.get(), local_anchor_a, local_anchor_b)
Param(
BodyPtr body_a,
BodyPtr body_b,
Point const& local_anchor_a,
Point const& local_anchor_b,
float frequency_hz = 0.f,
float damping_ratio = 0.f
)
: Param(body_a.get(), body_b.get(), local_anchor_a, local_anchor_b, frequency_hz, damping_ratio)
{}
};
@ -102,6 +129,316 @@ namespace kiwano
DistanceJoint(World* world, b2DistanceJointDef* def);
static DistanceJointPtr Create(World* world, Param const& param);
void SetLength(float length);
float GetLength() const;
// 设置弹簧阻尼器频率 [赫兹]
void SetFrequency(float hz) { KGE_ASSERT(raw_joint_); raw_joint_->SetFrequency(hz); }
float GetFrequency() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetFrequency(); }
// 设置阻尼比
void SetDampingRatio(float ratio) { KGE_ASSERT(raw_joint_); raw_joint_->SetDampingRatio(ratio); }
float GetDampingRatio() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetDampingRatio(); }
protected:
b2DistanceJoint* raw_joint_;
};
// 摩擦关节
class KGE_API FrictionJoint
: public Joint
{
public:
struct Param : public Joint::ParamBase
{
Point anchor;
float max_force;
float max_torque;
Param(
Body* body_a,
Body* body_b,
Point const& anchor,
float max_force = 0.f,
float max_torque = 0.f
)
: ParamBase(body_a, body_b)
, anchor(anchor)
, max_force(max_force)
, max_torque(max_torque)
{}
Param(
BodyPtr body_a,
BodyPtr body_b,
Point const& anchor,
float max_force = 0.f,
float max_torque = 0.f
)
: Param(body_a.get(), body_b.get(), anchor, max_force, max_torque)
{}
};
FrictionJoint();
FrictionJoint(World* world, b2FrictionJointDef* def);
static FrictionJointPtr Create(World* world, Param const& param);
// 设定最大摩擦力
void SetMaxForce(float force);
float GetMaxForce() const;
// 设定最大转矩
void SetMaxTorque(float torque);
float GetMaxTorque() const;
protected:
b2FrictionJoint* raw_joint_;
};
// 齿轮关节
class KGE_API GearJoint
: public Joint
{
public:
struct Param : public Joint::ParamBase
{
JointPtr joint_a;
JointPtr joint_b;
float ratio;
Param(
Joint* joint_a,
Joint* joint_b,
float ratio = 1.f
)
: ParamBase(nullptr, nullptr)
, joint_a(joint_a)
, joint_b(joint_b)
, ratio(ratio)
{}
Param(
JointPtr joint_a,
JointPtr joint_b,
float ratio = 1.f
)
: Param(joint_a.get(), joint_b.get(), ratio)
{}
};
GearJoint();
GearJoint(World* world, b2GearJointDef* def);
static GearJointPtr Create(World* world, Param const& param);
// 设定齿轮传动比
void SetRatio(float ratio);
float GetRatio() const;
protected:
b2GearJoint* raw_joint_;
};
// 马达关节
class KGE_API MotorJoint
: public Joint
{
public:
struct Param : public Joint::ParamBase
{
float max_force;
float max_torque;
float correction_factor;
Param(
Body* body_a,
Body* body_b,
float max_force = 1.f,
float max_torque = 100.f,
float correction_factor = 0.3f
)
: ParamBase(body_a, body_b)
, max_force(max_force)
, max_torque(max_torque)
, correction_factor(correction_factor)
{}
Param(
BodyPtr body_a,
BodyPtr body_b,
float max_force = 0.f,
float max_torque = 0.f,
float correction_factor = 0.3f
)
: Param(body_a.get(), body_b.get(), max_force, max_torque, correction_factor)
{}
};
MotorJoint();
MotorJoint(World* world, b2MotorJointDef* def);
static MotorJointPtr Create(World* world, Param const& param);
// 设定最大摩擦力
void SetMaxForce(float force);
float GetMaxForce() const;
// 设定最大转矩
void SetMaxTorque(float torque);
float GetMaxTorque() const;
protected:
b2MotorJoint* raw_joint_;
};
// 轮关节
class KGE_API WheelJoint
: public Joint
{
public:
struct Param : public Joint::ParamBase
{
Point anchor;
Vec2 axis;
bool enable_motor;
float max_motor_torque;
float motor_speed;
float frequency_hz;
float damping_ratio;
Param(
Body* body_a,
Body* body_b,
Point const& anchor,
Vec2 const& axis,
float frequency_hz = 2.0f,
float damping_ratio = 0.7f,
bool enable_motor = false,
float max_motor_torque = 0.0f,
float motor_speed = 0.0f
)
: ParamBase(body_a, body_b)
, anchor(anchor)
, axis(axis)
, enable_motor(enable_motor)
, max_motor_torque(max_motor_torque)
, motor_speed(motor_speed)
, frequency_hz(frequency_hz)
, damping_ratio(damping_ratio)
{}
Param(
BodyPtr body_a,
BodyPtr body_b,
Point const& anchor,
Vec2 const& axis,
float frequency_hz = 2.0f,
float damping_ratio = 0.7f,
bool enable_motor = false,
float max_motor_torque = 0.0f,
float motor_speed = 0.0f
)
: Param(body_a.get(), body_b.get(), anchor, axis, frequency_hz, damping_ratio, enable_motor, max_motor_torque, motor_speed)
{}
};
WheelJoint();
WheelJoint(World* world, b2WheelJointDef* def);
static WheelJointPtr Create(World* world, Param const& param);
float GetJointTranslation() const;
float GetJointLinearSpeed() const;
float GetJointAngle() const { KGE_ASSERT(raw_joint_); return math::Radian2Angle(raw_joint_->GetJointAngle()); }
float GetJointAngularSpeed() const { KGE_ASSERT(raw_joint_); return math::Radian2Angle(raw_joint_->GetJointAngularSpeed()); }
bool IsMotorEnabled() const { KGE_ASSERT(raw_joint_); return raw_joint_->IsMotorEnabled(); }
void EnableMotor(bool flag) { KGE_ASSERT(raw_joint_); raw_joint_->EnableMotor(flag); }
// 设置马达转速 [度/秒]
void SetMotorSpeed(float speed) { KGE_ASSERT(raw_joint_); raw_joint_->SetMotorSpeed(math::Angle2Radian(speed)); }
float GetMotorSpeed() const { KGE_ASSERT(raw_joint_); return math::Radian2Angle(raw_joint_->GetMotorSpeed()); }
// 设定最大马达转矩
void SetMaxMotorTorque(float torque);
float GetMaxMotorTorque() const;
void SetSpringFrequencyHz(float hz) { KGE_ASSERT(raw_joint_); raw_joint_->SetSpringFrequencyHz(hz); }
float GetSpringFrequencyHz() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetSpringFrequencyHz(); }
void SetSpringDampingRatio(float ratio) { KGE_ASSERT(raw_joint_); raw_joint_->SetSpringDampingRatio(ratio); }
float GetSpringDampingRatio() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetSpringDampingRatio(); }
protected:
b2WheelJoint* raw_joint_;
};
// 鼠标关节
// 用于使身体的某个点追踪世界上的指定点,例如让物体追踪鼠标位置
class KGE_API MouseJoint
: public Joint
{
public:
struct Param : public Joint::ParamBase
{
Point target;
float max_force;
float frequency_hz;
float damping_ratio;
Param(
Body* body_a,
Body* body_b,
Point const& target,
float max_force,
float frequency_hz = 5.0f,
float damping_ratio = 0.7f
)
: ParamBase(body_a, body_b)
, target(target)
, max_force(max_force)
, frequency_hz(frequency_hz)
, damping_ratio(damping_ratio)
{}
Param(
BodyPtr body_a,
BodyPtr body_b,
Point const& target,
float max_force,
float frequency_hz = 5.0f,
float damping_ratio = 0.7f
)
: Param(body_a.get(), body_b.get(), target, max_force, frequency_hz, damping_ratio)
{}
};
MouseJoint();
MouseJoint(World* world, b2MouseJointDef* def);
static MouseJointPtr Create(World* world, Param const& param);
// 设定最大摩擦力
void SetMaxForce(float force);
float GetMaxForce() const;
// 设置响应速度 [赫兹]
void SetFrequency(float hz) { KGE_ASSERT(raw_joint_); raw_joint_->SetFrequency(hz); }
float GetFrequency() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetFrequency(); }
// 设置阻尼比
void SetDampingRatio(float ratio) { KGE_ASSERT(raw_joint_); raw_joint_->SetDampingRatio(ratio); }
float GetDampingRatio() const { KGE_ASSERT(raw_joint_); return raw_joint_->GetDampingRatio(); }
protected:
b2MouseJoint* raw_joint_;
};
}
}

View File

@ -24,24 +24,56 @@ namespace kiwano
{
namespace physics
{
World::World()
: world_(b2Vec2(0, 10))
, vel_iter_(6)
, pos_iter_(2)
, global_scale_(100.f)
namespace
{
const float DefaultGlobalScale = 100.f; // 100 pixels per meters
}
World::World(Vec2 gravity)
: world_(b2Vec2(gravity.x, gravity.y))
class World::DestructionListener : public b2DestructionListener
{
World* world_;
public:
DestructionListener(World* world)
: world_(world)
{
}
void SayGoodbye(b2Joint* joint) override
{
if (world_)
{
world_->JointRemoved(joint);
}
}
void SayGoodbye(b2Fixture* fixture) override
{
}
};
World::World()
: world_(b2Vec2(0, 10.0f))
, vel_iter_(6)
, pos_iter_(2)
, global_scale_(100.f)
, global_scale_(DefaultGlobalScale)
, destruction_listener_(nullptr)
, removing_joint_(false)
{
destruction_listener_ = new DestructionListener(this);
world_.SetDestructionListener(destruction_listener_);
}
World::~World()
{
world_.SetDestructionListener(nullptr);
if (destruction_listener_)
{
delete destruction_listener_;
destruction_listener_ = nullptr;
}
// Make sure b2World was destroyed after b2Body
RemoveAllChildren();
RemoveAllBodies();
@ -56,27 +88,13 @@ namespace kiwano
BodyPtr World::CreateBody(Actor* actor)
{
BodyPtr body = Body::Create(this, actor);
bodies_.push_back(body.get());
return body;
}
JointPtr World::CreateJoint(b2JointDef* joint_def)
{
JointPtr joint = new Joint(this, joint_def);
joints_.push_back(joint.get());
return joint;
}
void World::RemoveBody(Body* body)
{
if (body)
{
auto iter = std::find(bodies_.begin(), bodies_.end(), body);
if (iter != bodies_.end())
{
bodies_.erase(iter);
}
if (body->GetB2Body())
{
world_.DestroyBody(body->GetB2Body());
@ -96,7 +114,14 @@ namespace kiwano
body = next;
}
}
bodies_.clear();
}
void World::AddJoint(Joint* joint)
{
if (joint)
{
joints_.push_back(joint);
}
}
void World::RemoveJoint(Joint* joint)
@ -107,11 +132,13 @@ namespace kiwano
if (iter != joints_.end())
{
joints_.erase(iter);
}
if (joint->GetB2Joint())
{
world_.DestroyJoint(joint->GetB2Joint());
if (joint->GetB2Joint())
{
removing_joint_ = true;
world_.DestroyJoint(joint->GetB2Joint());
removing_joint_ = false;
}
}
}
}
@ -120,17 +147,38 @@ namespace kiwano
{
if (world_.GetJointCount())
{
b2Joint* joint = world_.GetJointList();
while (joint)
removing_joint_ = true;
{
b2Joint* next = joint->GetNext();
world_.DestroyJoint(joint);
joint = next;
b2Joint* joint = world_.GetJointList();
while (joint)
{
b2Joint* next = joint->GetNext();
world_.DestroyJoint(joint);
joint = next;
}
}
removing_joint_ = false;
}
joints_.clear();
}
void World::JointRemoved(b2Joint* joint)
{
if (!removing_joint_ && joint)
{
auto iter = std::find_if(
joints_.begin(),
joints_.end(),
[joint](Joint* j) -> bool { return j->GetB2Joint() == joint; }
);
if (iter != joints_.end())
{
joints_.erase(iter);
}
}
}
b2World* World::GetB2World()
{
return &world_;

View File

@ -36,17 +36,12 @@ namespace kiwano
public:
World();
World(Vec2 gravity);
virtual ~World();
// 创建刚体
BodyPtr CreateBody(ActorPtr actor);
BodyPtr CreateBody(Actor* actor);
// 创建关节
JointPtr CreateJoint(b2JointDef* joint_def);
// 获取重力
Vec2 GetGravity() const;
@ -67,10 +62,10 @@ namespace kiwano
inline float Stage2World(float value) { return value / GetGlobalScale(); }
inline b2Vec2 Stage2World(const Point& pos) { return b2Vec2(Stage2World(pos.x), Stage2World(pos.y)); }
// 设置速度迭代次数
// 设置速度迭代次数, 默认为 6
inline void SetVelocityIterations(int vel_iter) { vel_iter_ = vel_iter; }
// 设置位置迭代次数
// 设置位置迭代次数, 默认为 2
inline void SetPositionIterations(int pos_iter) { pos_iter_ = pos_iter; }
// 获取 Box2D 世界
@ -86,21 +81,32 @@ namespace kiwano
// 移除所有刚体
void RemoveAllBodies();
// 添加关节
void AddJoint(Joint* joint);
// 移除关节
void RemoveJoint(Joint* joint);
// 移除所有关节
void RemoveAllJoints();
// 关节被移除
void JointRemoved(b2Joint* joint);
protected:
void Update(Duration dt) override;
class DestructionListener;
friend DestructionListener;
protected:
b2World world_;
int vel_iter_;
int pos_iter_;
float global_scale_;
Vector<Body*> bodies_;
DestructionListener* destruction_listener_;
bool removing_joint_;
Vector<Joint*> joints_;
};

View File

@ -525,7 +525,7 @@ namespace kiwano
return children;
}
ActorPtr Actor::GetChild(String const& name) const
Actor* Actor::GetChild(String const& name) const
{
size_t hash_code = std::hash<String>{}(name);

View File

@ -325,7 +325,7 @@ namespace kiwano
);
// 获取名称相同的子角色
ActorPtr GetChild(
Actor* GetChild(
String const& name
) const;

View File

@ -43,6 +43,11 @@ namespace kiwano
}
Action* ActionManager::AddAction(ActionPtr action)
{
return AddAction(action.get());
}
Action* ActionManager::AddAction(Action* action)
{
KGE_ASSERT(action && "AddAction failed, NULL pointer exception");
@ -50,10 +55,10 @@ namespace kiwano
{
actions_.push_back(action);
}
return action.get();
return action;
}
ActionPtr ActionManager::GetAction(String const & name)
Action* ActionManager::GetAction(String const & name)
{
if (actions_.empty())
return nullptr;

View File

@ -32,9 +32,13 @@ namespace kiwano
Action* AddAction(
ActionPtr action
);
// 添加动作
Action* AddAction(
Action* action
);
// 获取动作
ActionPtr GetAction(
Action* GetAction(
String const& name
);

View File

@ -41,6 +41,11 @@ namespace kiwano
}
EventListener* EventDispatcher::AddListener(EventListenerPtr listener)
{
return AddListener(listener.get());
}
EventListener* EventDispatcher::AddListener(EventListener* listener)
{
KGE_ASSERT(listener && "AddListener failed, NULL pointer exception");
@ -48,7 +53,7 @@ namespace kiwano
{
listeners_.push_back(listener);
}
return listener.get();
return listener;
}
EventListener* EventDispatcher::AddListener(EventType type, EventListener::Callback callback, String const& name)

View File

@ -33,6 +33,11 @@ namespace kiwano
EventListenerPtr listener
);
// 添加监听器
EventListener* AddListener(
EventListener* listener
);
// 添加监听器
EventListener* AddListener(
EventType type,