Was wanting to get a quick demo up with cocos2d-x and chipmunk to play around with chipmunk physics and had a bit of train wreck trying to get a debug node to work properly. It’s really not complicated, but hopefully this will keep someone else from stumbling through it like I did. I should’ve kept link to the person that inspired this. It wasn’t completely my idea.
ChipmunkDebugNode.h
// // desc: ChipmunkDebugNode.h // #ifndef _CHIPMUNKDEBUGNODE_H_ #define _CHIPMUNKDEBUGNODE_H_ // // includes // #include "cocos2d.h" #include "chipmunk.h" // // struct ChipmunkDebugNode // struct ChipmunkDebugNode : cocos2d::Node { // // static methods // static ChipmunkDebugNode *create(cpSpace *space); static void DrawShape(cpShape *shape, void *data); // // init // virtual bool init(cpSpace *space); // // overload draw // virtual void draw(); // // variables // cpSpace *_space; }; #endif // #ifndef _CHIPMUNKDEBUGNODE_H_
ChipmunkDebugNode.cpp
// // desc: ChipmunkDebugNode.cpp // // // includes // #include "ChipmunkDebugNode.h" // cocos2d namespace USING_NS_CC; ChipmunkDebugNode *ChipmunkDebugNode::create(cpSpace *space) { ChipmunkDebugNode *chipmunkDebugNode = new ChipmunkDebugNode(); if (chipmunkDebugNode && chipmunkDebugNode->init(space)) { chipmunkDebugNode->autorelease(); return chipmunkDebugNode; } // else cleanup delete chipmunkDebugNode; return NULL; } void ChipmunkDebugNode::DrawShape(cpShape* shape, void *data) { if (!shape) { return; } glLineWidth(5.0f); DrawPrimitives::setDrawColor4F(0.5f, 0.5f, 0.5f, 1.0f); if (shape->klass_private->type == CP_CIRCLE_SHAPE) { cpCircleShape *circle = (cpCircleShape *)shape; cpVect center = cpvadd(shape->body->p, cpvrotate(circle->c, shape->body->rot)); DrawPrimitives::drawCircle(Point(center.x, center.y), circle->r, shape->body->a, 20, true); return; } if (shape->klass_private->type == CP_POLY_SHAPE) { cpPolyShape *poly = (cpPolyShape *)shape; // convert chipmunk points to coco points Point *pointArray = new Point[poly->numVerts]; for (int i=0; i < poly->numVerts; i++) { pointArray[i] = Point(poly->tVerts[i].x, poly->tVerts[i].y); } DrawPrimitives::drawPoly(pointArray, poly->numVerts, true); delete pointArray; return; } if (shape->klass_private->type == CP_SEGMENT_SHAPE) { cpSegmentShape* segment = (cpSegmentShape*)shape; DrawPrimitives::drawLine(Point(segment->ta.x, segment->ta.y), Point(segment->tb.x, segment->tb.y)); return; } cpSegmentShape *segment = (cpSegmentShape *)shape; DrawPrimitives::drawLine(Point(segment->ta.x, segment->ta.y), Point(segment->tb.x, segment->tb.y)); } // // descP init // bool ChipmunkDebugNode::init(cpSpace *space) { if (!Node::init()) { return false; } // init variables _space = space; return true; } // // desc: override draw // void ChipmunkDebugNode::draw() { cpSpaceEachShape(_space, &DrawShape, this); }
And for completeness, here is example of using it inside my root layer. Should all be pretty straight forward once you see it.
// setup chimpunk stuff cpSpace *space = cpSpaceNew(); cpSpaceSetGravity(space, cpv(0.0f, -1.0f)); cpBody *body = cpBodyNew(100.0f, INFINITY); cpShape *shape = cpCircleShapeNew(body, 30.0f, cpvzero); body->p = cpv(visibleSize.width / 2.0f, visibleSize.height / 2.0f); cpSpaceAddBody(space, body); cpSpaceAddShape(space, shape); // create and add chipmunk debug node this->addChild(ChipmunkDebugNode::create(space));