ETERM *body_update_position(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); ETERM *deltap = erl_element(3, argp); erlmunk_space *s = NULL; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int body_id = ERL_INT_VALUE(idp); erlmunk_body *b = NULL; HASH_FIND_INT(s->bodies, &body_id, b); if (b == NULL) return NULL; cpVect position = cpBodyGetPosition(b->body); float angle = deg_to_rad(cpBodyGetAngle(b->body)); cpVect angleV = cpvforangle(angle); cpVect projection = cpvmult(angleV, ERL_FLOAT_VALUE(deltap)); cpVect new_position = cpvadd(projection, position); cpBodySetPosition(b->body, new_position); // DEBUGF(("body_update_position(x: %f, y: %f, delta: %f) has succeeded (x: %f, y: %f)", // position.x, position.y, ERL_FLOAT_VALUE(deltap), // new_position.x, new_position.y)); return NULL; }
ETERM *body_copy(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); ETERM *from_idp = erl_element(3, argp); erlmunk_space *s; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int body_id = ERL_INT_VALUE(idp); erlmunk_body *b; HASH_FIND_INT(s->bodies, &body_id, b); if (b == NULL) return NULL; int from_body_id = ERL_INT_VALUE(from_idp); erlmunk_body *from_b; HASH_FIND_INT(s->bodies, &from_body_id, from_b); // DEBUGF(("copying location from body #%d(%p) to #%d(%p)", // from_body_id, from_b, body_id, b)); // copy position and angle from the from body cpBodySetPosition(b->body, cpBodyGetPosition(from_b->body)); cpBodySetAngle(b->body, cpBodyGetAngle(from_b->body)); cpBodySetVelocity(b->body, cpBodyGetVelocity(from_b->body)); return NULL; }
void weapon_update(Entity *ent) { cpBody *body = entity_body(ent); WeaponEntityData *data = entity_data(ent); if (data->owner && !data->player_joint) { cvar_setd_player(entity_owner(ent), "weapon_id", entity_id(ent)); data->player_joint = cpSpaceAddConstraint(game.space, cpPivotJointNew2( body, entity_body(data->owner), cpv(0, -WEAPON_HEIGHT / 2), cpv(1, 0) )); cpConstraintSetErrorBias(data->player_joint, 0); } int mult = 0; if (keymap_is_held("mouse1")) mult++; if (keymap_is_held("mouse2")) mult--; if (mult) { cpVect force_pos = cpv(0, WEAPON_HEIGHT); cpVect weapon_pos = cpBodyGetPosition(body); cpVect world_force_pos = cpvadd(weapon_pos, cpvrotate(cpBodyGetRotation(body), force_pos)); cpVect mouse_delta = cpvsub(keymap_mouse_world(), world_force_pos); cpVect force = cpvmult(cpvnormalize(mouse_delta), mult * WEAPON_SWING_FORCE); cpBodyApplyForceAtWorldPoint(body, force, world_force_pos); } }
void handle_subscriber(erlmunk_subscriber *subscriber, element *bodies) { element *el; int count = 0; LL_COUNT(bodies, el, count); // DEBUGF(("# bodies in subscriber bounding box: %d", count)); ETERM **l_array = (ETERM **) malloc(sizeof(ETERM) * count); int nth_body = 0; LL_FOREACH(bodies, el) { cpVect vect = cpBodyGetPosition(el->body); float angle = cpBodyGetAngle(el->body); // cpVect vel = cpBodyGetVelocity(el->body); erlmunk_body_data *data = (erlmunk_body_data *) cpBodyGetUserData(el->body); // DEBUGF(("id: %d, x: %f, y: %f, angle: %f, vel.x: %f, vel.y: %f, data: %p", // data->id, vect.x, vect.y, angle, vel.x, vel.y, data)); ETERM **t_array = (ETERM **) malloc(sizeof(ETERM) * 4); t_array[0] = erl_mk_float(vect.x); t_array[1] = erl_mk_float(vect.y); t_array[2] = erl_mk_float(angle); if (data->term == NULL) t_array[3] = erl_mk_undefined(); else t_array[3] = erl_copy_term(data->term); ETERM *tuple = erl_mk_tuple(t_array, 4); free(t_array); ETERM *prop_value = erl_mk_int_prop_value(data->id, tuple); l_array[nth_body++] = prop_value; }
void PhysicsForceField::addBodyField(cpVect p, PhysicsBody* body, float mass, cpVect& ret) { cpBody* cpBody = body->getCPBody(); cpVect d = cpvsub(cpBodyGetPosition(cpBody), p); float dlensq = cpvlengthsq(d); if (dlensq >= _minDistanceSq) { ret = cpvadd(ret, cpvmult(d, mass / (dlensq*cpfsqrt(dlensq)) )); } }
RVector RCPBody::position() const { if (mBody) { cpVect p = cpBodyGetPosition(mBody); mPosition = RVector(p.x, p.y); } return mPosition; }
static void DrawConstraint(cpConstraint *constraint, DrawNode *renderer) { cpBody *body_a = cpConstraintGetBodyA(constraint); cpBody *body_b = cpConstraintGetBodyB(constraint); if(cpConstraintIsPinJoint(constraint)) { cpVect a = cpvadd(cpBodyGetPosition(body_a), cpvrotate(cpPinJointGetAnchorA(constraint), cpBodyGetRotation(body_a))); cpVect b = cpvadd(cpBodyGetPosition(body_b), cpvrotate(cpPinJointGetAnchorB(constraint), cpBodyGetRotation(body_b))); renderer->drawDot(cpVert2Point(a), 3.0, CONSTRAINT_COLOR); renderer->drawDot(cpVert2Point(b), 3.0, CONSTRAINT_COLOR); renderer->drawSegment(cpVert2Point(a), cpVert2Point(b), 1.0, CONSTRAINT_COLOR); } else if(cpConstraintIsSlideJoint(constraint)) { cpVect a = cpvadd(cpBodyGetPosition(body_a), cpvrotate(cpSlideJointGetAnchorA(constraint), cpBodyGetRotation(body_a))); cpVect b = cpvadd(cpBodyGetPosition(body_b), cpvrotate(cpSlideJointGetAnchorB(constraint), cpBodyGetRotation(body_b))); renderer->drawDot(cpVert2Point(a), 3.0, CONSTRAINT_COLOR); renderer->drawDot(cpVert2Point(b), 3.0, CONSTRAINT_COLOR); renderer->drawSegment(cpVert2Point(a), cpVert2Point(b), 1.0, CONSTRAINT_COLOR); } else if(cpConstraintIsPivotJoint(constraint)) { cpVect a = cpvadd(cpBodyGetPosition(body_a), cpvrotate(cpPivotJointGetAnchorA(constraint), cpBodyGetRotation(body_a))); cpVect b = cpvadd(cpBodyGetPosition(body_b), cpvrotate(cpPivotJointGetAnchorB(constraint), cpBodyGetRotation(body_b))); renderer->drawDot(cpVert2Point(a), 3.0, CONSTRAINT_COLOR); renderer->drawDot(cpVert2Point(b), 3.0, CONSTRAINT_COLOR); } else if(cpConstraintIsGrooveJoint(constraint)) { cpVect a = cpvadd(cpBodyGetPosition(body_a), cpvrotate(cpGrooveJointGetGrooveA(constraint), cpBodyGetRotation(body_a))); cpVect b = cpvadd(cpBodyGetPosition(body_a), cpvrotate(cpGrooveJointGetGrooveB(constraint), cpBodyGetRotation(body_a))); cpVect c = cpvadd(cpBodyGetPosition(body_b), cpvrotate(cpGrooveJointGetAnchorB(constraint), cpBodyGetRotation(body_b))); renderer->drawDot(cpVert2Point(c), 3.0, CONSTRAINT_COLOR); renderer->drawSegment(cpVert2Point(a), cpVert2Point(b), 1.0, CONSTRAINT_COLOR); } else if(cpConstraintIsDampedSpring(constraint)) { // TODO: uninplemented } else { // printf("Cannot draw constraint\n"); } }
void RigidBody2D::CopyBodyData(cpBody* from, cpBody* to) { cpBodySetAngle(to, cpBodyGetAngle(from)); cpBodySetAngularVelocity(to, cpBodyGetAngularVelocity(from)); cpBodySetCenterOfGravity(to, cpBodyGetCenterOfGravity(from)); cpBodySetForce(to, cpBodyGetForce(from)); cpBodySetPosition(to, cpBodyGetPosition(from)); cpBodySetTorque(to, cpBodyGetTorque(from)); cpBodySetVelocity(to, cpBodyGetVelocity(from)); }
void RigidBody2D::CopyBodyData(cpBody* body) { cpBodySetAngle(m_handle, cpBodyGetAngle(body)); cpBodySetAngularVelocity(m_handle, cpBodyGetAngularVelocity(body)); cpBodySetCenterOfGravity(m_handle, cpBodyGetCenterOfGravity(body)); cpBodySetForce(m_handle, cpBodyGetForce(body)); cpBodySetPosition(m_handle, cpBodyGetPosition(body)); cpBodySetTorque(m_handle, cpBodyGetTorque(body)); cpBodySetVelocity(m_handle, cpBodyGetVelocity(body)); }
static float PlayerMiddleY(void) { float sum = 0; for (int i = 0; i < MAX_PLAYERS; i++) { const Player *p = &players[i]; if (!p->Alive) continue; sum += (float)cpBodyGetPosition(p->Body).y; } return sum / PlayerAliveCount(); }
bool Player::render(float time){ cpVect pos= cpBodyGetPosition(playerBody); cpVect vel = cpBodyGetVelocity(playerBody); playerX=pos.x; playerY=pos.y; printf("%4.2f %4.2f\n", playerX, playerY);//512->10*3 glSprite(playerX,playerY,GL2D_CENTER,&spr[0],false,0,0.01953125*3,0.01953125*3); return true; }
void initialize_player(struct obj *self) { Mix_Chunk *sound = load_sound("electric_1.wav"); CHECK_EXTRA_STRUCT(self,sizeof(struct player_extra), struct player_extra, .keystate = SDL_GetKeyboardState(NULL), .gunSound = sound); cpBodyEachShape(self->body, shape_set_collision_type, CT_PLAYER); printf("old volume: %d", sound, -1); self->room->viewport.focus = self->body; self->room->viewport.focusLast = cpBodyGetPosition(self->body); }
static int l_physics_getBodyPosition(lua_State* state) { l_tools_checkUserDataPlusErrMsg(state, 1, "You must provide a body"); l_physics_Body* body = (l_physics_Body*)lua_touserdata(state, 1); cpVect vec = cpBodyGetPosition(body->body); lua_pushnumber(state, vec.x); lua_pushnumber(state, vec.y); return 2; }
void BlockDraw(const Block *block, const float y) { const cpVect pos = cpBodyGetPosition(block->Body); SDL_Rect src = { 0, 0, SCREEN_X(block->W), block->T.H }; SDL_Rect dest = { (int)SCREEN_X((float)pos.x - block->W / 2), (int)(SCREEN_Y((float)pos.y + block->H / 2) - y), src.w, src.h }; RenderTex(block->T.T, &src, &dest); }
static void planetGravityVelocityFunc(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt) { // Gravitational acceleration is proportional to the inverse square of // distance, and directed toward the origin. The central planet is assumed // to be massive enough that it affects the satellites but not vice versa. cpVect p = cpBodyGetPosition(body); cpFloat sqdist = cpvlengthsq(p); cpVect g = cpvmult(p, -gravityStrength / (sqdist * cpfsqrt(sqdist))); cpBodyUpdateVelocity(body, g, damping, dt); }
/*** Step the space through time dt ***/ void Stage::updateEnvironment(double dt){ cpSpaceStep(envSpace, dt); cpVect controlPos = cpBodyGetPosition(userControlObject->body); if(firstPerson){ camera.update(glm::vec3(controlPos.x, controlPos.y + userControlObject->height/4.0f, 0.0f)); Obj::matView = glm::lookAt(camera.pos, camera.origin, camera.up); } else Obj::matView = glm::lookAt(glm::vec3(controlPos.x, controlPos.y + 400.0f, 1000.0f), glm::vec3(controlPos.x, controlPos.y, 0.0f), camera.up); skybox->position = glm::vec3(controlPos.x, controlPos.y, 0); }
/* Mouse handling is a bit tricky. We want the user to move * tiles using the mouse but because tiles are dynamic bodies * managed by Chipmunk2D, we cannot directly control them. * This is resolved by creating a pivot joint between an * invisible mouse body that we can control and the tile body * that we cannot directly control. */ static void apply_mouse_motion(struct state* state) { struct mouse m; update_mouse(&m); int w, h; get_screen_size(&w, &h); int x = m.x_position * w; int y = m.y_position * h; cpVect mouse_pos = cpv(x, y); cpVect new_point = cpvlerp(cpBodyGetPosition(state->mouse_body), mouse_pos, 0.25f); cpBodySetVelocity( state->mouse_body, cpvmult(cpvsub(new_point, cpBodyGetPosition(state->mouse_body)), 60.0f)); cpBodySetPosition(state->mouse_body, new_point); if (m.left_click && state->mouse_joint == NULL) { cpFloat radius = 5.0; cpPointQueryInfo info = { 0 }; cpShape* shape = cpSpacePointQueryNearest(state->space, mouse_pos, radius, GRAB_FILTER, &info); if (shape && cpBodyGetMass(cpShapeGetBody(shape)) < INFINITY) { cpVect nearest = (info.distance > 0.0f ? info.point : mouse_pos); cpBody* body = cpShapeGetBody(shape); state->mouse_joint = cpPivotJointNew2(state->mouse_body, body, cpvzero, cpBodyWorldToLocal(body, nearest)); cpConstraintSetMaxForce(state->mouse_joint, 5000000.0f); cpConstraintSetErrorBias(state->mouse_joint, cpfpow(1.0f - 0.15f, 60.0f)); cpSpaceAddConstraint(state->space, state->mouse_joint); } } if (m.left_click == false && state->mouse_joint != NULL) { cpSpaceRemoveConstraint(state->space, state->mouse_joint); cpConstraintFree(state->mouse_joint); state->mouse_joint = NULL; } }
int update_brain(Ship* s) { float* inputs = new float[NINPUTS]; float noseang = cpBodyGetAngle(s->body) + s->nose_angle; cpVect rpos = cpBodyGetPosition(s->target->body) - cpBodyGetPosition(s->body); inputs[0] = cpvlength(rpos); inputs[1] = restrictangle(cpvtoangle(rpos)-noseang); cpVect rvel = cpBodyGetVelocity(s->target->body) - cpBodyGetVelocity(s->body); inputs[2] = (rpos.x * rvel.x + rpos.y * rvel.y)/inputs[0]; inputs[3] = (rpos.x * rvel.y - rpos.y * rvel.x)/(inputs[0]*inputs[0]) - cpBodyGetAngularVelocity(s->body); inputs[4] = restrictangle(cpBodyGetAngle(s->target->body) + s->target->nose_angle - noseang); inputs[5] = cpBodyGetAngularVelocity(s->target->body); s->brain->update(inputs); delete inputs; return 0; }
void BlockDraw(const Block *block, const float y) { const cpVect pos = cpBodyGetPosition(block->Body); SDL_Rect src = { 0, 0, (Sint16)SCREEN_X(block->W), (Sint16)block->Surface->h }; SDL_Rect dest = { (Sint16)SCREEN_X((float)pos.x - block->W / 2), (Sint16)(SCREEN_Y((float)pos.y + block->H / 2) - y), 0, 0 }; SDL_BlitSurface(block->Surface, &src, Screen, &dest); }
static float PlayerMaxY(void) { float y = NAN; for (int i = 0; i < MAX_PLAYERS; i++) { const Player *p = &players[i]; if (!p->Alive) continue; const float py = (float)cpBodyGetPosition(p->Body).y; if (isnan(y) || py > y) { y = py; } } return y; }
/* Updating each frame * ------------------- * * Updating and drawing a frame takes stepping the Chipmunk2D * simulation by the 1/1000s fration of a second passed and * then drawing any active tile using its up-to-date * position. * We then delegate any mouse actions to apply_mouse_motion(). */ static void update_sample(void* data, float elapsed_ms) { struct state* state = data; cpFloat timeStep = elapsed_ms / 1000.0; cpSpaceStep(state->space, timeStep); screen_color(color_from_RGB(244, 244, 244)); for (size_t i = 0; i < MAX_TILES; i++) { if (state->tiles[i].is_active) { cpVect pos = cpBodyGetPosition(state->tiles[i].body); draw_image(state->tile_img, pos.x - state->tile_img->width / 2, pos.y - state->tile_img->height / 2, NULL, 0); } } apply_mouse_motion(state); }
const Vec2& PhysicsSprite::getPosFromPhysics() const { static Vec2 s_physicPosion; #if CC_ENABLE_CHIPMUNK_INTEGRATION cpVect cpPos = cpBodyGetPosition(_CPBody); s_physicPosion = Vec2(cpPos.x, cpPos.y); #elif CC_ENABLE_BOX2D_INTEGRATION b2Vec2 pos = _pB2Body->GetPosition(); float x = pos.x * _PTMRatio; float y = pos.y * _PTMRatio; s_physicPosion.set(x,y); #endif return s_physicPosion; }
void TitleScreenDoLogic(bool* Continue, bool* Error, Uint32 Milliseconds) { (void)Continue; (void)Error; cpSpaceStep(space.Space, Milliseconds * 0.001); for (int i = 0; i < MAX_PLAYERS; i++) { PlayerUpdate(&players[i], Milliseconds); // Check which players have fallen below their start pads cpVect pos = cpBodyGetPosition(players[i].Body); if (pos.y < BLOCK_Y) { if (!playersEnabled[i]) { // New player entered countdownMs = COUNTDOWN_START_MS; SoundPlay(SoundStart, 1.0); } playersEnabled[i] = true; } } if (countdownMs >= 0) { const int countdownMsNext = countdownMs - Milliseconds; // Play a beep every second if ((countdownMs / 1000) > (countdownMsNext / 1000)) { SoundPlay(SoundBeep, 1.0); } // Start game if counted down to zero if (countdownMsNext <= 0) { TitleScreenEnd(); ToGame(); return; } countdownMs = countdownMsNext; } Animation *a = Start ? &TitleAnim : &GameOverAnim; AnimationUpdate(a, Milliseconds); HighScoreDisplayUpdate(&HSD, Milliseconds); }
RTransformation RCPBody::transformation() const { RTransformation trans; if (mBody) { cpVect pos = cpBodyGetPosition(mBody); cpVect rot = cpBodyGetRotation(mBody); float matrix[16] = { rot.x, rot.y, 0.0f, 0.0f, -rot.y, rot.x, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, pos.x, pos.y, 0.0f, 1.0f}; trans = RMatrix(matrix); } return trans; }
ETERM *body_get_position(ETERM *fromp, ETERM *argp) { // get the args ETERM *space_refp = erl_element(1, argp); ETERM *idp = erl_element(2, argp); erlmunk_space *s = NULL; int space_id = ERL_REF_NUMBER(space_refp); HASH_FIND_INT(erlmunk_spaces, &space_id, s); int body_id = ERL_INT_VALUE(idp); erlmunk_body *b = NULL; HASH_FIND_INT(s->bodies, &body_id, b); if (b == NULL) return NULL; cpVect position = cpBodyGetPosition(b->body); float angle = cpBodyGetAngle(b->body); ETERM **position_tuple_array = (ETERM **) malloc(sizeof(ETERM*) * 2); position_tuple_array[0] = erl_mk_float(position.x); position_tuple_array[1] = erl_mk_float(position.y); ETERM *position_tuple = erl_mk_tuple(position_tuple_array, 2); free(position_tuple_array); ETERM *atom_ok = erl_mk_atom("ok"); ETERM **get_position_array = (ETERM **) malloc(sizeof(ETERM*) * 3); get_position_array[0] = atom_ok; get_position_array[1] = position_tuple; get_position_array[2] = erl_mk_float(angle); ETERM *get_position_tuple = erl_mk_tuple(get_position_array, 3); free(get_position_array); ETERM *reply_tuple = erl_mk_reply(fromp, get_position_tuple); ETERM *gen_cast_tuple = erl_mk_gen_cast(reply_tuple); // DEBUGF(("body_get_position(body: %d, x: %f, y: %f, angle: %f) has succeeded", // body_id, position.x, position.y, angle)); return gen_cast_tuple; }
static void update(cpSpace *space, double dt) { cpFloat coef = (2.0f + ChipmunkDemoKeyboard.y)/3.0f; cpFloat rate = ChipmunkDemoKeyboard.x*30.0f*coef; cpSimpleMotorSetRate(motor, rate); cpConstraintSetMaxForce(motor, rate ? 1000000.0f : 0.0f); cpSpaceStep(space, dt); for(int i=0; i<numBalls; i++){ cpBody *ball = balls[i]; cpVect pos = cpBodyGetPosition(ball); if(pos.x > 320.0f){ cpBodySetVelocity(ball, cpvzero); cpBodySetPosition(ball, cpv(-224.0f, 200.0f)); } } }
void GameDoLogic(bool* Continue, bool* Error, Uint32 Milliseconds) { (void)Continue; (void)Error; if (Pause) return; cpSpaceStep(space.Space, Milliseconds * 0.001); CameraUpdate(&camera, PlayerMiddleY(), Milliseconds); bool hasPlayers = false; for (int i = 0; i < MAX_PLAYERS; i++) { Player *p = &players[i]; if (!p->Enabled) continue; PlayerUpdate(p, Milliseconds); // Check if the player needs to be respawned if (p->RespawnCounter == 0 && !p->Alive && space.Gaps.size > 0) { SpaceRespawnPlayer(&space, p); } if (!p->Alive) { // Check if any players are past ones that await reenabling if (p->RespawnCounter == -1 && PlayerMinY() < p->y) { PlayerRevive(p); } else { continue; } } hasPlayers = true; // Check player pickups if (PickupsCollide(p->x, p->y, PLAYER_RADIUS)) { PlayerScore(p, false); } // Players that hit the top of the screen die if (cpBodyGetPosition(p->Body).y + PLAYER_RADIUS >= camera.Y + FIELD_HEIGHT / 2) { PlayerKill(p); } } // If no players left alive, end the game if (!hasPlayers) { ToTitleScreen(false); } SpaceUpdate(&space, PlayerMinY(), camera.Y, PlayerMaxY(), &players[0]); ParticlesUpdate(Milliseconds); // Players that hit the top of the screen die if (PlayerMaxY() + PLAYER_RADIUS >= camera.Y + FIELD_HEIGHT / 2) { ToTitleScreen(false); } }
static cpSpace * init(void) { ChipmunkDemoMessageString = "Control the crane by moving the mouse. Right click to release."; cpSpace *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); cpShapeSetFilter(shape, NOT_GRABBABLE_FILTER); // Add a body for the dolly. dollyBody = cpSpaceAddBody(space, cpBodyNew(10, INFINITY)); cpBodySetPosition(dollyBody, cpv(0, 100)); // Add a block so you can see it. cpSpaceAddShape(space, cpBoxShapeNew(dollyBody, 30, 30, 0.0)); // 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, cpBodyGetPosition(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)); cpBodySetPosition(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))); cpBodySetPosition(boxBody, cpv(200, -200)); // Add a block so you can see it. shape = cpSpaceAddShape(space, cpBoxShapeNew(boxBody, 50, 50, 0.0)); cpShapeSetFriction(shape, 0.7); cpShapeSetCollisionType(shape, CRATE); cpCollisionHandler *handler = cpSpaceAddCollisionHandler(space, HOOK_SENSOR, CRATE); handler->beginFunc = (cpCollisionBeginFunc)HookCrate; return space; }
static void AttachHook(cpSpace *space, cpBody *hook, cpBody *crate) { hookJoint = cpSpaceAddConstraint(space, cpPivotJointNew(hook, crate, cpBodyGetPosition(hook))); }
Vec2 PhysicsBody::getPosition() const { cpVect tt = cpBodyGetPosition(_cpBody); return Vec2(tt.x - _positionOffset.x, tt.y - _positionOffset.y); }