#include "pch.h" #include "Spider.h" Texture* Spider::m_pTextures{ nullptr }; int Spider::m_Count{ 0 }; Spider::Spider(int x, int y) : Spider{ Point2f{ x * Tile::m_Size, y * Tile::m_Size } } { } Spider::Spider(const Point2f& pos) : Enemy{ pos } , m_ActionState{ ActionState::HANGING } , m_JumpTimer{ } , m_JumpDuration{ 0.5f } , m_JumpSpeed{ 620.f } , m_MoveSpeed{ 240.f } , m_JumpSFX{ "Resources/Sounds/spider_jump.wav" } , m_IdleDuration{ 1 } , m_IdleTimer{ } , m_BrakeSpeed { 250.f } { m_Hitbox.width = 58; m_Hitbox.height = 36; m_HitboxMargin.x = 12; m_HitboxMargin.y = 19; m_Lives = 1; if (m_Count == 0) { m_pTextures = new Texture{ "Resources/Sprites/enemy_spider.png" }; } m_pTexture = m_pTextures; SetAction(ActionState::HANGING); m_Count++; } Spider::~Spider() { m_Count--; if (m_Count == 0) { delete m_pTextures; m_pTextures = nullptr; } } void Spider::Draw() const { Enemy::Draw(); } void Spider::Update(float elapsedSec, const Level& level, Player* pPlayer, ParticleManager* pParticleManager) { if (m_ActionState != ActionState::HANGING) { if (!level.IsOnGround(m_Hitbox)) m_Velocity += elapsedSec * m_GravityAcceleration; if (std::fabs(m_Velocity.x) > m_BrakeSpeed * elapsedSec) { (m_Velocity.x > 0) ? m_Velocity.x -= m_BrakeSpeed * elapsedSec : m_Velocity.x += m_BrakeSpeed * elapsedSec; } else { m_Velocity.x = 0; } m_Hitbox.bottom += m_Velocity.y * elapsedSec; m_Hitbox.left += m_Velocity.x * elapsedSec; level.HandleCollision(m_Hitbox, m_Velocity); } if (pPlayer->GetState() != Player::ActionState::HURT) { if (utils::IsOverlapping(m_Hitbox, pPlayer->GetHitbox())) { if (pPlayer->DidJumpOnEnemy(GetTopVertices())) { pParticleManager->CreateBlood(Point2f{ GetHitbox().left, GetHitbox().bottom }); m_Lives--; } else { (pPlayer->GetHitbox().left < m_Hitbox.left) ? m_Direction = Direction::LEFT : m_Direction = Direction::RIGHT; pParticleManager->CreateBlood(Point2f{ pPlayer->GetHitbox().left, pPlayer->GetHitbox().bottom }); pPlayer->Hit(1, int(m_Direction)); } } } utils::HitInfo hitInfo{}; switch (m_ActionState) { case ActionState::HANGING: if (utils::Raycast(pPlayer->GetTopVertices(), Point2f{ m_Hitbox.left + m_Hitbox.width / 2, m_Hitbox.bottom }, Point2f{ m_Hitbox.left + m_Hitbox.width / 2, m_Hitbox.bottom - Tile::m_Size * 6 }, hitInfo)) { SetAction(ActionState::DROPPING); break; } break; case ActionState::DROPPING: if (level.IsOnGround(m_Hitbox)) { SetAction(ActionState::IDLE); break; } break; case ActionState::IDLE: m_IdleTimer += elapsedSec; if (m_IdleTimer >= m_IdleDuration) { (pPlayer->GetHitbox().left < m_Hitbox.left) ? m_Velocity.x = -m_MoveSpeed : m_Velocity.x = m_MoveSpeed; SetAction(ActionState::JUMPING); break; } break; case ActionState::JUMPING: m_JumpTimer += elapsedSec; if (m_JumpTimer >= m_JumpDuration) { SetAction(ActionState::IDLE); break; } break; default: break; } m_AnimTime += elapsedSec; if (m_AnimTime >= 1.f / m_NrFramesPerSec) { m_AnimFrame++; if (m_AnimFrame >= m_AnimLength) { if (m_AnimLoop) { m_AnimFrame = 0; } else { m_AnimFrame = m_AnimLength; } } m_AnimTime = 0; } m_SpriteRect.left = m_Hitbox.left - m_HitboxMargin.x; m_SpriteRect.bottom = m_Hitbox.bottom - m_HitboxMargin.y; } void Spider::SetAction(ActionState action) { m_ActionState = action; m_AnimFrame = 0; m_AnimLoop = true; switch (action) { case ActionState::IDLE: m_IdleTimer = 0; m_Velocity.x = 0; m_AnimFirstFrameId = 17; m_AnimLength = 4; m_NrFramesPerSec = 15; break; case ActionState::HANGING: m_AnimLoop = false; m_Velocity.x = 0; m_AnimFirstFrameId = 11; m_AnimLength = 0; m_NrFramesPerSec = 0; break; case ActionState::DROPPING: m_JumpSFX.Play(0); m_AnimLoop = false; m_JumpTimer = 0; m_Velocity.x = 0; m_AnimFirstFrameId = 11; m_AnimLength = 6; m_NrFramesPerSec = 12; break; case ActionState::JUMPING: m_Velocity.y += m_JumpSpeed; m_JumpTimer = 0; m_JumpSFX.Play(0); m_AnimLoop = false; m_AnimFirstFrameId = 7; m_AnimLength = 3; m_NrFramesPerSec = 8; break; default: break; } }