Пример #1
0
void LineSegSlingshot::Collide(CollisionEvent* coll)
{
    Ball *pball = coll->ball;
    const Vertex3Ds& hitnormal = coll->hitnormal;

	const float dot = pball->m_vel.x * hitnormal.x  + pball->m_vel.y * hitnormal.y; // normal velocity to slingshot

	const bool threshold = (dot <= -m_psurface->m_d.m_slingshot_threshold);  // normal greater than threshold?

	if (!m_psurface->m_fDisabled && threshold) // enabled and if velocity greater than threshold level		
	{
		const float len = (v2.x - v1.x)*hitnormal.y - (v2.y - v1.y)*hitnormal.x; // length of segment, Unit TAN points from V1 to V2

		const Vertex2D vhitpoint(pball->m_pos.x - hitnormal.x * pball->m_radius, //project ball radius along norm
								 pball->m_pos.y - hitnormal.y * pball->m_radius);

		// vhitpoint will now be the point where the ball hits the line
		// Calculate this distance from the center of the slingshot to get force

		const float btd = (vhitpoint.x - v1.x)*hitnormal.y - (vhitpoint.y - v1.y)*hitnormal.x; // distance to vhit from V1
		float force = (len != 0.0f) ? ((btd+btd)/len - 1.0f) : -1.0f;	// -1..+1
		force = 0.5f *(1.0f-force*force);	//!! maximum value 0.5 ...I think this should have been 1.0...oh well
											// will match the previous physics
		force *= m_force;//-80;

		pball->m_vel.x -= hitnormal.x * force;	// boost velocity, drive into slingshot (counter normal)
		pball->m_vel.y -= hitnormal.y * force;	// allow CollideWall to handle the remainder
	}

	pball->Collide2DWall(hitnormal, m_elasticity, m_elasticityFalloff, m_friction, m_scatter);

    if (m_pfe && !m_psurface->m_fDisabled && threshold)
    {
        // is this the same place as last event? if same then ignore it
        const Vertex3Ds dist = pball->m_Event_Pos - pball->m_pos;
        pball->m_Event_Pos = pball->m_pos; //remember last collide position

        if (dist.LengthSquared() > 0.25f) // must be a new place if only by a little
        {
            m_pfe->FireGroupEvent(DISPID_SurfaceEvents_Slingshot);
            m_slingshotanim.m_TimeReset = g_pplayer->m_time_msec + 100;
        }
    }
}
Пример #2
0
void BumperHitCircle::Collide(CollisionEvent* coll)
{
    Ball *pball = coll->ball;
    const Vertex3Ds& hitnormal = coll->hitnormal;

	const float dot = hitnormal.x * pball->m_vel.x + hitnormal.y * pball->m_vel.y;

	pball->Collide2DWall(hitnormal, m_elasticity, m_elasticityFalloff, m_friction, m_scatter);	//reflect ball from wall

	// if the bumper is disabled then don't activate the bumper
	if (m_pbumper->m_fDisabled)
		return;

	if (dot <= -m_pbumper->m_d.m_threshold) // if velocity greater than threshold level
	{
		pball->m_vel.x += hitnormal.x * m_pbumper->m_d.m_force; // add a chunk of velocity to drive ball away
		pball->m_vel.y += hitnormal.y * m_pbumper->m_d.m_force;

		m_bumperanim.m_fHitEvent = true;

		m_pbumper->FireGroupEvent(DISPID_HitEvents_Hit);
	}
}