Пример #1
0
CFVec2 CSteeringAgent::GetRepulsionBearingEffect() const
{
	CFVec2 vCumulativeRepulsionEffect = fv2EMPTY;

	const vector<CCircle>& krRepulsionZones = CBlackboard::GetInstance().GetRepulsionZones();
	for (unsigned int uiIndex = 0; uiIndex < krRepulsionZones.size(); uiIndex++)
	{
		CFVec2 vRepulsionEffect = m_krCat.GetPosition() - krRepulsionZones.at(uiIndex).Centre();
		FLOAT32 fDistanceBetweenCenters = vRepulsionEffect.Magnitude();

		FLOAT32 fDistanceBetweenBorders = fDistanceBetweenCenters - m_krCat.GetRadius() -
			krRepulsionZones.at(uiIndex).Radius();

		if (m_krCat.GetHeadingVector().DotProduct(vRepulsionEffect) < 0.0f &&
			fDistanceBetweenBorders < m_fRepulsionBufferStatic)
		{
			FLOAT32 fDistanceIntoRepulsionBuffer = (m_fRepulsionBufferStatic - fDistanceBetweenBorders) /
				m_fRepulsionBufferStatic;
			vRepulsionEffect.Normalise();
			vRepulsionEffect *= fDistanceIntoRepulsionBuffer;
			vCumulativeRepulsionEffect += vRepulsionEffect;
		}
	}

	const vector<const CCat*>& krCats = CBlackboard::GetInstance().GetCats();
	for (unsigned int uiIndex = 0; uiIndex < krCats.size(); uiIndex++)
	{
		CFVec2 vRepulsionEffect = m_krCat.GetPosition() - krCats.at(uiIndex)->GetPosition();
		FLOAT32 fDistanceBetweenCenters = vRepulsionEffect.Magnitude();

		// We don't want the cat to repel itself...
		if (fDistanceBetweenCenters == 0.0f)
		{
			continue;
		}

		FLOAT32 fDistanceBetweenBorders = fDistanceBetweenCenters - m_krCat.GetRadius() * 2.0f;

		if (m_krCat.GetHeadingVector().DotProduct(vRepulsionEffect) < 0.0f &&
			fDistanceBetweenBorders < m_fRepulsionBufferDynamic)
		{
			FLOAT32 fDistanceIntoRepulsionBuffer = (m_fRepulsionBufferDynamic - fDistanceBetweenBorders) /
				m_fRepulsionBufferDynamic;
			vRepulsionEffect.Normalise();
			vRepulsionEffect *= fDistanceIntoRepulsionBuffer;
			vCumulativeRepulsionEffect += vRepulsionEffect;
		}
	}

	if (vCumulativeRepulsionEffect.Magnitude() > 1.0f)
	{
		vCumulativeRepulsionEffect.Normalise();
	}

	return vCumulativeRepulsionEffect;
}
Пример #2
0
void
CMole::ComputeSeekForce(CFVec2& _vrSeekForce, int _iTargetNodeId)
{
	const Path::TNode& ktrTargetNode = s_pSharedPath->GetNode(_iTargetNodeId);


	CFVec2 vSeekForce;
	vSeekForce  = ktrTargetNode.vPosition;
	vSeekForce -= m_vPosition;
	vSeekForce.Normalise();


	_vrSeekForce = vSeekForce;
}
Пример #3
0
CFVec2 CSteeringAgent::GetAbsoluteWhiskerStart(const CFVec2& _krvRelativeWhisker) const
{
	CFVec2 vAbsoluteWhiskerStart = GetAdjustedWhisker(_krvRelativeWhisker);

	if (vAbsoluteWhiskerStart.Magnitude() != 0.0f)
	{
		vAbsoluteWhiskerStart.Normalise();
		vAbsoluteWhiskerStart *= m_krCat.GetRadius();
	}

	vAbsoluteWhiskerStart += m_krCat.GetPosition();

	return vAbsoluteWhiskerStart;
}
Пример #4
0
CFVec2 CSteeringAgent::GetWhiskerBearingEffect() const
{
	CBlackboard& rBlackboard = CBlackboard::GetInstance();
	bool bRotationApplied = false;
	FLOAT32 fTotalRotation = 0.0f;

	FLOAT32 fRotation = Math::PI / 2.0f; // 90 degrees
	for (unsigned int uiIndex = 0 ; uiIndex < SIDE_WHISKER_COUNT; uiIndex++)
	{
		FLOAT32 fWhiskerTime =
			rBlackboard.GetClosestWallIntersectionTime(GetAbsoluteWhiskerStart(m_vWhiskersLeft[uiIndex]),
			GetAdjustedWhisker(m_vWhiskersLeft[uiIndex]));
		if (fWhiskerTime != -1.0f)
		{
			fTotalRotation += fRotation;
			bRotationApplied = true;
		}

		fWhiskerTime =
			rBlackboard.GetClosestWallIntersectionTime(GetAbsoluteWhiskerStart(m_vWhiskersRight[uiIndex]),
			GetAdjustedWhisker(m_vWhiskersRight[uiIndex]));
		if (fWhiskerTime != -1.0f)
		{
			fTotalRotation -= fRotation;
			bRotationApplied = true;
		}

		fRotation /= 5.0f; // TODO MAGIC
	}

	if (bRotationApplied)
	{
		// If the rotation was cancelled out (accounting for rounding errors).
		if (abs(fTotalRotation) < 0.0001f)
		{
			// The whiskers are intersecting on both sides so chances are we're heading straight for something and we
			// need to turn. Clockwise 90 degrees sounds good...
			fTotalRotation += Math::PI / 2.0f;
		}

		CFVec2 vWhiskerBearingEffect = m_krCat.GetHeadingVector();
		vWhiskerBearingEffect.Normalise();
		vWhiskerBearingEffect.RotateZ(fTotalRotation);

		return vWhiskerBearingEffect;
	}

	return fv2EMPTY;
}
void CPathFindingAgent::AdvanceDestinationOnPath(float _fDistance)
{
	if (m_iPreviousWaypointIndex == -1)
	{
		m_iPreviousWaypointIndex = 0;
		m_iNextWaypointIndex = 1;
	}

	CFVec2 vAdvancement =
		m_path.at(m_iNextWaypointIndex)->GetPosition() -
		m_path.at(m_iPreviousWaypointIndex)->GetPosition();
	vAdvancement.Normalise();
	vAdvancement *= _fDistance;
	CFVec2 vDestinationCopy = m_vDestination;
	vDestinationCopy += vAdvancement; 

	float fDistancePastNextWaypoint =
		(vDestinationCopy - m_path.at(m_iPreviousWaypointIndex)->GetPosition()).Magnitude() -
		(m_path.at(m_iNextWaypointIndex)->GetPosition() - m_path.at(m_iPreviousWaypointIndex)->GetPosition()).Magnitude();

	if (fDistancePastNextWaypoint > 0.0f)
	{
		m_vDestination = m_path.at(m_iNextWaypointIndex)->GetPosition();

		if (m_path.size() > (unsigned) m_iNextWaypointIndex + 1)
		{
			m_iPreviousWaypointIndex++;
			m_iNextWaypointIndex++;

			AdvanceDestinationOnPath(fDistancePastNextWaypoint);
		}
	}
	else
	{
		m_vDestination += vAdvancement;
	}
}
Пример #6
0
void	CSquirrel::Update( FLOAT32 fTimeDelta )
{
	if ( 0 == m_uNumLives )
	{
		return;
	}

	const static CFVec2 s_vMoveOffsets[] = 
	{
		SFVec2( -1.0f,  0.0f ), //"Left",
		SFVec2(  1.0f,  0.0f ), //"Right",
		SFVec2(  0.0f, -1.0f ), //"Up",
		SFVec2(  0.0f,  1.0f ), //"Down"
	};

	_COMPILE_ASSERT( _ARRAY_SIZE( s_vMoveOffsets ) == EMove_COUNT );

	CFVec2 vMove = SFVec2( 0.0f, 0.0f );
	for ( UINT32 i=0; i< EMove_COUNT; i++ )
	{
		if ( m_Movements[i].m_bValue )
		{
			vMove += s_vMoveOffsets[i];
		}
	}

	// great, now we have the movement direction.
	if ( vMove.SquareMagnitude() != 0.0f )
	{
		m_fDistTimeMoving += fTimeDelta;
		vMove.Normalise();
		FLOAT32 fStep = 1.0f;
		CFVec2 vTestedMove = vMove * fTimeDelta * m_fSpeed * fStep;
		// now check the target position -  is it embedded in any walls?
		CCircle TargetBounds;
		while ( fStep > 0.0f )
		{
			TargetBounds.Initialise( m_vPosition + vTestedMove, m_fRadius );
			if ( false == CMMMContext::GetInstance().CircleIntersectsGeometry( TargetBounds ) )
			{
				break;	// found a valid, allowable movement.
			}
			fStep -= 0.2f;
			vTestedMove = vMove * fTimeDelta * m_fSpeed * fStep;
		}
		// now update to the new position
		m_vPosition += vTestedMove;

		// finally what happens at the new position
		// is an acorn collected?
		if ( m_uNumAcorns != m_uMaxAcorns )
		{
			CAcorn* pLevelAcorns;
			UINT32 uNumLevelAcorns;
			CMMMContext::GetInstance().GetAcorns( pLevelAcorns, uNumLevelAcorns );
			for ( UINT32 i=0; i<uNumLevelAcorns; i++ )
			{
				if ( pLevelAcorns[i].GetState() == CAcorn::ES_Available )
				{
					if ( pLevelAcorns[i].Intersects( TargetBounds ) )
					{
						pLevelAcorns[i].SetState( CAcorn::ES_Carried );
						m_ppAcorns[m_uNumAcorns++] = pLevelAcorns+i;
						if ( m_uNumAcorns == m_uMaxAcorns )
						{
							break;	// cannont collect any more!
						}
					}
				}
			}
		}
		// is a tunnel reached?
		if ( m_uNumAcorns > 0 )
		{
			CTunnel*	pTunnels;
			UINT32		uNumTunnels;
			CMMMContext::GetInstance().GetTunnels( pTunnels, uNumTunnels );
			for ( UINT32 i=0; i<uNumTunnels; i++ )
			{
				if ( pTunnels[i].Intersects( TargetBounds ) )
				{
					// reached the tunnel.
					for ( UINT32 i=0; i<m_uNumAcorns; i++ )
					{
						m_ppAcorns[i]->SetState( CAcorn::ES_Collected );
						m_uScore++;
					}
					m_uNumAcorns = 0;
				}
			}
		}
	}

	m_fTimeToDisturbance -= fTimeDelta;
	if ( m_fTimeToDisturbance <= 0.0f )
	{
		// schedule the next disturbance.
		m_fTimeToDisturbance = FLOAT32(rand())/FLOAT32(RAND_MAX);
		m_fTimeToDisturbance *= m_fMaxDistSep-m_fMinDistSep;
		m_fTimeToDisturbance += m_fMinDistSep;

		// create this disturbance:
		FLOAT32 fRad = m_fLastDistDelay=0.0f?0.0f:m_fDistTimeMoving/m_fLastDistDelay;
//		DbgPrint( "Creating Disturbance strength %0.2f, next delay %0.2f\n", fRad,m_fTimeToDisturbance );
		fRad *= m_fMaxDistRad-m_fMinDistRad;
		fRad += m_fMinDistRad;

		if ( fRad >= 0.0f )
		{
			CCircle Dist;
			Dist.Initialise( m_vPosition, fRad );
			CMMMContext::GetInstance().CreateDisturbance( Dist );
		}
		m_fDistTimeMoving = 0.0f;
		m_fLastDistDelay = m_fTimeToDisturbance;
	}



}