Cocos2dx - Unable to set velocity = 0.0
Asked Answered
P

1

1

I'm making an pool game with cocos2dx. First, i setup the edgeBox with this parameters PhysicsMaterial(1.0f, 1.0f, 0.8f) And then these 2 balls PhysicsMaterial(1.0f, 1.0f, 0.5f)

On the update function, i want slow down balls time by time without gravity (like making ground friction) by adding physicsBody->setLinearDamping(0.3);

On the update function, i set the minimum velocity, if the velocity of each ball reaches lower than 15, reset velocity to 0,0

auto MV = 15;
auto v1 = player1->getPhysicsBody()->getVelocity();
auto v2 = player2->getPhysicsBody()->getVelocity();
if (v1.x > MV || v1.x < -MV ||
    v1.y > MV || v1.y < -MV) {
} else if(v1 != Vec2(0,0)) {
    player1->getPhysicsBody()->setVelocity(Vec2(0,0));
    CCLOG("sx 1 : %f %f",v1.x,v1.y);
}

if (v2.x > MV || v2.x < -MV ||
    v2.y > MV || v2.y < -MV) {
} else if(v2 != Vec2(0,0)) {
    player2->getPhysicsBody()->setVelocity(Vec2(0,0));
    CCLOG("sx 2 : %f %f",v2.x,v2.y);
}

Everything works fine except when the balls stand next to the wall or each other. I see the small blue glue to these objects, this is when the contact has been made.

And in these situation, i can't set the velocity to 0,0. I think there is some kind of force constantly changing the velocity. You can see the image below to see the blue glue and keep setting velocity = 0.0 like forever.

enter image description here

Pyknic answered 27/9, 2016 at 4:42 Comment(0)
S
0

Firstly reset forces before setting velocity to zero: player2->getPhysicsBody()->resetForces();

Also gravity can be a cause that bodies continue to move. So you can set gravity to zero for whole physics world. For example:

auto scene = Scene::createWithPhysics();
scene->getPhysicsWorld()->setGravity(Vec2(0, 0));

or just for one particular body:

player2->getPhysicsBody()->setGravityEnable(false);

or you can customize velocity function:

#include "chipmunk.h"

cocos2d::PhysicsBody * pBody = player2->getPhysicsBody();
pBody->getCPBody()->velocity_func = customVelFunc;

where customVelFunc could be defined as:

void customVelFunc(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
{
    cpBodyUpdateVelocity(body, cpvzero, damping, dt);
}
Seasickness answered 29/9, 2016 at 18:56 Comment(10)
At the beginning, i disabled the Gravity on the physics world. Tried to resetForces but didn't work. This thing happens when the contact has been made.Pyknic
@Pyknic in addition to my pervious advice try to set restitution and friction to zero PhysicsMaterial(1.f, 0, 0) or alternatively you could set your custom collision callbacks to control behavior of your physics objects when they collide.Seasickness
I've already tried to set friction and density to 0. restitution can't be 0 because i need creating bouncing. but the ball still keep slightly moving even after setting velocity to 0,0.Pyknic
Do you need me to provide demo code? I have the screenshot and everything works like i've described. Mind the glue on the screenshot between ball and wall, everytime the contact has been made (ball to wall, ball to ball), the velocity constantly change. I have found the way to work around is setDynamic to false to disable the movement if velocity equals to 0. But this stupid error may cause many things , example like this: #39816398Pyknic
@Pyknic yes i need demo code as starting point to give you working solution.Seasickness
@Pyknic hey, check my repo (to make balls moving tap top-right button)Seasickness
Thanks, you can check my forked version here github.com/Tom29/BallTest i don't have permission to push to your repo. There're few changes between your code and i, maybe gravity is the cause of this trouble?Pyknic
@Pyknic you could create pull request. And i noticed that my demo has the same behavior if velocity and direction equal to the values from your example. I have also tried to call setDynamic method instead of setting speed to zero but in this case bodies sometimes remain a little bit overlapping. So i think that this is intended behavior of physics engine and i suggest you to turn on auto sleep mode in the physics world as stated hereSeasickness
@Pyknic but i'm not sure if you can switch on auto-sleep mode for your physics through cocos2-x wrapper. You could ask this question on cocos2d-x forum.Seasickness
Thanks, i work around by setDynamic if the velocity equals to zero, so it will avoid the overlapping. Basically this error temporally has been fixed even i don't really know the main cause. Now i have to work with synchronization coordinate between multiple devices :( . Btw, your code is awesome. I'm new for C++ and cocos for 2 weeks and can learn from your code.Pyknic

© 2022 - 2024 — McMap. All rights reserved.