From 4befb503070b5c632f5ad430f827884d697b407e Mon Sep 17 00:00:00 2001 From: boyu0 Date: Fri, 13 Dec 2013 16:26:26 +0800 Subject: [PATCH] issue #2771: add PhysicsWorld function set/getUpdateRate and set/getSpeed. Change name PhysicsQueryRectCallbackFunc and PhysicsPointQueryCallbackFunc to PhysicsRectQueryCallbackFunc and PhysicsQueryPointCallbackFunc --- cocos/physics/CCPhysicsWorld.cpp | 19 +++++++++---- cocos/physics/CCPhysicsWorld.h | 28 +++++++++++++------ .../Classes/PhysicsTest/PhysicsTest.cpp | 5 ++-- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/cocos/physics/CCPhysicsWorld.cpp b/cocos/physics/CCPhysicsWorld.cpp index f6b7722fb5..0414b4854b 100644 --- a/cocos/physics/CCPhysicsWorld.cpp +++ b/cocos/physics/CCPhysicsWorld.cpp @@ -75,14 +75,14 @@ namespace typedef struct RectQueryCallbackInfo { PhysicsWorld* world; - PhysicsRectQueryCallbackFunc func; + PhysicsQueryRectCallbackFunc func; void* data; }RectQueryCallbackInfo; typedef struct PointQueryCallbackInfo { PhysicsWorld* world; - PhysicsPointQueryCallbackFunc func; + PhysicsQueryPointCallbackFunc func; void* data; }PointQueryCallbackInfo; } @@ -355,7 +355,7 @@ void PhysicsWorld::rayCast(PhysicsRayCastCallbackFunc func, const Point& point1, } -void PhysicsWorld::queryRect(PhysicsRectQueryCallbackFunc func, const Rect& rect, void* data) +void PhysicsWorld::queryRect(PhysicsQueryRectCallbackFunc func, const Rect& rect, void* data) { CCASSERT(func != nullptr, "func shouldn't be nullptr"); @@ -373,7 +373,7 @@ void PhysicsWorld::queryRect(PhysicsRectQueryCallbackFunc func, const Rect& rect } } -void PhysicsWorld::queryPoint(PhysicsPointQueryCallbackFunc func, const Point& point, void* data) +void PhysicsWorld::queryPoint(PhysicsQueryPointCallbackFunc func, const Point& point, void* data) { CCASSERT(func != nullptr, "func shouldn't be nullptr"); @@ -1022,7 +1022,13 @@ void PhysicsWorld::update(float delta) body->update(delta); } - _info->step(delta); + _updateTime += delta; + if (++_updateRateCount >= _updateRate) + { + _info->step(_updateTime * _speed); + _updateRateCount = 0; + _updateTime = 0.0f; + } if (_debugDrawMask != DEBUGDRAW_NONE) { @@ -1033,6 +1039,9 @@ void PhysicsWorld::update(float delta) PhysicsWorld::PhysicsWorld() : _gravity(Point(0.0f, -98.0f)) , _speed(1.0f) +, _updateRate(1) +, _updateRateCount(0) +, _updateTime(0.0f) , _info(nullptr) , _scene(nullptr) , _delayDirty(false) diff --git a/cocos/physics/CCPhysicsWorld.h b/cocos/physics/CCPhysicsWorld.h index dfd85e5744..23fc5acaf0 100644 --- a/cocos/physics/CCPhysicsWorld.h +++ b/cocos/physics/CCPhysicsWorld.h @@ -73,8 +73,8 @@ typedef struct PhysicsRayCastInfo * @return true to continue, false to terminate */ typedef std::function PhysicsRayCastCallbackFunc; -typedef std::function PhysicsRectQueryCallbackFunc; -typedef PhysicsRectQueryCallbackFunc PhysicsPointQueryCallbackFunc; +typedef std::function PhysicsQueryRectCallbackFunc; +typedef PhysicsQueryRectCallbackFunc PhysicsQueryPointCallbackFunc; /** * @brief An PhysicsWorld object simulates collisions and other physical properties. You do not create PhysicsWorld objects directly; instead, you can get it from an Scene object. @@ -101,23 +101,30 @@ public: virtual void removeAllBodies(); void rayCast(PhysicsRayCastCallbackFunc func, const Point& point1, const Point& point2, void* data); - void queryRect(PhysicsRectQueryCallbackFunc func, const Rect& rect, void* data); - void queryPoint(PhysicsPointQueryCallbackFunc func, const Point& point, void* data); + void queryRect(PhysicsQueryRectCallbackFunc func, const Rect& rect, void* data); + void queryPoint(PhysicsQueryPointCallbackFunc func, const Point& point, void* data); Vector getShapes(const Point& point) const; PhysicsShape* getShape(const Point& point) const; const Vector& getAllBodies() const; PhysicsBody* getBody(int tag) const; - /** Register a listener to receive contact callbacks*/ - //inline void registerContactListener(EventListenerPhysicsContact* delegate) { _listener = delegate; } - /** Unregister a listener. */ - //inline void unregisterContactListener() { _listener = nullptr; } - inline Scene& getScene() const { return *_scene; } /** get the gravity value */ inline Vect getGravity() const { return _gravity; } /** set the gravity value */ void setGravity(const Vect& gravity); + /** Set the speed of physics world, speed is the rate at which the simulation executes. default value is 1.0 */ + inline void setSpeed(float speed) { if(speed >= 0.0f) { _speed = speed; } } + /** get the speed of physics world */ + inline float getSpeed() { return _speed; } + /** + * set the update rate of physics world, update rate is the value of EngineUpdateTimes/PhysicsWorldUpdateTimes. + * set it higher can improve performance, set it lower can improve accuracy of physics world simulation. + * default value is 1.0 + */ + inline void setUpdateRate(int rate) { if(rate > 0) { _updateRate = rate; } } + /** get the update rate */ + inline int getUpdateRate() { return _updateRate; } /** set the debug draw */ void setDebugDrawMask(int mask); @@ -153,6 +160,9 @@ protected: protected: Vect _gravity; float _speed; + int _updateRate; + int _updateRateCount; + float _updateTime; PhysicsWorldInfo* _info; Vector _bodies; diff --git a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp index 4865b81352..0572157afd 100644 --- a/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp +++ b/samples/Cpp/TestCpp/Classes/PhysicsTest/PhysicsTest.cpp @@ -418,6 +418,7 @@ void PhysicsDemoLogoSmash::onEnter() PhysicsDemo::onEnter(); _scene->getPhysicsWorld()->setGravity(Point(0, 0)); + _scene->getPhysicsWorld()->setUpdateRate(5.0f); _ball = SpriteBatchNode::create("Images/ball.png", sizeof(logo_image)/sizeof(logo_image[0])); addChild(_ball); @@ -445,9 +446,9 @@ void PhysicsDemoLogoSmash::onEnter() auto bullet = makeBall(Point(400, 0), 10, PhysicsMaterial(PHYSICS_INFINITY, 0, 0)); - bullet->getPhysicsBody()->setVelocity(Point(400, 0)); + bullet->getPhysicsBody()->setVelocity(Point(200, 0)); - bullet->setPosition(Point(-1000, VisibleRect::getVisibleRect().size.height/2)); + bullet->setPosition(Point(-500, VisibleRect::getVisibleRect().size.height/2)); _ball->addChild(bullet); }