float AbstractPlaneBehavoiur::angleToPlayer() { return vectorToPlayer().getAngle(); }
Vec2 AbstractPlaneBehavoiur::directionToPlayer() { return vectorToPlayer().getNormalized(); }
float AbstractPlaneBehavoiur::distanceToPlayer() { return vectorToPlayer().getLength(); }
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); } }