Пример #1
0
    //!!!WARNING: Code in this method should not depend on how many times this method is run
    void Player::updateState() {
        //states
        if (mHpLossTimer.exceededReset()) {
            hurt(mInCloud);
        }

        //Apply impulse
        cpVect totalVel = cpvadd(mVel,mVectp);
        if (cpvlength(totalVel) != 0) {
            cpBodyApplyImpulseAtWorldPoint(mEntity->body(), totalVel, cpv(0, 0));
            mVel = cpvzero;
            mVectp = cpvzero;
        }

        mVectp = cpvzero;
        cpBody * body = mEntity->body();
        for(int i=0; i<mMaxAmmo; i++)
            if( mAmmo[i].checkExist() )
                mAmmo[i].move();

        //Move around screen
        if( body->p.x > SCREEN_WIDTH + mEntity->width()/2 )
            body->p.x = -mEntity->width();
        if( body->p.x < -mEntity->width() )
            body->p.x = SCREEN_WIDTH + mEntity->width()/2;
        if( body->p.y > SCREEN_HEIGHT + mEntity->height()/2)
            body->p.y = -mEntity->height();
        if( body->p.y < -mEntity->height() )
            body->p.y = SCREEN_HEIGHT + mEntity->height()/2;
    }
Пример #2
0
ETERM *body_apply_impulse(ETERM *fromp, ETERM *argp) {

    // get the args
    ETERM *space_refp = erl_element(1, argp);
    ETERM *idp = erl_element(2, argp);
    ETERM *impulsep = 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;

    // apply the impulse at the center of the body and along it's current angle
    float angle = deg_to_rad(cpBodyGetAngle(b->body));
    cpVect angleV = cpvforangle(angle);
    cpVect impulse = cpvmult(angleV, ERL_FLOAT_VALUE(impulsep));
    cpBodyApplyImpulseAtWorldPoint(b->body, impulse, angleV);

    return NULL;
}
Пример #3
0
void RCPBody::applyImpulse(RVector const & impulse)
{
    if (mBody) {
        cpBodyApplyImpulseAtWorldPoint(mBody, cpv(impulse.x(), impulse.y()), cpBodyLocalToWorld(mBody, cpBodyGetCenterOfGravity(mBody)));
    }

}
Пример #4
0
	void RigidBody2D::AddImpulse(const Vector2f& impulse, const Vector2f& point, CoordSys coordSys)
	{
		switch (coordSys)
		{
			case CoordSys_Global:
				cpBodyApplyImpulseAtWorldPoint(m_handle, cpv(impulse.x, impulse.y), cpv(point.x, point.y));
				break;

			case CoordSys_Local:
				cpBodyApplyImpulseAtLocalPoint(m_handle, cpv(impulse.x, impulse.y), cpv(point.x, point.y));
				break;
		}
	}
Пример #5
0
cpBool Buoyancy::WaterPreSolve(cpArbiter *arb, cpSpace *space, void *ptr)
{
    CP_ARBITER_GET_SHAPES(arb, water, poly);
    cpBody *body = cpShapeGetBody(poly);

    // Get the top of the water sensor bounding box to use as the water level.
    cpFloat level = cpShapeGetBB(water).t;

    // Clip the polygon against the water level
    int count = cpPolyShapeGetCount(poly);
    int clippedCount = 0;
#ifdef _MSC_VER
    // MSVC is pretty much the only compiler in existence that doesn't support variable sized arrays.
    cpVect clipped[10];
#else
    cpVect clipped[count + 1];
#endif

    for(int i=0, j=count-1; i<count; j=i, i++){
        cpVect a = cpBodyLocalToWorld(body, cpPolyShapeGetVert(poly, j));
        cpVect b = cpBodyLocalToWorld(body, cpPolyShapeGetVert(poly, i));

        if(a.y < level){
            clipped[clippedCount] = a;
            clippedCount++;
        }

        cpFloat a_level = a.y - level;
        cpFloat b_level = b.y - level;

        if(a_level*b_level < 0.0f){
            cpFloat t = cpfabs(a_level)/(cpfabs(a_level) + cpfabs(b_level));

            clipped[clippedCount] = cpvlerp(a, b, t);
            clippedCount++;
        }
    }

    // Calculate buoyancy from the clipped polygon area
    cpFloat clippedArea = cpAreaForPoly(clippedCount, clipped, 0.0f);
    cpFloat displacedMass = clippedArea*FLUID_DENSITY;
    cpVect centroid = cpCentroidForPoly(clippedCount, clipped);

    cpDataPointer data = ptr;
    DrawPolygon(clippedCount, clipped, 0.0f, RGBAColor(0, 0, 1, 1), RGBAColor(0, 0, 1, 0.1f), data);
    DrawDot(5, centroid, RGBAColor(0, 0, 1, 1), data);

    cpFloat dt = cpSpaceGetCurrentTimeStep(space);
    cpVect g = cpSpaceGetGravity(space);

    // Apply the buoyancy force as an impulse.
    cpBodyApplyImpulseAtWorldPoint(body, cpvmult(g, -displacedMass*dt), centroid);

    // Apply linear damping for the fluid drag.
    cpVect v_centroid = cpBodyGetVelocityAtWorldPoint(body, centroid);
    cpFloat k = k_scalar_body(body, centroid, cpvnormalize(v_centroid));
    cpFloat damping = clippedArea*FLUID_DRAG*FLUID_DENSITY;
    cpFloat v_coef = cpfexp(-damping*dt*k); // linear drag
    //	cpFloat v_coef = 1.0/(1.0 + damping*dt*cpvlength(v_centroid)*k); // quadratic drag
    cpBodyApplyImpulseAtWorldPoint(body, cpvmult(cpvsub(cpvmult(v_centroid, v_coef), v_centroid), 1.0/k), centroid);

    // Apply angular damping for the fluid drag.
    cpVect cog = cpBodyLocalToWorld(body, cpBodyGetCenterOfGravity(body));
    cpFloat w_damping = cpMomentForPoly(FLUID_DRAG*FLUID_DENSITY*clippedArea, clippedCount, clipped, cpvneg(cog), 0.0f);
    cpBodySetAngularVelocity(body, cpBodyGetAngularVelocity(body)*cpfexp(-w_damping*dt/cpBodyGetMoment(body)));

    return cpTrue;
}