Esempio n. 1
0
void ChoosePath(Unit &ghost)
{
	int choices = CanMoveTo(ghost, Right)
	              + CanMoveTo(ghost, Left)
	              + CanMoveTo(ghost, Up)
	              + CanMoveTo(ghost, Down);

	if(ghost.Rotating == false && choices >= 3)
	{
		Direction backwards = Invert(ghost.Face);
		do
		{
			ghost.Face = (Direction) (rand() % 4);
		} while(CanMove(ghost) == false || ghost.Face == backwards);

		ghost.Rotating = true;
	}
}
shared_ptr<ZombieInstanceBase> ZombieInstance::Spawn(PlayerInstance& targetPlayer, const vector<shared_ptr<ZombieInstanceBase>>& zombies)
{
	ModelParameters zombieParameters;

	do
	{
		zombieParameters = GetRandomZombieParameters(targetPlayer);
	}
	while (!CanMoveTo(DirectX::XMFLOAT2(zombieParameters.position.x, zombieParameters.position.z), zombies, nullptr));

	return shared_ptr<ZombieInstanceBase>(new ZombieInstance(zombieParameters, targetPlayer, zombies));
}
Esempio n. 3
0
std::vector<AStarDungeon::Node> AStarDungeon::GetSuccessors(const AStarDungeon::Node &node) const
{
	Node up = node;
	++up.y;
	Node right = node;
	++right.x;
	Node down = node;
	--down.y;
	Node left = node;
	--left.x;

	std::vector<Node> successors = { up, right, down, left };

	// get rid of untraversable tiles
	auto canMoveToLambda = [this](Node &n) { return !CanMoveTo(n); };
	successors.erase(std::remove_if(successors.begin(), successors.end(), canMoveToLambda), successors.end());

	return successors;
}
void ZombieInstance::Update(const RenderParameters& renderParameters)
{
	ZombieStates targetState;
	
	auto emitterPosition = m_Parameters.position;
	emitterPosition.y += 1.6f;
	m_AudioEmitter.SetPosition(m_Parameters.position, DirectX::XMFLOAT3(0.0f, 0.0f, 0.0f));

	float distanceToPlayerSqr;

	if (!m_IsDead)
	{
		auto playerPosition = m_TargetPlayer.GetPosition();
		auto angleY = -atan2(m_Parameters.position.z - playerPosition.z, m_Parameters.position.x - playerPosition.x) - DirectX::XM_PI / 2.0f;

		if (m_TargetPlayer.GetGameState() == GameState::Playing)
		{
			DirectX::XMFLOAT2 vectorToPlayer(playerPosition.x - m_Parameters.position.x, playerPosition.z - m_Parameters.position.z);
			distanceToPlayerSqr = vectorToPlayer.x * vectorToPlayer.x + vectorToPlayer.y * vectorToPlayer.y;	

			if (distanceToPlayerSqr > 1.5f)
			{
				if (distanceToPlayerSqr > 100.0f * 100.0f)
				{
					m_IsDead = true;
					System::GetInstance().RemoveModel(this);
					return;
				}
				else
				{
					auto vectorMultiplier = m_Speed * renderParameters.frameTime / sqrt(distanceToPlayerSqr);

					DirectX::XMFLOAT2 newPosition(m_Parameters.position.x + vectorMultiplier * vectorToPlayer.x, 
						m_Parameters.position.z + vectorMultiplier * vectorToPlayer.y);

					if (CanMoveTo(newPosition, m_Zombies, this))
					{
						targetState = ZombieStates::Running;

						m_Parameters.position.x = newPosition.x;
						m_Parameters.position.z = newPosition.y;
					}
					else
					{
						targetState = ZombieStates::Idle;
					}
				}
			}
			else
			{
				targetState = ZombieStates::Hitting;

				if (renderParameters.time - m_LastMadeNearPlayerSound >= kNearPlayerSoundInterval)
				{
					m_LastMadeNearPlayerSound = renderParameters.time;
					m_NearPlayerSound.Play3D(m_AudioEmitter);
				}
			}
		}
		else
		{
			targetState = ZombieStates::Idle;
		}

		SetRotation(DirectX::XMFLOAT3(0.0f, angleY, 0.0f));
	}
	else
	{
		targetState = ZombieStates::Death;

		if (renderParameters.time - m_DeathTime > kZombieBodyLastingTime)
		{
			System::GetInstance().RemoveModel(this);
		}
	}

	Assert(targetState >= 0 && targetState < ZombieStates::StateCount);
	m_AnimationStateMachine.Update(renderParameters, targetState);

	if (m_AnimationStateMachine.GetCurrentAnimationState() == ZombieStates::Hitting && 
		!m_AnimationStateMachine.IsTransitioningAnimationStates() &&
		m_AnimationStateMachine.GetCurrentStateAnimationProgress() > 0.1f && 
		m_AnimationStateMachine.GetCurrentStateAnimationProgress() < 0.2f &&
		renderParameters.time - m_LastHitPlayerAt >= kZombieHitInterval)
	{
		m_LastHitPlayerAt = renderParameters.time;
		m_TargetPlayer.TakeDamage(Tools::Random::GetNextReal<float>(0.03f, 0.1f));
		m_PunchSound.Play3D(m_AudioEmitter);
	}
	else if (renderParameters.time - m_LastFootStep >= kFootStepInterval &&
			 m_AnimationStateMachine.GetCurrentAnimationState() == ZombieStates::Running && 
			 !m_AnimationStateMachine.IsTransitioningAnimationStates() && 
			 distanceToPlayerSqr < 100.0f)
	{
		m_LastFootStep = renderParameters.time;
		m_FootStepSound.Play3D(m_AudioEmitter, 8.0f);
	}
}
Esempio n. 5
0
//*****************************************************************************
void CSerpent::GetNormalMovement(
// Figures out the normal movement of the serpent when not affected by a brain.
//
//Params:
	int &dx,		//(out) Horizontal delta (-1, 0, or 1) for where monster
					//		can go, taking into account obstacles.
	int &dy)		//(out) Vertical delta (-1, 0, or 1) for same.
const
{
	// If swordsman is ahead or behind the serpent, keep moving toward him.
	// Otherwise, switch between favoring horizonal or vertical movement
	// every five turns.  
	const bool horizontal = ((this->pCurrentGame->wSpawnCycleCount % 10) < 5);

	const int oX = nGetOX(wO);
	const int oY = nGetOY(wO);

	if (CanFindSwordsman()) 
	{
		//Is swordsman in front of or behind serpent?
		if (!oX)
		{
			//serpent is moving vertically
			if (this->pCurrentGame->swordsman.wX == this->wX)
			{
				//Yes.  Keep moving this direction.
				dy = oY;
				dx = 0;
				if (CanMoveTo(this->wX + dx, this->wY + dy))
					return;
			}
		} else {
			//serpent moving horizontally
			if (this->pCurrentGame->swordsman.wY == this->wY)
			{
				dx = oX;
				dy = 0;
				if (CanMoveTo(this->wX + dx, this->wY + dy))
					return;
			}
		}

		// Move towards swordsman.
		if (horizontal)
		{
			dx = sgn(this->pCurrentGame->swordsman.wX - this->wX);
			if (dx == 0)
				dy = sgn(this->pCurrentGame->swordsman.wY - this->wY);
			else
				dy = 0;
		}
		else
		{
			dy = sgn(this->pCurrentGame->swordsman.wY - this->wY);
			if (dy == 0)
				dx = sgn(this->pCurrentGame->swordsman.wX - this->wX);
			else
				dx = 0;
		}

		// Check the coordinates
		if (CanMoveTo(this->wX + dx, this->wY + dy))
			return;	//move here
	}

	// We can't move towards the swordsman in the desired manner.
	// Try the four cardinal directions
	static const int directions[] = {N, E, S, W};
	bool found = false;
	for (int i = 0; !found && i < 4; i++) 
	{
		dx = nGetOX(directions[i]);
		dy = nGetOY(directions[i]);
		// Don't backtrack
		if (dx == -oX && dy == -oY)
			continue;
		if (CanMoveTo(this->wX + dx, this->wY + dy))
			found = true;
	}
	if (!found)
		dx = dy = 0;	//stuck
}