BubbleBobbleRemake / BubbleBobble / PlayerComponent.cpp
PlayerComponent.cpp
Raw
#include "PlayerComponent.h"
#include "GameObject.h"
#include "AnimatedTextureComponent.h"
#include "LevelComponent.h"
#include "ColliderComponent.h"
#include "RigidbodyComponent.h"
#include "ServiceLocator.h"
#include "GameEvents.h"
#include "PlayerStates.h"

#include "BubbleComponent.h"

dae::PlayerComponent::PlayerComponent(float startX, float startY, int spriteId, int lives)
	: m_StartX{ startX }
	, m_StartY{ startY }
	, m_SpriteId{ spriteId }
	, m_Lives{ lives }
	, m_MaxLives{ lives }
{
	m_pStates[FROZEN] = std::make_shared<PlayerFrozenState>();
	m_pStates[IN_BUBBLE] = std::make_shared<PlayerInBubbleState>();
	m_pStates[IDLE] = std::make_shared<PlayerIdleState>();
	m_pStates[RUNNING] = std::make_shared<PlayerRunningState>();
	m_pStates[JUMPING] = std::make_shared<PlayerJumpingState>();
	m_pStates[FALLING] = std::make_shared<PlayerFallingState>();
	m_pStates[SHOOT_BUBBLE] = std::make_shared<PlayerShootingBubbleState>();
	m_pStates[DEAD] = std::make_shared<PlayerDeadState>();
}

dae::PlayerComponent::~PlayerComponent()
{

}

void dae::PlayerComponent::RegisterLevel(LevelComponent* pLevelComponent)
{
	m_pLevelComponent = pLevelComponent;
	
	pLevelComponent->AddPlayerCollider(GetGameObject()->GetComponent<ColliderComponent>());
}

void dae::PlayerComponent::RegisterEnemyColliders(const std::vector<ColliderComponent*>& enemyColliders)
{
	m_EnemyColliders = enemyColliders;
}

void dae::PlayerComponent::Initialize()
{
	m_pSoundSystem = &ServiceLocator::GetSoundSystem();

	GameObject* pGameObject = GetGameObject();
	pGameObject->SetPosition(m_StartX, m_StartY);

	m_pAnimTexComp = pGameObject->AddComponent(new AnimatedTextureComponent("player" + std::to_string(m_SpriteId) + ".png", 64, 64, 8, 5));
	pGameObject->AddComponent(new ColliderComponent(32, 32, false, m_SpriteOffset, 32));
	m_pRigidBodyComponent = pGameObject->AddComponent(new RigidbodyComponent());

	if (m_SpriteId == 2)
	{
		m_Direction = FacingDirection::LEFT;
		m_pAnimTexComp->SetFlipped(bool(m_Direction));
	}

	ChangeState(FROZEN);
}

void dae::PlayerComponent::Reset()
{
	GetGameObject()->SetPosition(m_StartX, m_StartY);

	if (m_SpriteId == 2)
	{
		m_Direction = FacingDirection::LEFT;
		m_pAnimTexComp->SetFlipped(bool(m_Direction));
	}
	else
	{
		m_Direction = FacingDirection::RIGHT;
		m_pAnimTexComp->SetFlipped(bool(m_Direction));
	}

	ChangeState(IDLE);
	ChangeState(FROZEN);
}

void dae::PlayerComponent::ChangeDirection(float dirX, float)
{
	if (dirX > 0)
	{
		m_Direction = FacingDirection::RIGHT;
	}
	else if (dirX < 0)
	{
		m_Direction = FacingDirection::LEFT;
	}
	m_pAnimTexComp->SetFlipped(bool(m_Direction));
}

void dae::PlayerComponent::SpawnBubble()
{
	auto pBubble = new GameObject();
	pBubble->SetParent(GetGameObject()->GetRootGameObject());
	pBubble->AddComponent(new BubbleComponent(m_pLevelComponent, m_EnemyColliders, m_Direction, m_SpriteId, GetGameObject()->GetPosition().x, GetGameObject()->GetPosition().y));
}

dae::ColliderComponent* dae::PlayerComponent::GetCollider()
{
	return GetGameObject()->GetComponent<ColliderComponent>();
}

bool dae::PlayerComponent::TryRespawn()
{
	if (m_Lives > 0)
	{
		m_Lives--;
		NotifyObservers(PlayerEvents::DIED);
		GetGameObject()->SetPosition(m_StartX, m_StartY);

		return true;
	}
	else
	{
		GetGameObject()->SetActive(false);
		NotifyObservers(PlayerEvents::OUT_OF_LIVES);

		return false;
	}
}

bool dae::PlayerComponent::IsCollidingWithEnemies()
{
	float colX{}; float colY{};
	if (m_pRigidBodyComponent->IsCollidingWith(m_EnemyColliders, colX, colY, true))
	{
		if (!m_pRigidBodyComponent->GetLastCollidedGameObject()->GetComponent<ColliderComponent>()->GetIgnoreFlag())
			return true;
	}

	return false;
}

void dae::PlayerComponent::Move(float dirX, float dirY)
{
	reinterpret_cast<IPlayerState*>(m_pCurrentState.get())->Move(this, dirX, dirY);
}

void dae::PlayerComponent::ShootBubble()
{
	if (m_ShootTimer > 0)
		return;
	
	reinterpret_cast<IPlayerState*>(m_pCurrentState.get())->ShootBubble(this);
}

void dae::PlayerComponent::Update(float deltaTime)
{
	reinterpret_cast<IPlayerState*>(m_pCurrentState.get())->Update(this, deltaTime);
}

void dae::PlayerComponent::HandleMovement(float deltaTime)
{
	if (IsCollidingWithEnemies())
	{
		ChangeState(DEAD);
		return;
	}

	if (m_CurrentYSpeed < 0)
	{
		m_IsGrounded = m_pRigidBodyComponent->Move(m_CurrentXSpeed * deltaTime, m_CurrentYSpeed * deltaTime, m_pLevelComponent->GetBorderColliders());
	}
	else
	{
		m_IsGrounded = m_pRigidBodyComponent->Move(m_CurrentXSpeed * deltaTime, m_CurrentYSpeed * deltaTime, m_pLevelComponent->GetNearbyLevelTileColliders());
	}

	auto pos = GetGameObject()->GetWorldPosition();
	if (pos.y > 448.f)
	{
		GetGameObject()->SetPosition(pos.x, 0 - 64.f);
	}

	if (m_CurrentXSpeed < 0)
	{
		m_CurrentXSpeed += m_MoveSpeed;
		if (m_CurrentXSpeed > 0) m_CurrentXSpeed = 0;
	}
	else if (m_CurrentXSpeed > 0)
	{
		m_CurrentXSpeed -= m_MoveSpeed;
		if (m_CurrentXSpeed < 0) m_CurrentXSpeed = 0;
	}

	if (!m_IsGrounded)
	{
		m_CurrentYSpeed += m_AirDecelerationSpeed * deltaTime;
		if (m_CurrentYSpeed > m_MaxFallSpeed) m_CurrentYSpeed = m_MaxFallSpeed;
	}
}

void dae::PlayerComponent::FixedUpdate(float)
{

}