i'm (trying) to develop a simple game using cocos2d-x v3 (see here).
The aim is to move the rainbow-ish player from the bottom green area to the top one. The joystick is the white thumb on the left: it can be moved with the finger to change the player's direction.
So far, i'm using the built-in collision detector in cocos2d-x v3 (through the class PhysicalBody
). The red borders in the figure represent the shape of the player are the borders of the arena it can freely move in.
When the user moves the joystick's thumb, its direction is used to set the player's velocity. However, being in physical world, setting the velocity is not the best choice because it breaks the physical laws, i.e. only a force can be applied to a body. Therefore, from the desired speed, I compute the impulse to be applied to achieve it:
Vec2 currentVel = _player->getPhysicsBody()->getVelocity();
Vec2 desiredVel = 80*_joystick->getDirection(); // a normalized Vec2
Vec2 deltaVel = desiredVel - currentVel;
Vec2 impulse = _player->getPhysicsBody()->getMass() * deltaVel;
_player->getPhysicsBody()->applyImpulse(impulse);
The problem is that the player can cross the edges as show here.
This happens when the player is in contact with the arena's edge and the impulse is applied.
I set the player's body as:
auto playerBody = PhysicsBody::createBox(_player->getContentSize(), PhysicsMaterial(100.0f, 0.0f, 0.0f));
playerBody->setDynamic(true);
playerBody->setRotationEnable(false);
playerBody->setGravityEnable(false);
_player->setPhysicsBody(playerBody);
where the three parameters of PhysicsMaterial
are density, restitution and friction. In the same way, the map's body is:
auto mapBody = PhysicsBody::createEdgeChain(polygonPoints.data(), polygonPoints.size(), PhysicsMaterial(100.0f, 0.0f, 0.0f));
mapBody->setDynamic(false);
mapBody->setGravityEnable(false);
_tileMap->setPhysicsBody(mapBody);
where polygonPoints
is a vector of Vec2
's defining the shape. The player is a Sprite
and the map is a TMXTiledMap
.
I tried to change the values of density, friction and restitution without success.
Have you ever experienced the same problem?
Thanks!
It seems you are using the cocos2d-x implementation for Physics. So, i have less idea about this. But Generally, this happens when update physics world update rate cycle is low, either by setting or low frame rate. check, UpdateRate of your world.
From Doc:
/** 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; }