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 chipmunk 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));
