コード例 #1
0
bool BattleManagerScreen::GetVecBetween( ICastEntity* from, ICastEntity* to, kmVec2& distVec )
{
	CastWorldModel* world = CastWorldModel::get();

	if( !world->isValid(from) || !world->isValid(to) ) return false;

	kmVec2 pFrom;
	pFrom.x = pFrom.y = 0;
	GameEntityView* fromView = getViewForEntity(from);
	if( fromView != NULL ) 
	{
		pFrom.x = fromView->getPositionX();
		pFrom.y = fromView->getPositionY();
	}
	
	kmVec2 pTo;
	pTo.x = pTo.y = 0;
	GameEntityView* toView = getViewForEntity(to);
	if( toView != NULL ) 
	{
		pTo.x = toView->getPositionX();
		pTo.y = toView->getPositionY();
	}else {
		CCLog("uhoh..");
	}

	kmVec2Subtract( &distVec, &pFrom, &pTo );
	kmVec2Scale(&distVec, &distVec, GAME_UNIT_CONVERSION ); //safe to operate on same vector

	return true;
}
コード例 #2
0
ファイル: vec2.c プロジェクト: pperon/kazmath
/**
 * Reflects a vector about a given surface normal. The surface normal is
 * assumed to be of unit length.
 */
kmVec2* kmVec2Reflect(kmVec2* pOut, const kmVec2* pIn, const kmVec2* normal) {
	kmVec2 tmp;
	kmVec2Scale(&tmp, normal, 2.0f * kmVec2Dot(pIn, normal));
	kmVec2Subtract(pOut, pIn, &tmp);

	return pOut;
}
コード例 #3
0
ファイル: vec2.c プロジェクト: skandhas/plotter
/**
 * Returns the point mid-way between two others
 */
kmVec2* kmVec2MidPointBetween(kmVec2* pOut, const kmVec2* v1, const kmVec2* v2) {
	kmVec2 diff;
	kmVec2Subtract(&diff, v2, v1);
	kmVec2Normalize(&diff, &diff);
	kmVec2Scale(&diff, &diff, kmVec2DistanceBetween(v1, v2) * 0.5);
	kmVec2Add(pOut, v1, &diff);
	return pOut;
}
コード例 #4
0
bool BattleManagerScreen::GetEntityPosition( ICastEntity* entity, kmVec2& pos )
{
	GameEntityView* view = getViewForEntity( entity );

	if( view != NULL ) {
		pos.x = view->getPositionX();
		pos.y = view->getPositionY();
		kmVec2Scale(&pos, &pos, GAME_UNIT_CONVERSION);
		return true;
	}

	return false;
}
コード例 #5
0
void BattleManagerScreen::onEntityEffectEvent( CCObject* e )
{
	GameEntityEffectEvt* evt = dynamic_cast<GameEntityEffectEvt*>(e);
	if(!evt) return;

	if( evt->name.compare("Death Grip") == 0 ) {
		CCLog("death grip");

		kmVec2 pOrigin;
		kmVec2 pTarget;
		if( !GetEntityPosition(evt->origin, pOrigin) ||  !GetEntityPosition(evt->target, pTarget) )
		{
			CCLog("aborting death grip evt due to invalid target(s)");
		}
		
		kmVec2 toTarget;
		kmVec2Subtract(&toTarget, &pTarget, &pOrigin);

		kmVec2 u_toTarget;
		kmVec2Normalize(&u_toTarget, &toTarget);

		float leashDistance = 1;  //one game unit

		kmVec2 dv;
		kmVec2Scale(&dv, &u_toTarget, leashDistance );

		kmVec2 posEnd;
		kmVec2Add(&posEnd, &pOrigin, &dv);

		//convert back to screen coordinates
		kmVec2Scale(&posEnd, &posEnd, VIEW_UNIT_CONVERSION);

		GameEntityView* tView =	getViewForEntity(evt->target);
		tView->setPosition(posEnd.x, posEnd.y);
	}

}
コード例 #6
0
bool BattleManagerScreen::GetEntitiesInRadius( kmVec2 p, float r, std::vector<ICastEntity*>& entities )
{

	bool found = false;

	float upscale = VIEW_UNIT_CONVERSION;
	kmVec2Scale( &p, &p, upscale );
	r *= VIEW_UNIT_CONVERSION; //convert to pixels

	float rSq = r*r;
	for( int i=0; i< m_allEntities.size(); i++)
	{
		kmVec2 ePos;
		ePos.x = m_allEntities[i].view->getPositionX();
		ePos.y = m_allEntities[i].view->getPositionY();

		float distSq = 0;
		if( ePos.x == p.x ) //handle simple cases first
		{
			distSq = ePos.y - p.y;
			distSq *= distSq;
		}else if( ePos.y == p.y )
		{
			distSq = ePos.x - p.x;
			distSq *= distSq;
		}else {
			kmVec2 dist;
			kmVec2Subtract( &dist, &p, &ePos );
			distSq = kmVec2LengthSq(&dist);
		}

		CCLog("ent %d in radius dist %f", i, sqrt(distSq));

		if( distSq  <= rSq ) {
			entities.push_back( m_allEntities[i].model );
			found = true;
		}
	}

	return found;
}
コード例 #7
0
ファイル: types.cpp プロジェクト: gitter-badger/KGLT
kglt::Vec2 operator*(float lhs, const kglt::Vec2& rhs) {
    kglt::Vec2 result;
    kmVec2Scale(&result, &rhs, lhs);
    return result;
}
コード例 #8
0
void BattleManagerScreen::enemyMovementAI( int enemyIdx, float dt )
{
	float speed = 75.0f; //5 pixels/sec
	EntityPair& enemy = m_enemies[enemyIdx];
	
	std::vector<kmVec2> impulses; //x, y
	std::vector<float> impulseWeights;

	//TODO: select from closest player
	EntityPair& player =  m_players[0];
	
	CCSize eSize = enemy.view->getContentSize();
	CCPoint ePos = enemy.view->getPosition();
	ePos.x += eSize.width/2;
	ePos.y += eSize.height/2; //convert to center origin
	CCSize pSize = player.view->getContentSize();
	CCPoint pPos = player.view->getPosition();
	pPos.x += pSize.width/2;
	pPos.y += pSize.height/2; //convert to center origin
	
	float playerLeash = pSize.width * 1.1f;
	float playerLeashSq = playerLeash*playerLeash;

	//impulse towards the player
	kmVec2 toPlayer = { pPos.x - ePos.x, pPos.y - ePos.y };
	kmVec2 u_toPlayer;
	kmVec2Normalize( &u_toPlayer, &toPlayer);
	
	
	if( kmVec2LengthSq( &toPlayer ) < (playerLeashSq * 0.75f) )
	{
		//impulse away from player (too close)
		kmVec2 u_fromPlayer;
		kmVec2Scale(&u_fromPlayer, &u_toPlayer, -1*0.75f); //flip the 'to player' vector
		
		impulses.push_back(u_fromPlayer);
		impulseWeights.push_back(100); //vastly overweigh the impulse to the player
	}else {

		if( kmVec2LengthSq(&toPlayer) > playerLeashSq )
		{
			//kmVec2Scale(&u_toPlayer, &u_toPlayer, 0.51f);
			//impulse towards player
			impulses.push_back(u_toPlayer);
			impulseWeights.push_back(100);

		}
	}
	
	//add impulses away from other enemies
	for( int i=0; i< m_enemies.size(); i++) {
		if( i == enemyIdx ) continue;
		
		CCSize nSize = m_enemies[i].view->getContentSize();
		CCPoint nPos = m_enemies[i].view->getPosition();
		nPos.x += nSize.width/2;
		nPos.y += nSize.height/2;
		
		kmVec2 toNeighbor = { nPos.x - ePos.x, nPos.y - ePos.y };

		float neighborLeash = nSize.width;
		if( kmVec2LengthSq(&toNeighbor) < neighborLeash * neighborLeash ) {
			kmVec2 u_toNeighbor;
			kmVec2Normalize(&u_toNeighbor, &toNeighbor);
			kmVec2 u_fromNeighbor;
			kmVec2Scale(&u_fromNeighbor, &u_toNeighbor, -1);
			impulses.push_back(u_fromNeighbor);
			impulseWeights.push_back(50);
		}
	}
	
	if( impulses.size() == 0 ) return;

	//blend impulses
	kmVec2 finalImpulse = impulses[0]; //zero always valid because its the impulse to the player
	float finalImpulseWeight = impulseWeights[0];
	for( int i=1; i< impulses.size(); i++) {

		float w1 = finalImpulseWeight;
		float w2 = impulseWeights[i];
		float wTot =  w1 + w2;
		
		kmVec2 blend;
		blend.x = (finalImpulse.x * w1 / wTot) + (impulses[i].x * w2 / wTot);
		blend.y = (finalImpulse.y * w1 / wTot) + (impulses[i].y * w2 / wTot);
		
		//run-length summation
		finalImpulseWeight = wTot;
		finalImpulse = blend;
	}
	
	kmVec2 scaledImpulse;
	kmVec2Scale(&scaledImpulse, &finalImpulse, speed * dt);
	
	//CCLog("impulse %.4f", kmVec2Length(& finalImpulse));
	if( kmVec2Length(& finalImpulse) <  (0.5f) )
	{
		//CCLog("ignore impulse %.4f", kmVec2Length(& finalImpulse));
		return; //ignore very small changes to avoid leash jitter
	}
	
	ePos.x += scaledImpulse.x;
	ePos.y += scaledImpulse.y;
	ePos.x -= eSize.width/2;
	ePos.y -= eSize.height/2; //back to original anchor coords
	enemy.view->setPosition(ePos);
}