void MachineSystem::removePart(cpVect gridPosition) { int machineNum = machinePositionToNumber(gridPosition); MachinePart *partToRemove = parts[machineNum]; if (partToRemove) { cpBody *attachmentBody = partToRemove->getBody(); __block cpBody *pegBody = NULL; cpBodyEachConstraint_b(attachmentBody, ^(cpConstraint *c) { if (cpConstraintGetB(c) == attachmentBody) { cpBody *otherBody = cpConstraintGetA(c); // the peg is always body A if (cpBodyGetMass(otherBody) == INFINITY) pegBody = otherBody; } }); assert(pegBody); int nPegs = size.x * size.y; // remove the attachments for this machine for (int i=0; i<nPegs; i++) { cpVect otherMachinePos = machineNumberToPosition(i); detachMachines(gridPosition, otherMachinePos); } partToRemove->detachFromBody(pegBody); cpBodyEachShape_b(pegBody, ^(cpShape *shape) { cpSpaceRemoveStaticShape(space, shape); cpShapeFree(shape); });
static void draw_shape(cpShape* shape, SDL_Surface* screen) { cpBody* body = shape->body; struct draw_options opts = { .surface = screen, .colour = colour(200, 200, 200) }; switch (shape->CP_PRIVATE(klass)->type) { case CP_CIRCLE_SHAPE: draw_circle_shape(opts, shape, body); break; case CP_SEGMENT_SHAPE: draw_segment_shape(opts, shape, body); break; case CP_POLY_SHAPE: draw_poly_shape(opts, shape, body); break; default: debug_putsf("ignoring unrecognised shape type %d", shape->CP_PRIVATE(klass)->type); break; } } static void draw_constraint(cpConstraint* constraint, SDL_Surface *screen) { struct draw_options opts = { .surface = screen, .colour = colour(100, 100, 200) }; cpVect vect_a = cpBodyGetPos(cpConstraintGetA(constraint)); cpVect vect_b = cpBodyGetPos(cpConstraintGetB(constraint)); draw_line(opts, vect_a, vect_b); } static void draw_rotation_vector(cpBody *body, SDL_Surface *screen) { struct draw_options opts = { .surface = screen, .colour = colour(200, 100, 100) }; cpFloat rotation_vector_length = 30; cpVect pos = cpBodyGetPos(body); cpVect rotation = cpvmult(cpvforangle(cpBodyGetAngle(body)), rotation_vector_length); draw_line(opts, pos, cpvadd(pos, rotation)); } static void draw_forces(cpBody *body, SDL_Surface *screen) { struct draw_options opts = { .surface = screen, .colour = colour(100, 200, 100) }; cpVect pos = cpBodyGetPos(body); cpVect force = cpBodyGetForce(body); draw_line(opts, pos, cpvadd(pos, force)); } static void draw_body(cpBody *body, SDL_Surface *screen) { draw_rotation_vector(body, screen); draw_forces(body, screen); } void debug_draw_space(cpSpace* space, SDL_Surface* screen) { cpSpaceEachShape(space, (cpSpaceShapeIteratorFunc)draw_shape, screen); cpSpaceEachConstraint(space, (cpSpaceConstraintIteratorFunc)draw_constraint, screen); cpSpaceEachBody(space, (cpSpaceBodyIteratorFunc)draw_body, screen); }