My only issue now is creating a verlet rope!
Anyone know how to do this in C++?
Thanks!
My only issue now is creating a verlet rope!
Anyone know how to do this in C++?
Thanks!
Here you go: https://github.com/teemukorh/VRope-x
(it is box2d though, so you might need to rework it if you’re using physicsbodies in cocos2d-x v3)
Nikcain,
I am using this same code to create the Verlet Rope. (Vpoint, Vstick and Vrope classes)
Although I dont know how to make the rope show up! (his example of implementing the rope is pretty vague).
Also I have enabled Box2d and Im using it in Cocos2d-x 3.8!
I have tried:
// Create joint
b2RopeJoint* bodyAbodyBJoint = (b2RopeJoint*) world->CreateJoint(&jd);
// Create batchnode and vrope for joint (can also be made between two bodies)
CCSpriteBatchNode* batch = dynamic_cast<CCSpriteBatchNode*> (getChildByTag(KTagRopeBatchNode));
VRope* verlet = new VRope(bodyAbodyBJoint, batch);
// Update the verlets in the game loop
verlet->update(dt);
verlet->updateSprites();
Although when I run this, nothing comes up. Not sure what Im doing wrong.
Note: I am 100% sure my Box2d is working as I have created other projects using it.
Can you get yours to work and show me what you did?
That looks right to me, and is the same as I’m doing. I didn’t have to change their code at all in my implementation.
The sprite batch was created as
ropeBatch = CCSpriteBatchNode::create("rope.png", 100);
addChild(ropeBatch, 1, myRopeBatchTag);
although the capacity automatically increases, so shouldn’t matter what number you put there.
What is your jointdef like? (with the bodies too?). I think I struggled creating joints more than I struggled with the rope class.
There’s also a debugdraw method that might help determine whether it’s a box2d issue or a sprite issue (i.e. the rope’s there, but the sprites aren’t in the right place). Also try logging the getPosition x & y on both the sprites and boidies after the update.
Here you go, this is a modified hello world project (using v2.2 - I’ve not graduated to v3 yet!).
I’ve also attached all the files Classes.zip (14.1 KB)
The body and joint definitions are a bit messy looking as I’ve exported them from the R.U.B.E editor (which is very useful). I don’t normally use RUBE’s exported code but instead parse their JSON files and construct them from that.
I couldn’t see anything particularly wrong with what you’d done (it’s odd to dereference your b2RopeJointDef like that, but it should still work). You’re not updating your world, but I assume that’s in a different bit of code.
The most likely cause is it’s just outside the screen view - try sorting out the ptmratio value.
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
/////////////////////////////
// 2. add a menu item with "X" image, which is clicked to quit the program
// you may modify it.
// add a "close" icon to exit the progress. it's an autorelease object
CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(HelloWorld::menuCloseCallback));
pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
origin.y + pCloseItem->getContentSize().height/2));
// create menu, it's an autorelease object
CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
pMenu->setPosition(CCPointZero);
this->addChild(pMenu, 1);
ropeBatch = CCSpriteBatchNode::create("rope.png", 100);
addChild(ropeBatch, 1, 555);
CCSpriteBatchNode* batch = dynamic_cast<CCSpriteBatchNode*> (getChildByTag(555));
m_world = new b2World(b2Vec2(0.0, -10));
b2Body* ceiling;
b2Body* swing;
b2Joint* rope1;
b2Joint* rope2;
// Ceiling
{
b2BodyDef bd;
bd.type = b2BodyType(0);
bd.position.Set(-1.614868640899658e-003f, 5.331412315368652e+000f);
bd.angle = 0.0f;
bd.linearVelocity.Set(0.0f, 0.0f);
bd.angularVelocity = 0.0f;
bd.linearDamping = 0.0f;
bd.angularDamping = 0.0f;
bd.allowSleep = bool(4);
bd.awake = bool(2);
bd.fixedRotation = bool(0);
bd.bullet = bool(0);
bd.active = bool(32);
bd.gravityScale = 1.0f;
ceiling = m_world->CreateBody(&bd);
{
b2FixtureDef fd;
fd.friction = 2.000000029802322e-001f;
fd.restitution = 0.0f;
fd.density = 1.0f;
fd.isSensor = bool(0);
fd.filter.categoryBits = uint16(1);
fd.filter.maskBits = uint16(65535);
fd.filter.groupIndex = int16(0);
b2PolygonShape shape;
b2Vec2 vs[8];
vs[0].Set(1.000161457061768e+001f, -3.314123153686523e-001f);
vs[1].Set(1.000161457061768e+001f, 2.668587684631348e+000f);
vs[2].Set(-1.998385190963745e+000f, 2.668587684631348e+000f);
vs[3].Set(-1.998385190963745e+000f, -3.314123153686523e-001f);
shape.Set(vs, 4);
fd.shape = &shape;
ceiling->CreateFixture(&fd);
}
}
// Swing
{
b2BodyDef bd;
bd.type = b2BodyType(2);
bd.position.Set(2.391709089279175e+000f, 1.420945525169373e+000f);
bd.angle = 0.0f;
bd.linearVelocity.Set(0.0f, 0.0f);
bd.angularVelocity = 0.0f;
bd.linearDamping = 0.0f;
bd.angularDamping = 0.0f;
bd.allowSleep = bool(4);
bd.awake = bool(2);
bd.fixedRotation = bool(0);
bd.bullet = bool(0);
bd.active = bool(32);
bd.gravityScale = 1.0f;
swing = m_world->CreateBody(&bd);
{
b2FixtureDef fd;
fd.friction = 5.000000000000000e-001f;
fd.restitution = 0.0f;
fd.density = 1.0f;
fd.isSensor = bool(0);
fd.filter.categoryBits = uint16(1);
fd.filter.maskBits = uint16(65535);
fd.filter.groupIndex = int16(0);
b2PolygonShape shape;
b2Vec2 vs[8];
vs[0].Set(1.253884911537170e+000f, -2.436261177062988e-001f);
vs[1].Set(1.253884673118591e+000f, 8.604699373245239e-002f);
vs[2].Set(-6.699655055999756e-001f, 8.604681491851807e-002f);
vs[3].Set(-6.699658036231995e-001f, -2.436261773109436e-001f);
shape.Set(vs, 4);
fd.shape = &shape;
swing->CreateFixture(&fd);
}
}
// rope joints
{
b2RopeJointDef jd;
jd.bodyA = swing;
jd.bodyB = ceiling;
jd.collideConnected = bool(0);
jd.localAnchorA.Set(1.166776180267334e+000f, 1.977586746215820e-002f);
jd.localAnchorB.Set(5.222444057464600e+000f, -3.281159400939941e-001f);
jd.maxLength = 4.0f;
rope1 = m_world->CreateJoint(&jd);
verlet1 = new VRope(rope1, batch);
}
{
b2RopeJointDef jd;
jd.bodyA = swing;
jd.bodyB = ceiling;
jd.collideConnected = bool(0);
jd.localAnchorA.Set(-5.537242889404297e-001f, 3.955173492431641e-002f);
jd.localAnchorB.Set(3.620598316192627e+000f, -3.281159400939941e-001f);
jd.maxLength = 4.0f;
rope2 = m_world->CreateJoint(&jd);
verlet2 = new VRope(rope2, batch);
}
scheduleUpdate();
return true;
}
void HelloWorld::update(float dt)
{
m_world->Step(dt, 8, 1);
verlet1->update(dt);
verlet1->updateSprites();
verlet2->update(dt);
verlet2->updateSprites();
}
Finally got it to work, thanks alot!!