Update physics::World

This commit is contained in:
Nomango 2019-10-21 11:15:22 +08:00
parent e225361151
commit 765e4404b2
5 changed files with 93 additions and 41 deletions

View File

@ -42,20 +42,29 @@ namespace kiwano
World::~World()
{
// Make sure destroyed b2World after b2Body
// Make sure b2World was destroyed after b2Body
RemoveAllChildren();
RemoveAllBodies();
RemoveAllJoints();
}
BodyPtr World::CreateBody(ActorPtr actor)
{
return CreateBody(actor.get());
}
BodyPtr World::CreateBody(Actor* actor)
{
BodyPtr body = new Body(this, actor);
body->UpdateFromActor();
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;
}
@ -67,7 +76,6 @@ namespace kiwano
if (iter != bodies_.end())
{
bodies_.erase(iter);
}
if (body->GetB2Body())
{
@ -75,9 +83,20 @@ namespace kiwano
}
}
}
}
void World::RemoveAllBodies()
{
if (world_.GetBodyCount())
{
b2Body* body = world_.GetBodyList();
while (body)
{
b2Body* next = body->GetNext();
world_.DestroyBody(body);
body = next;
}
}
bodies_.clear();
}
@ -89,7 +108,6 @@ namespace kiwano
if (iter != joints_.end())
{
joints_.erase(iter);
}
if (joint->GetB2Joint())
{
@ -97,9 +115,20 @@ namespace kiwano
}
}
}
}
void World::RemoveAllJoints()
{
if (world_.GetJointCount())
{
b2Joint* joint = world_.GetJointList();
while (joint)
{
b2Joint* next = joint->GetNext();
world_.DestroyJoint(joint);
joint = next;
}
}
joints_.clear();
}

View File

@ -30,6 +30,9 @@ namespace kiwano
class KGE_API World
: public Stage
{
friend class Body;
friend class Joint;
public:
World();
@ -38,23 +41,12 @@ namespace kiwano
virtual ~World();
// 创建刚体
BodyPtr CreateBody(ActorPtr actor);
BodyPtr CreateBody(Actor* actor);
// 创建关节
JointPtr CreateJoint(b2JointDef* joint_def);
// 移除刚体
void RemoveBody(Body* body);
// 移除所有刚体
void RemoveAllBodies();
// 移除关节
void RemoveJoint(Joint* joint);
// 移除所有关节
void RemoveAllJoints();
// 获取重力
Vec2 GetGravity() const;
@ -87,6 +79,19 @@ namespace kiwano
// 获取 Box2D 世界
const b2World* GetB2World() const;
protected:
// 移除刚体
void RemoveBody(Body* body);
// 移除所有刚体
void RemoveAllBodies();
// 移除关节
void RemoveJoint(Joint* joint);
// 移除所有关节
void RemoveAllJoints();
protected:
void Update(Duration dt) override;
@ -95,8 +100,8 @@ namespace kiwano
int vel_iter_;
int pos_iter_;
float global_scale_;
Vector<BodyPtr> bodies_;
Vector<JointPtr> joints_;
Vector<Body*> bodies_;
Vector<Joint*> joints_;
};
KGE_DECLARE_SMART_PTR(World);

View File

@ -455,32 +455,43 @@ namespace kiwano
is_fast_transform_ = false;
}
void Actor::AddChild(ActorPtr child)
void Actor::AddChild(Actor* child, int zorder)
{
KGE_ASSERT(child && "Actor::AddChild failed, NULL pointer exception");
if (child)
{
KGE_ASSERT(!child->parent_ && "Actor::AddChild failed, the actor to be added already has a parent");
#ifdef KGE_DEBUG
if (child->parent_)
KGE_ERROR_LOG(L"The actor to be added already has a parent");
for (Actor* parent = parent_; parent; parent = parent->parent_)
{
if (parent == child)
{
KGE_ERROR_LOG(L"A actor cannot be its own parent");
return;
}
}
#endif // KGE_DEBUG
children_.push_back(child);
child->parent_ = this;
child->SetStage(this->stage_);
child->dirty_transform_ = true;
child->UpdateOpacity();
child->z_order_ = zorder;
child->Reorder();
child->UpdateOpacity();
}
}
void Actor::AddChild(ActorPtr child, int zorder)
{
AddChild(child.get());
}
void Actor::AddChildren(Vector<ActorPtr> const& children)
{
for (const auto& actor : children)
@ -528,7 +539,7 @@ namespace kiwano
return nullptr;
}
Actor::Children const & Actor::GetChildren() const
Actor::Children const & Actor::GetAllChildren() const
{
return children_;
}

View File

@ -42,10 +42,10 @@ namespace kiwano
friend class Transition;
friend class intrusive_list<ActorPtr>;
public:
using Children = intrusive_list<ActorPtr>;
using UpdateCallback = Function<void(Duration)>;
public:
Actor();
// 更新角色
@ -309,7 +309,14 @@ namespace kiwano
// 添加子角色
void AddChild(
ActorPtr child
ActorPtr child,
int zorder = 0
);
// 添加子角色
void AddChild(
Actor* child,
int zorder = 0
);
// 添加多个子角色
@ -317,18 +324,18 @@ namespace kiwano
Vector<ActorPtr> const& children
);
// 获取所有名称相同的子角色
Vector<ActorPtr> GetChildren(
String const& name
) const;
// 获取名称相同的子角色
ActorPtr GetChild(
String const& name
) const;
// 获取所有名称相同的子角色
Vector<ActorPtr> GetChildren(
String const& name
) const;
// 获取全部子角色
Children const& GetChildren() const;
Children const& GetAllChildren() const;
// 移除子角色
void RemoveChild(

View File

@ -268,9 +268,9 @@ private:
inline iterator_impl operator++(int) { iterator_impl old = (*this); ++(*this); return old; }
inline iterator_impl& operator--() { KGE_ASSERT(base_); if (is_end_) is_end_ = false; else base_ = value_type(base_->prev_item()); return (*this); }
inline iterator_impl operator--(int) { iterator_impl old = (*this); --(*this); return old; }
inline bool operator==(iterator_impl const& other) const { return base_ == other.base_; }
inline bool operator==(iterator_impl const& other) const { return base_ == other.base_ && is_end_ == other.is_end_; }
inline bool operator!=(iterator_impl const& other) const { return !(*this == other); }
inline operator bool() const { return base_ != nullptr; }
inline operator bool() const { return base_ != nullptr && !is_end_; }
private:
bool is_end_;