스타크래프트 기능 구현 3

2023. 7. 16. 15:07개인공부/Direct2D

체력바와 유닛 공격 구현


구현내용

1. 체력 Bar

 현재는 Unit 컴포넌트가 여러가지 컴포넌트를 가지고 전체적인 이벤트들을 처리하고 있다. BarUI를 예를 들면 Unit 컴포넌트가 Start 함수에서  BarUI의 주소를 받아오고 Unit의 체력이 조정될때 BarUI의 길이를 바꾸는 형식으로 구현하였다.

조정을 받은 BarUI는 자신의 정보들을 가지고 랜더링을 시작한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void BarUI::PostRender(D2DRenderer* _d2DRenderer)
{
    // 게임오브젝트의 위치를 가져온다
    Transform* transform = GetComponent<Transform>();
    Vector2 position = transform->GetPosition();
 
    // 오프셋 조정
    Vector2 finalPosition = position + m_positionOffset;
    Vector2 innerScale = m_scale + m_innerBarOffset;
    
    // 바깥쪽 바그리기
    _d2DRenderer->DrawFillRectangle(finalPosition, m_scale, m_edgeColor);
 
    // 내부 빈공간 바그리기
    _d2DRenderer->DrawFillRectangle(finalPosition, innerScale, m_innerEmptyColor);
 
    // 내부에 채워지는 바 그리기
 
    Vector2 leftTop{};
    leftTop.x = finalPosition.x - innerScale.x * 0.5f;
    leftTop.y = finalPosition.y + innerScale.y * 0.5f;
    Vector2 rightBottom{};
    rightBottom.x = leftTop.x + innerScale.x * m_barLength;
    rightBottom.y = finalPosition.y - innerScale.y * 0.5f;
 
    _d2DRenderer->DrawFillRectangle2(leftTop, rightBottom, m_innerFillBarColor);
}
 
cs

 

2. 공격 

공격의 경우에는 확정적으로 대미지를 주는 방법(타겟팅 방법)을 먼저  구현하였다.  Sensor 컴포넌트를 사용해서 공격대상이  현재 사거리 내부에 있으면 공격하고 밖이면 추적하는 방식이다. 발사된 총알은 충돌체를 가지지 않고 목표와의 거리를 계산해서 대미지 처리를 하였다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 
void ShootBullet::Update(float _deltaTime)
{
    // 타겟이 사라진경우 총알을 파괴한다.
    if ( m_target == nullptr || !m_target->IsAlive())
    {
        m_target = nullptr;
    }
 
    Transform* transform = GetComponent<Transform>();
    
    // 총알이 이동거리만큼 이동한다.
    Vector2 moveDistance = m_direct * _deltaTime * m_shootSpeed;
    transform->AddPosition(moveDistance);
 
    Vector2 position = transform->GetPosition();
    
    // 거리의 제곱이 이전 거리보다 증가했으면 총알을 삭제하고 타겟에게 대미지를 준다.
    float currentDistance = (position - m_desitinaiton).LengthSquared();
 
    if (m_prevDistance <= currentDistance && GetGameObject()->GetObjectState() == OBJECT_STATE::ALIVE)
    {
        GetGameObject()->Destory();
        GameObject* effect = new GameObject("effect", GetManagerSet(), OBJECT_TYPE::ATTACK_EFFECT);
        effect->CreateComponent<Transform>()->SetPosition(position);
        effect->CreateComponent<Animator>()->CreateAnimation(L"hitAnimation1", L"hitEffect1"
            , Vector2::Zero, Vector2(32.f, 32.f), Vector2(32.f, 0.f), 0.1f, 3);
        effect->GetComponent<Animator>()->Play(L"hitAnimation1"false);
 
        GetManagerSet()->GetSceneManager()->RegisterObject(effect);
        effect->Destory(0.3f);
    
        if (m_target != nullptr)
            m_target->GetComponent<Unit>()->TakeDamage(10.f);
    }
 
    m_prevDistance = currentDistance;
}
cs

 

다음 목표

확실히 현재의 구조에서는 다양한 오브젝트의 처리를 처리하는데 한계가 있다. 구조에 대한 고민을 더하고 더 확장성 있는 구조로 리팩토링 예정이다.

'개인공부 > Direct2D' 카테고리의 다른 글

D2D 이펙트 공부  (0) 2023.07.26
Direct2D Effect 응용  (0) 2023.07.25
스타크래프트 기능 구현 2  (0) 2023.07.14
충돌 연산 최적화  (0) 2023.07.12
스타크래프트 기능 구현 1  (0) 2023.07.10