static void do_logic(game_state *state) { switch_state_data *data = state->data->switch_data; if (data->mouse_down_last_step && state->game->mouse_down == false) { /* clicked and released; create a circle */ cpFloat radius = 15; cpFloat mass = 10; cpFloat moment = cpMomentForCircle(mass, 0, radius, cpvzero); cpBody *ball = cpSpaceAddBody(data->space, cpBodyNew(mass, moment)); cpBodySetPos(ball, state->game->mouse_pos); cpShape *ball_shape = cpSpaceAddShape(data->space, cpCircleShapeNew(ball, radius, cpvzero)); cpShapeSetElasticity(ball_shape, 0.7); cpShapeSetFriction(ball_shape, 0.7); cpShapeSetLayers(ball_shape, L_PLAYER); } cpSpaceStep(data->space, TARGET_SEC_PER_FRAME); data->mouse_down_last_step = state->game->mouse_down; if (ent_switch_get_state(data->sw)) debug_puts("switch is on"); else debug_puts("switch is off"); }
__declspec( dllexport ) void push( const void * _in, int in_size, void * _out, int out_sz ) { int index; Variable *var; cpBody *body; cpShape *shape; index = PEEKINT(INPUT_MEMBLOCK,0); var = vhGetVariable(&mVariableHandler,index); switch (var->mType) { case VarTypeBody: body = (cpBody*)var->mPtr; cpBodySetAngle(body,degToRad(PEEKFLOAT(INPUT_MEMBLOCK,4))); cpBodySetPos(body,PEEKVECT(INPUT_MEMBLOCK,8)); cpBodySetAngVel(body,degToRad(PEEKFLOAT(INPUT_MEMBLOCK,16))); cpBodySetVel(body,PEEKVECT(INPUT_MEMBLOCK,20)); break; case VarTypeShape: shape = (cpShape*)var->mPtr; cpShapeSetFriction(shape,PEEKFLOAT(INPUT_MEMBLOCK,4)); cpShapeSetElasticity(shape,PEEKFLOAT(INPUT_MEMBLOCK,8)); cpShapeSetLayers(shape,PEEKUINT(INPUT_MEMBLOCK,12)); cpShapeSetGroup(shape,PEEKUINT(INPUT_MEMBLOCK,16)); break; } }
static cpSpace * init(void) { ChipmunkDemoMessageString = "Right click and drag to slice up the block."; cpSpace *space = cpSpaceNew(); cpSpaceSetIterations(space, 30); cpSpaceSetGravity(space, cpv(0, -500)); cpSpaceSetSleepTimeThreshold(space, 0.5f); cpSpaceSetCollisionSlop(space, 0.5f); cpBody *body, *staticBody = cpSpaceGetStaticBody(space); cpShape *shape; // Create segments around the edge of the screen. shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-1000,-240), cpv(1000,-240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); cpFloat width = 200.0f; cpFloat height = 300.0f; cpFloat mass = width*height*DENSITY; cpFloat moment = cpMomentForBox(mass, width, height); body = cpSpaceAddBody(space, cpBodyNew(mass, moment)); shape = cpSpaceAddShape(space, cpBoxShapeNew(body, width, height)); cpShapeSetFriction(shape, 0.6f); return space; }
static cpSpace * init(void) { ChipmunkDemoMessageString = "Right click to make pentagons static/dynamic."; cpSpace *space = cpSpaceNew(); cpSpaceSetIterations(space, 5); cpSpaceSetGravity(space, cpv(0, -100)); cpBody *body, *staticBody = cpSpaceGetStaticBody(space); cpShape *shape; // Vertexes for a triangle shape. cpVect tris[] = { cpv(-15,-15), cpv( 0, 10), cpv( 15,-15), }; // Create the static triangles. for(int i=0; i<9; i++){ for(int j=0; j<6; j++){ cpFloat stagger = (j%2)*40; cpVect offset = cpv(i*80 - 320 + stagger, j*70 - 240); shape = cpSpaceAddShape(space, cpPolyShapeNew(staticBody, 3, tris, offset)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); } } // Create vertexes for a pentagon shape. cpVect verts[NUM_VERTS]; for(int i=0; i<NUM_VERTS; i++){ cpFloat angle = -2*M_PI*i/((cpFloat) NUM_VERTS); verts[i] = cpv(10*cos(angle), 10*sin(angle)); } pentagon_mass = 1.0; pentagon_moment = cpMomentForPoly(1.0f, NUM_VERTS, verts, cpvzero); // Add lots of pentagons. for(int i=0; i<300; i++){ body = cpSpaceAddBody(space, cpBodyNew(pentagon_mass, pentagon_moment)); cpFloat x = rand()/(cpFloat)RAND_MAX*640 - 320; cpBodySetPos(body, cpv(x, 350)); shape = cpSpaceAddShape(space, cpPolyShapeNew(body, NUM_VERTS, verts, cpvzero)); cpShapeSetElasticity(shape, 0.0f); cpShapeSetFriction(shape, 0.4f); } return space; }
static void create_physics_objects(game_state *state) { switch_state_data *data = state->data->switch_data; cpSpace *space = cpSpaceNew(); cpSpaceSetGravity(space, cpv(0, 250)); /* add borders */ cpShape *shape = NULL; shape = cpSpaceAddShape(space, cpSegmentShapeNew(space->staticBody, cpv(0, 0), cpv(0, SCREEN_HEIGHT), 0)); cpShapeSetLayers(shape, L_GROUND); shape =cpSpaceAddShape(space, cpSegmentShapeNew(space->staticBody, cpv(0, SCREEN_HEIGHT), cpv(SCREEN_WIDTH, SCREEN_HEIGHT), 0)); cpShapeSetLayers(shape, L_GROUND); shape = cpSpaceAddShape(space, cpSegmentShapeNew(space->staticBody, cpv(SCREEN_WIDTH, SCREEN_HEIGHT), cpv(SCREEN_WIDTH, 0), 0)); cpShapeSetLayers(shape, L_GROUND); shape = cpSpaceAddShape(space, cpSegmentShapeNew(space->staticBody, cpv(SCREEN_WIDTH, 0), cpv(0, 0), 0)); cpShapeSetLayers(shape, L_GROUND); ent_switch *sw = ent_switch_new(space, cpv(SCREEN_WIDTH / 2, SCREEN_HEIGHT + 2), 0); data->space = space; data->sw = sw; }
void PhysicsShape::componentComplete() { if(m_shapeType == PhysicsTypes::Box) { cpVect niz[] = { cpv(-(this->width()/2.0f), -(this->height()/2.0f)), cpv(-(this->width()/2.0f), (this->height()/2.0f)), cpv( (this->width()/2.0f), (this->height()/2.0f)), cpv( (this->width()/2.0f), -(this->height()/2.0f)) }; m_shape = cpPolyShapeNew(NULL, 4, niz, cpv(m_offsetX, -m_offsetY)); } else if(m_shapeType == PhysicsTypes::Circle) { m_shape = cpCircleShapeNew(NULL, m_diameter/2, cpvzero); } else { //TODO error qDebug() << "Error circle"; } m_shape->data = this; cpShapeSetFriction(m_shape, m_friction); cpShapeSetElasticity(m_shape, m_elasticity); if(m_sensor) { cpShapeSetSensor(m_shape, true); } cpShapeSetLayers(m_shape, m_layer); m_isPhysicsCreated = true; m_world->addPhysicsInterface(this); if(m_debugDraw) { this->setFlag(QQuickItem::ItemHasContents, true); } if(m_debugPrint) { qDebug() << "PhysicsShape - componentComplete()"; qDebug() << " Is sensor:" << m_sensor; qDebug() << " Shape type:" << m_shapeType; qDebug() << " Name:" << m_name; qDebug() << " Width:" << this->width(); qDebug() << " Height:" << this->height(); qDebug() << " QQuickitem pos:" << this->x() << this->y(); qDebug() << " Offset pos:" << this->m_offsetX << this->m_offsetY; } QQuickItem::componentComplete(); }
// NOTE - don't use a GEAR attachment to attach to the wall - the peg does not rotate, so the body will not rotate void MachineSystem::addPart(MachinePart *newPart, Attachment *attachment, cpVect gridPosition) { int machineNumber = machinePositionToNumber(gridPosition); MachinePart *alreadyAttached = parts[machineNumber]; if (!alreadyAttached) { cpVect pegPosition = gridPositionToWorld(gridPosition); cpBody *pegBody = cpBodyNewStatic(); cpBodySetPos(pegBody, pegPosition); cpShape *pegShape = cpCircleShapeNew(pegBody, 5.0, cpv(0,0)); cpShapeSetLayers(pegShape, PEG_LAYER); cpSpaceAddStaticShape(space, pegShape); parts[machineNumber] = newPart; nMachines++; newPart->setOriginalPosition(pegPosition); newPart->attachToBody(attachment, pegBody); attachments[machineNumber][machineNumber] = attachment; } }
static cpSpace * init(void) { // Create a rouge body to control the planet manually. planetBody = cpBodyNew(INFINITY, INFINITY); cpBodySetAngVel(planetBody, 0.2f); cpSpace *space = cpSpaceNew(); cpSpaceSetIterations(space, 20); for(int i=0; i<30; i++) add_box(space); cpShape *shape = cpSpaceAddShape(space, cpCircleShapeNew(planetBody, 70.0f, cpvzero)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); return space; }
static cpSpace * init(void) { cpSpace *space = cpSpaceNew(); cpSpaceSetIterations(space, 30); cpSpaceSetGravity(space, cpv(0, -300)); cpSpaceSetSleepTimeThreshold(space, 0.5f); cpSpaceSetCollisionSlop(space, 0.5f); // Add a floor. cpShape *shape = cpSpaceAddShape(space, cpSegmentShapeNew(cpSpaceGetStaticBody(space), cpv(-600,-240), cpv(600,-240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); // Add the dominoes. int n = 12; for(int i=0; i<n; i++){ for(int j=0; j<(n - i); j++){ cpVect offset = cpv((j - (n - 1 - i)*0.5f)*1.5f*HEIGHT, (i + 0.5f)*(HEIGHT + 2*WIDTH) - WIDTH - 240); add_domino(space, offset, cpFalse); add_domino(space, cpvadd(offset, cpv(0, (HEIGHT + WIDTH)/2.0f)), cpTrue); if(j == 0){ add_domino(space, cpvadd(offset, cpv(0.5f*(WIDTH - HEIGHT), HEIGHT + WIDTH)), cpFalse); } if(j != n - i - 1){ add_domino(space, cpvadd(offset, cpv(HEIGHT*0.75f, (HEIGHT + 3*WIDTH)/2.0f)), cpTrue); } else { add_domino(space, cpvadd(offset, cpv(0.5f*(HEIGHT - WIDTH), HEIGHT + WIDTH)), cpFalse); } } } return space; }
void EndlessWorld::extendFlat() { //flat cpVect verts[] = { cpv(koniec - dodatek - G_odlegloscmiedzyBramkami, -2000), cpv(koniec - dodatek - G_odlegloscmiedzyBramkami, 0), cpv(koniec, 0), cpv(koniec, -2000), }; cpSpaceRemoveStaticShape(gravitySpace, floor); floor = cpPolyShapeNew(floorBody, 4, verts, cpvzero); floor->e = 0;//elastycznosc; floor->u = 0.1f;//friction floor->collision_type = COLLISIONTYPEFLOOR; cpShapeSetLayers(floor, CPFLOORCOLIDER); cpSpaceAddStaticShape(gravitySpace, floor); flatsprite->setTextureRect(Rect(verts[0].x, verts[1].y, abs(verts[3].x), flatsprite->getTexture()->getContentSize().height)); bottomSpr->setPositionX(koniec - dodatek - G_odlegloscmiedzyBramkami); //chkpts if (isEndless()) { for (int i = koniec - dodatek; i <= koniec; i += G_odlegloscmiedzyBramkami) { auto chkpt = Chcekpoint::create(this, &orderedOpponents, R_SPRITE_checkpoint); chkpt->setPosition(i, floor->bb.t); modifyGate(chkpt); rotationLayer->addChild(chkpt); } } //POWERUPS for (int j = koniec - dodatek + G_powerUpOdleglos + random(0,G_powerUpOdlegloscVar); j <= koniec; j += G_powerUpOdleglos + random(0,G_powerUpOdlegloscVar)) { int wysokosc = 2.5f * Sprite::createWithSpriteFrameName(R_Box[1])->getContentSize().height; PowerUp *pwrup = PowerUp::create(&orderedOpponents); pwrup->setPosition(Vec2(j, floor->bb.t + wysokosc)); rotationLayer->addChild(pwrup); } }
cpShape *eol_level_add_segment_to_space(eolFloat sx, eolFloat sy, eolFloat ex, eolFloat ey, cpSpace *space) { cpShape *shape; float friction = 0.1; if(space == NULL)return NULL; shape = cpSegmentShapeNew(cpSpaceGetStaticBody(space), cpv(sx,sy), cpv(ex,ey), _eol_level_clip_thickness); if (sx == ex) { friction = 0; } if(shape != NULL) { shape->e = 0; shape->u = friction; shape->collision_type = eolEntityClipLevel; cpShapeSetLayers (shape, eolEntityClipLevel); cpSpaceAddShape(space, shape); } return shape; }
void CCPhysicsShape::setCollisionLayers(int layers) { cpShapeSetLayers(m_shape, (cpLayers)layers); }
static cpSpace * init(void) { ChipmunkDemoMessageString = "Use the arrow keys to control the machine."; space = cpSpaceNew(); cpSpaceSetGravity(space, cpv(0, -600)); cpBody *staticBody = cpSpaceGetStaticBody(space); cpShape *shape; // beveling all of the line segments slightly helps prevent things from getting stuck on cracks shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-256,16), cpv(-256,300), 2.0f)); cpShapeSetElasticity(shape, 0.0f); cpShapeSetFriction(shape, 0.5f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-256,16), cpv(-192,0), 2.0f)); cpShapeSetElasticity(shape, 0.0f); cpShapeSetFriction(shape, 0.5f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-192,0), cpv(-192, -64), 2.0f)); cpShapeSetElasticity(shape, 0.0f); cpShapeSetFriction(shape, 0.5f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-128,-64), cpv(-128,144), 2.0f)); cpShapeSetElasticity(shape, 0.0f); cpShapeSetFriction(shape, 0.5f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-192,80), cpv(-192,176), 2.0f)); cpShapeSetElasticity(shape, 0.0f); cpShapeSetFriction(shape, 0.5f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-192,176), cpv(-128,240), 2.0f)); cpShapeSetElasticity(shape, 0.0f); cpShapeSetFriction(shape, 0.5f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-128,144), cpv(192,64), 2.0f)); cpShapeSetElasticity(shape, 0.0f); cpShapeSetFriction(shape, 0.5f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); cpVect verts[] = { cpv(-30,-80), cpv(-30, 80), cpv( 30, 64), cpv( 30,-80), }; cpBody *plunger = cpSpaceAddBody(space, cpBodyNew(1.0f, INFINITY)); cpBodySetPos(plunger, cpv(-160,-80)); shape = cpSpaceAddShape(space, cpPolyShapeNew(plunger, 4, verts, cpvzero)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 0.5f); cpShapeSetLayers(shape, 1); // add balls to hopper for(int i=0; i<numBalls; i++) balls[i] = add_ball(cpv(-224 + i,80 + 64*i)); // add small gear cpBody *smallGear = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 80, 0, cpvzero))); cpBodySetPos(smallGear, cpv(-160,-160)); cpBodySetAngle(smallGear, -M_PI_2); shape = cpSpaceAddShape(space, cpCircleShapeNew(smallGear, 80.0f, cpvzero)); cpShapeSetLayers(shape, 0); cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, smallGear, cpv(-160,-160), cpvzero)); // add big gear cpBody *bigGear = cpSpaceAddBody(space, cpBodyNew(40.0f, cpMomentForCircle(40.0f, 160, 0, cpvzero))); cpBodySetPos(bigGear, cpv(80,-160)); cpBodySetAngle(bigGear, M_PI_2); shape = cpSpaceAddShape(space, cpCircleShapeNew(bigGear, 160.0f, cpvzero)); cpShapeSetLayers(shape, 0); cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, bigGear, cpv(80,-160), cpvzero)); // connect the plunger to the small gear. cpSpaceAddConstraint(space, cpPinJointNew(smallGear, plunger, cpv(80,0), cpv(0,0))); // connect the gears. cpSpaceAddConstraint(space, cpGearJointNew(smallGear, bigGear, -M_PI_2, -2.0f)); // feeder mechanism cpFloat bottom = -300.0f; cpFloat top = 32.0f; cpBody *feeder = cpSpaceAddBody(space, cpBodyNew(1.0f, cpMomentForSegment(1.0f, cpv(-224.0f, bottom), cpv(-224.0f, top)))); cpBodySetPos(feeder, cpv(-224, (bottom + top)/2.0f)); cpFloat len = top - bottom; cpSpaceAddShape(space, cpSegmentShapeNew(feeder, cpv(0.0f, len/2.0f), cpv(0.0f, -len/2.0f), 20.0f)); cpSpaceAddConstraint(space, cpPivotJointNew2(staticBody, feeder, cpv(-224.0f, bottom), cpv(0.0f, -len/2.0f))); cpVect anchr = cpBodyWorld2Local(feeder, cpv(-224.0f, -160.0f)); cpSpaceAddConstraint(space, cpPinJointNew(feeder, smallGear, anchr, cpv(0.0f, 80.0f))); // motorize the second gear motor = cpSpaceAddConstraint(space, cpSimpleMotorNew(staticBody, bigGear, 3.0f)); return space; }
static cpSpace * init(void) { ChipmunkDemoMessageString = "Use the arrow keys to control the machine."; space = cpSpaceNew(); cpSpaceSetIterations(space, 20); cpSpaceSetGravity(space, cpv(0,-500)); cpBody *staticBody = cpSpaceGetStaticBody(space); cpShape *shape; cpVect a, b; // Create segments around the edge of the screen. shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); cpFloat offset = 30.0f; // make chassis cpFloat chassis_mass = 2.0f; a = cpv(-offset, 0.0f), b = cpv(offset, 0.0f); cpBody *chassis = cpSpaceAddBody(space, cpBodyNew(chassis_mass, cpMomentForSegment(chassis_mass, a, b))); shape = cpSpaceAddShape(space, cpSegmentShapeNew(chassis, a, b, seg_radius)); cpShapeSetGroup(shape, 1); // make crank cpFloat crank_mass = 1.0f; cpFloat crank_radius = 13.0f; cpBody *crank = cpSpaceAddBody(space, cpBodyNew(crank_mass, cpMomentForCircle(crank_mass, crank_radius, 0.0f, cpvzero))); shape = cpSpaceAddShape(space, cpCircleShapeNew(crank, crank_radius, cpvzero)); cpShapeSetGroup(shape, 1); cpSpaceAddConstraint(space, cpPivotJointNew2(chassis, crank, cpvzero, cpvzero)); cpFloat side = 30.0f; int num_legs = 2; for(int i=0; i<num_legs; i++){ make_leg(side, offset, chassis, crank, cpvmult(cpvforangle((cpFloat)(2*i+0)/(cpFloat)num_legs*M_PI), crank_radius)); make_leg(side, -offset, chassis, crank, cpvmult(cpvforangle((cpFloat)(2*i+1)/(cpFloat)num_legs*M_PI), crank_radius)); } motor = cpSpaceAddConstraint(space, cpSimpleMotorNew(chassis, crank, 6.0f)); return space; }
static cpSpace * init(void) { cpSpace *space = cpSpaceNew(); cpSpaceSetIterations(space, 30); cpSpaceSetGravity(space, cpv(0, -100)); cpSpaceSetSleepTimeThreshold(space, 0.5f); cpBody *body, *staticBody = cpSpaceGetStaticBody(space); cpShape *shape; // Create segments around the edge of the screen. shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); cpFloat mass = 1; cpFloat width = 20; cpFloat height = 30; cpFloat spacing = width*0.3; // Add lots of boxes. for(int i=0; i<CHAIN_COUNT; i++){ cpBody *prev = NULL; for(int j=0; j<LINK_COUNT; j++){ cpVect pos = cpv(40*(i - (CHAIN_COUNT - 1)/2.0), 240 - (j + 0.5)*height - (j + 1)*spacing); body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForBox(mass, width, height))); cpBodySetPos(body, pos); shape = cpSpaceAddShape(space, cpBoxShapeNew(body, width, height)); cpShapeSetFriction(shape, 0.8f); cpFloat breakingForce = 80000; cpConstraint *constraint = NULL; if(prev == NULL){ constraint = cpSpaceAddConstraint(space, cpSlideJointNew(body, staticBody, cpv(0, height/2), cpv(pos.x, 240), 0, spacing)); } else { constraint = cpSpaceAddConstraint(space, cpSlideJointNew(body, prev, cpv(0, height/2), cpv(0, -height/2), 0, spacing)); } cpConstraintSetMaxForce(constraint, breakingForce); cpConstraintSetPostSolveFunc(constraint, BreakableJointPostSolve); prev = body; } } cpFloat radius = 15.0f; body = cpSpaceAddBody(space, cpBodyNew(10.0f, cpMomentForCircle(10.0f, 0.0f, radius, cpvzero))); cpBodySetPos(body, cpv(0, -240 + radius+5)); cpBodySetVel(body, cpv(0, 300)); shape = cpSpaceAddShape(space, cpCircleShapeNew(body, radius, cpvzero)); cpShapeSetElasticity(shape, 0.0f); cpShapeSetFriction(shape, 0.9f); return space; }
MachineSystem::MachineSystem(MachineSystem &original, cpVect position) : space(cpSpaceNew()), size(original.size), gridSpacing(original.gridSpacing), inputMachinePosition(original.inputMachinePosition), outputMachinePosition(original.outputMachinePosition), nMachines(0), nAttachments(0), destroyAttachments(original.destroyAttachments) { cpFloat width = (original.size.x +1)*original.gridSpacing.x; cpFloat height = (original.size.y +1)*original.gridSpacing.y; body = cpBodyNewStatic(); cpBodySetPos(body, position); cpShape *wallShape = cpSegmentShapeNew(body, cpv(-width/2, height/2), cpv(width/2, height/2), .5); cpShapeSetLayers(wallShape, WALL_LAYER); cpSpaceAddStaticShape(space, wallShape); wallShape = cpSegmentShapeNew(body, cpv(-width/2, -height/2), cpv(+width/2, -height/2), 0.5); cpShapeSetLayers(wallShape, WALL_LAYER); cpSpaceAddStaticShape(space, wallShape); wallShape = cpSegmentShapeNew(body, cpv(-width/2, +height/2), cpv(-width/2, -height/2), 0.5); cpShapeSetLayers(wallShape, WALL_LAYER); cpSpaceAddStaticShape(space, wallShape); wallShape = cpSegmentShapeNew(body, cpv(+width/2, +height/2), cpv(+width/2, -height/2), 0.5); cpShapeSetLayers(wallShape, WALL_LAYER); cpSpaceAddStaticShape(space, wallShape); // do the copy of the attachment and machines manually, because we need to add and attach machines int nPegs = size.x*size.y; parts.resize(nPegs, NULL); attachments.resize(nPegs); for (int i=0; i<nPegs; i++) attachments[i].resize(nPegs, NULL); for (int x = 0; x < size.x; x++ ) { for (int y = 0; y < size.y; y++) { cpVect gridPos = cpv(x,y); int machineNum = machinePositionToNumber(gridPos); MachinePart *machineToCopy = original.parts[machineNum]; if (machineToCopy) { MachinePart *newPart = new MachinePart(*machineToCopy, space); Attachment *wallAttachment = Attachment::copyAttachment(original.attachments[machineNum][machineNum]); addPart(newPart, wallAttachment, gridPos); } } } for (int i=0; i<nPegs; i++) { for (int j=0; j<i; j++) { Attachment *attachmentToCopy = original.attachments[i][j]; if (attachmentToCopy) { Attachment *attachmentCopy = Attachment::copyAttachment(attachmentToCopy); cpVect machine1Pos = machineNumberToPosition(i); cpVect machine2Pos = machineNumberToPosition(j); attachMachines(machine1Pos, machine2Pos, attachmentCopy); attachmentCopy->innovationNumber = attachmentToCopy->innovationNumber; } } } }
static cpSpace * init(void) { ChipmunkDemoMessageString = "Control the crane by moving the mouse. Press the down arrow to release."; space = cpSpaceNew(); cpSpaceSetIterations(space, 30); cpSpaceSetGravity(space, cpv(0, -100)); cpSpaceSetDamping(space, 0.8); cpBody *staticBody = cpSpaceGetStaticBody(space); cpShape *shape; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); // Add a body for the dolly. dollyBody = cpSpaceAddBody(space, cpBodyNew(10, INFINITY)); cpBodySetPos(dollyBody, cpv(0, 100)); // Add a block so you can see it. cpSpaceAddShape(space, cpBoxShapeNew(dollyBody, 30, 30)); // Add a groove joint for it to move back and forth on. cpSpaceAddConstraint(space, cpGrooveJointNew(staticBody, dollyBody, cpv(-250, 100), cpv(250, 100), cpvzero)); // Add a pivot joint to act as a servo motor controlling it's position // By updating the anchor points of the pivot joint, you can move the dolly. dollyServo = cpSpaceAddConstraint(space, cpPivotJointNew(staticBody, dollyBody, cpBodyGetPos(dollyBody))); // Max force the dolly servo can generate. cpConstraintSetMaxForce(dollyServo, 10000); // Max speed of the dolly servo cpConstraintSetMaxBias(dollyServo, 100); // You can also change the error bias to control how it slows down. //cpConstraintSetErrorBias(dollyServo, 0.2); // Add the crane hook. cpBody *hookBody = cpSpaceAddBody(space, cpBodyNew(1, INFINITY)); cpBodySetPos(hookBody, cpv(0, 50)); // Add a sensor shape for it. This will be used to figure out when the hook touches a box. shape = cpSpaceAddShape(space, cpCircleShapeNew(hookBody, 10, cpvzero)); cpShapeSetSensor(shape, cpTrue); cpShapeSetCollisionType(shape, HOOK_SENSOR); // Add a slide joint to act as a winch motor // By updating the max length of the joint you can make it pull up the load. winchServo = cpSpaceAddConstraint(space, cpSlideJointNew(dollyBody, hookBody, cpvzero, cpvzero, 0, INFINITY)); // Max force the dolly servo can generate. cpConstraintSetMaxForce(winchServo, 30000); // Max speed of the dolly servo cpConstraintSetMaxBias(winchServo, 60); // TODO cleanup // Finally a box to play with cpBody *boxBody = cpSpaceAddBody(space, cpBodyNew(30, cpMomentForBox(30, 50, 50))); cpBodySetPos(boxBody, cpv(200, -200)); // Add a block so you can see it. shape = cpSpaceAddShape(space, cpBoxShapeNew(boxBody, 50, 50)); cpShapeSetFriction(shape, 0.7); cpShapeSetCollisionType(shape, CRATE); cpSpaceAddCollisionHandler(space, HOOK_SENSOR, CRATE, (cpCollisionBeginFunc)HookCrate, NULL, NULL, NULL, NULL); return space; }
static cpSpace * init(void) { space = cpSpaceNew(); cpSpaceSetIterations(space, 10); cpSpaceSetGravity(space, cpv(0, -100)); cpSpaceSetSleepTimeThreshold(space, 0.5f); cpBody *staticBody = cpSpaceGetStaticBody(space); cpShape *shape; shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,120), cpv(320,120), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,0), cpv(320,0), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-120), cpv(320,-120), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-160,-240), cpv(-160,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(0,-240), cpv(0,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(160,-240), cpv(160,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f)); cpShapeSetElasticity(shape, 1.0f); cpShapeSetFriction(shape, 1.0f); cpShapeSetLayers(shape, NOT_GRABABLE_MASK); cpVect boxOffset; cpBody *body1, *body2; cpVect posA = cpv( 50, 60); cpVect posB = cpv(110, 60); #define POS_A cpvadd(boxOffset, posA) #define POS_B cpvadd(boxOffset, posB) // Pin Joints - Link shapes with a solid bar or pin. // Keeps the anchor points the same distance apart from when the joint was created. boxOffset = cpv(-320, -240); body1 = addBall(posA, boxOffset); body2 = addBall(posB, boxOffset); cpSpaceAddConstraint(space, cpPinJointNew(body1, body2, cpv(15,0), cpv(-15,0))); // Slide Joints - Like pin joints but with a min/max distance. // Can be used for a cheap approximation of a rope. boxOffset = cpv(-160, -240); body1 = addBall(posA, boxOffset); body2 = addBall(posB, boxOffset); cpSpaceAddConstraint(space, cpSlideJointNew(body1, body2, cpv(15,0), cpv(-15,0), 20.0f, 40.0f)); // Pivot Joints - Holds the two anchor points together. Like a swivel. boxOffset = cpv(0, -240); body1 = addBall(posA, boxOffset); body2 = addBall(posB, boxOffset); cpSpaceAddConstraint(space, cpPivotJointNew(body1, body2, cpvadd(boxOffset, cpv(80,60)))); // cpPivotJointNew() takes it's anchor parameter in world coordinates. The anchors are calculated from that // cpPivotJointNew2() lets you specify the two anchor points explicitly // Groove Joints - Like a pivot joint, but one of the anchors is a line segment that the pivot can slide in boxOffset = cpv(160, -240); body1 = addBall(posA, boxOffset); body2 = addBall(posB, boxOffset); cpSpaceAddConstraint(space, cpGrooveJointNew(body1, body2, cpv(30,30), cpv(30,-30), cpv(-30,0))); // Damped Springs boxOffset = cpv(-320, -120); body1 = addBall(posA, boxOffset); body2 = addBall(posB, boxOffset); cpSpaceAddConstraint(space, cpDampedSpringNew(body1, body2, cpv(15,0), cpv(-15,0), 20.0f, 5.0f, 0.3f)); // Damped Rotary Springs boxOffset = cpv(-160, -120); body1 = addBar(posA, boxOffset); body2 = addBar(posB, boxOffset); // Add some pin joints to hold the circles in place. cpSpaceAddConstraint(space, cpPivotJointNew(body1, staticBody, POS_A)); cpSpaceAddConstraint(space, cpPivotJointNew(body2, staticBody, POS_B)); cpSpaceAddConstraint(space, cpDampedRotarySpringNew(body1, body2, 0.0f, 3000.0f, 60.0f)); // Rotary Limit Joint boxOffset = cpv(0, -120); body1 = addLever(posA, boxOffset); body2 = addLever(posB, boxOffset); // Add some pin joints to hold the circles in place. cpSpaceAddConstraint(space, cpPivotJointNew(body1, staticBody, POS_A)); cpSpaceAddConstraint(space, cpPivotJointNew(body2, staticBody, POS_B)); // Hold their rotation within 90 degrees of each other. cpSpaceAddConstraint(space, cpRotaryLimitJointNew(body1, body2, -M_PI_2, M_PI_2)); // Ratchet Joint - A rotary ratchet, like a socket wrench boxOffset = cpv(160, -120); body1 = addLever(posA, boxOffset); body2 = addLever(posB, boxOffset); // Add some pin joints to hold the circles in place. cpSpaceAddConstraint(space, cpPivotJointNew(body1, staticBody, POS_A)); cpSpaceAddConstraint(space, cpPivotJointNew(body2, staticBody, POS_B)); // Ratchet every 90 degrees cpSpaceAddConstraint(space, cpRatchetJointNew(body1, body2, 0.0f, M_PI_2)); // Gear Joint - Maintain a specific angular velocity ratio boxOffset = cpv(-320, 0); body1 = addBar(posA, boxOffset); body2 = addBar(posB, boxOffset); // Add some pin joints to hold the circles in place. cpSpaceAddConstraint(space, cpPivotJointNew(body1, staticBody, POS_A)); cpSpaceAddConstraint(space, cpPivotJointNew(body2, staticBody, POS_B)); // Force one to sping 2x as fast as the other cpSpaceAddConstraint(space, cpGearJointNew(body1, body2, 0.0f, 2.0f)); // Simple Motor - Maintain a specific angular relative velocity boxOffset = cpv(-160, 0); body1 = addBar(posA, boxOffset); body2 = addBar(posB, boxOffset); // Add some pin joints to hold the circles in place. cpSpaceAddConstraint(space, cpPivotJointNew(body1, staticBody, POS_A)); cpSpaceAddConstraint(space, cpPivotJointNew(body2, staticBody, POS_B)); // Make them spin at 1/2 revolution per second in relation to each other. cpSpaceAddConstraint(space, cpSimpleMotorNew(body1, body2, M_PI)); // Make a car with some nice soft suspension boxOffset = cpv(0, 0); cpBody *wheel1 = addWheel(posA, boxOffset); cpBody *wheel2 = addWheel(posB, boxOffset); cpBody *chassis = addChassis(cpv(80, 100), boxOffset); cpSpaceAddConstraint(space, cpGrooveJointNew(chassis, wheel1, cpv(-30, -10), cpv(-30, -40), cpvzero)); cpSpaceAddConstraint(space, cpGrooveJointNew(chassis, wheel2, cpv( 30, -10), cpv( 30, -40), cpvzero)); cpSpaceAddConstraint(space, cpDampedSpringNew(chassis, wheel1, cpv(-30, 0), cpvzero, 50.0f, 20.0f, 10.0f)); cpSpaceAddConstraint(space, cpDampedSpringNew(chassis, wheel2, cpv( 30, 0), cpvzero, 50.0f, 20.0f, 10.0f)); return space; }