WinApi/TBI(더 바인딩 오브 아이작) 모작

[Win32 API TBI 모작] 8. CCollider & CImage & CRigidBody

Vfly 2025. 5. 30. 22:19

이번에는 CObject의 다른 컴포넌트인 충돌체(CCollider), 이미지(CImage), 강체(CrigidBody)에 대해 알아보자.

 

전체 소스코드 : https://github.com/vfly1189/TBI


1. CCollider (충돌 검출 컴포넌트)

주요 기능

  • 충돌 영역 관리: 오브젝트의 충돌 범위를 정의하고 관리
  • 그룹별 충돌 처리: Player ↔ Monster 등 그룹 단위로 충돌 검사
  • 상대적 위치 지원: 오브젝트 중심으로부터 오프셋 위치 설정 가능

핵심 구조

class CCollider {
    static UINT g_iNextID;      // 전역 ID 관리
    CObject* m_pOwner;          // 소유 오브젝트
    Vec2 m_vOffsetPos;          // 상대적 위치
    Vec2 m_vFinalPos;           // 최종 계산된 위치
    Vec2 m_vScale;              // 충돌체 크기
    UINT m_iID;                 // 고유 ID
    UINT m_iCol;                // 충돌 상태 카운터
    bool m_bActive;             // 활성화 여부
};

주요 특징

  1. 고유 ID 시스템: 정적 변수로 각 충돌체마다 유일한 ID 부여
  2. 충돌 상태 추적: m_iCol 변수로 현재 충돌 중인 객체 수 관리
  3. 시각적 디버깅: 충돌 상태에 따라 빨간색(충돌)/초록색(비충돌)으로 렌더링
  4. 복사 생성자 처리: 깊은 복사로 새로운 ID 할당

 

2. CImage (이미지 렌더링 컴포넌트)

주요 기능

  • Direct2D 비트맵 렌더링: ID2D1Bitmap을 사용한 이미지 출력
  • 스케일 커스터마이징: 이미지 크기 조정 기능
  • HP/MP 바 구현: 비율 기반 부분 렌더링 지원
  • 계층 구조 지원: UI 객체의 parent-child 관계 처리

핵심 구조

class CImage {
    CObject* m_pOwner;          // 소유 오브젝트
    ID2D1Bitmap* m_pBitmap;     // Direct2D 비트맵
    Vec2 m_vOffSet;             // 오프셋 위치
    Vec2 m_vFinalPos;           // 최종 위치
    bool m_bScaleCustom;        // 스케일 커스텀 여부
    Vec2 m_vScale;              // 스케일 비율
    float m_fAlpha;             // 투명도
    float m_fRatioX, m_fRatioY; // 렌더링 비율
};

특별한 기능들

  1. 비율 기반 렌더링: HP/MP 바처럼 채워지는 정도를 표현
     
    // 아래에서부터 채워지는 방식으로 계산
    D2D1_RECT_F fillRect = D2D1::RectF(
        left, down - fillHeight, left + fillWidth, down
    );
  2. 카메라 시스템 연동:
    • UI, DEFAULT, EFFECT 타입: 화면 고정 위치
    • 기타 타입: 카메라 이동에 따라 위치 변경
  3. 회전 지원: 이미지 중심점 기준 회전 변환

렌더링 파이프라인

  1. 최종 위치 계산 (finalupdate)
  2. 카메라 변환 적용
  3. 비율 기반 소스/대상 영역 계산
  4. 회전 변환 적용
  5. DrawBitmap으로 렌더링

 

3. CRigidBody (물리 시뮬레이션 컴포넌트)

주요 기능

  • 뉴턴 물리학 구현: F = ma 공식 기반 운동 계산
  • 마찰력 시뮬레이션: 현실적인 감속 효과
  • 속도 제한: 축별 최대 속도 제한
  • 힘 기반 이동: AddForce()로 자연스러운 움직임

핵심 구조

class CRigidBody {
    CObject* m_pOwner;          // 소유 오브젝트
    Vec2 m_vForce;              // 적용된 힘
    Vec2 m_vAccel;              // 가속도
    Vec2 m_vAccelA;             // 추가 가속도
    Vec2 m_vVelocity;           // 속도
    Vec2 m_vMaxVelocity;        // 최대 속도
    float m_fMass;              // 질량
    float m_fFricCoeff;         // 마찰 계수
};

물리 계산 과정

  1. 힘 → 가속도 변환:
     
    float m_fAccel = fForce / m_fMass;  // F = ma
    m_vAccel = m_vForce * m_fAccel;
  2. 속도 업데이트:
     
    m_vVelocity += m_vAccel * fDT;
  3. 마찰력 적용:
     
    Vec2 vFriction = vFircDir * m_fFricCoeff * fDT;
  4. 속도 제한 (축별 독립 처리):
     
    if (m_vMaxVelocity.x < abs(m_vVelocity.x)) {
        m_vVelocity.x = (m_vVelocity.x > 0 ? 1 : -1) * m_vMaxVelocity.x;
    }
  5. 위치 업데이트 및 초기화

물리 시뮬레이션의 특징

  • 현실적인 감속: 마찰력이 속도보다 크면 즉시 정지
  • 축별 속도 제한: X, Y축 독립적으로 최대 속도 적용
  • 프레임 독립적: 델타 타임(fDT) 사용으로 일관된 물리 연산

 

컴포넌트 시스템의 장점

1. 모듈성

  • 각 컴포넌트가 독립적인 기능을 담당
  • 필요에 따라 선택적으로 오브젝트에 부착 가능

2. 재사용성

  • 복사 생성자를 통한 컴포넌트 복제 지원
  • 다양한 오브젝트 타입에 동일한 컴포넌트 적용 가능

3. 확장성

  • friend class CObject를 통한 안전한 데이터 접근
  • 새로운 컴포넌트 추가 시 기존 코드 수정 최소화

4. 성능 최적화

  • finalupdate()를 통한 일괄 업데이트
  • 카메라 시스템과의 효율적인 연동