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);
        });
Пример #2
0
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);
}