*** 공부 방법 ***
1. 코딩을 해야 하는 부분은 첫 부분에 변수나 함수, 메소드에 대한 선언이 코드블럭으로 표시되어 있다. //ex) MakeFunction(); 2. 코드블럭 하단에는 해당 선언에 대한 구현 로직이 작성되어 있다. 처
hyrule.tistory.com
[ 오류 수정 ]
< bool CCollisionManager::CollisionBoxToBox(Vector2& HitPoint, CColliderBox* Src, CColliderBox* Dest) >
- HitPoint 값을 Src와 Dest 모두 바꿔주어야 하는데 Src의 값만 변경하였음.
- HitPoint의 값을 Src와 Dest 둘 다 변경해주어야 하므로 HitPoit를 인자로 받지 말고 아예 메소드 안에서 접근하여 처리해준다.
- 아예 두 개로 분리되어 있던 메소드를 하나로 합쳐 주자.
- CCollisionManager에서 CColliderBox로 접근할 수 있도록 friend class 추가가 필요하다.
-
bool CCollisionManager::CollisionBoxToBox(CColliderBox* Src, CColliderBox* Dest)
{
const BoxInfo& SrcInfo = Src->GetInfo();
const BoxInfo& DestInfo = Dest->GetInfo();
//일단 충돌이 안 일어나는 상황을 전부 걸러주면
if (SrcInfo.LT.x > DestInfo.RB.x)
return false;
else if (SrcInfo.RB.x < DestInfo.LT.x)
return false;
else if (SrcInfo.LT.y > DestInfo.RB.y)
return false;
else if (SrcInfo.RB.y < DestInfo.LT.y)
return false;
//충돌이 일어나는 상황이라는 말이 된다.
//충돌이 일어나는 상황이라면우선 히트포인트를 계산해야 한다.
float Left = SrcInfo.LT.x > DestInfo.LT.x ? SrcInfo.LT.x : DestInfo.LT.x;
float Top = SrcInfo.LT.y > DestInfo.LT.y ? SrcInfo.LT.y : DestInfo.LT.y;
float Right = SrcInfo.RB.x < DestInfo.RB.x ? SrcInfo.RB.x : DestInfo.RB.x;
float Bottom = SrcInfo.RB.y < DestInfo.RB.y ? SrcInfo.RB.y : DestInfo.RB.y;
Vector2 HitPoint;
HitPoint.x = (Bottom + Top) / 2.f;
HitPoint.y = (Right + Left) / 2.f;
Src->m_HitPoint = HitPoint;
Dest->m_HitPoint = HitPoint;
return true;
}
- 이제 게임에서 충돌 여부와 충돌시 충돌 위치를 알 수 있게 되었다.
- 이제 타격 이펙트를 만들 수 있다.
flag.h
- 플래그에 이펙트의 타입을 저장할 열거체를 만들어 준다.
< EEffectType >
- Once, Duration, Loop
- Once: 일반 타격이펙트, Duration: 버프, Loop: 계속 지속(ex.전직 이펙트, 아이템 이펙트(태양불꽃망토 등))
class CEffect
- CGameObject의 상속을 받아서 생성. CGameObject의 하위 필터로 생성해준다.
마찬가지로 Init, Update, PostUpdate, Render 메소드를 가진다.
< m_EffectType >
- 위의 EffectType를 들고 있는 변수
< GetEffectType(), SetEffectType() >
- SetEffectType()를 해 줄떄 만약 설정한 타입이 Loop이면 바로 CAnimation에 들어가서 루프로 설정 해준다.
-- CAnimation에 루프로 설정해주는 메소드가 추가되어있지 않으므로 추가한다.
< CEffect() >
- 생성자에서 기본값으로 EffectType를 Once로 초기화해준다.
< Init() >
- CreateAnimation() 메소드를 통해 무조건 하나의 애니메이션을 들고있게 해준다.
- 또한, 이펙트 타입은 애니메이션이 재생되고 나서 사라지는 경우가 많다. -> 이렇게 사라지게 되는건 EndFunction()에서 처리가 가능하다.
-- 문제점은... 현재 코드가 CAnimaion에 특정 CAnimationInfo를 등록하지 않으면 EndFunction도 등록할 수 없다는 것이다.
---> CAnimation 클래스의 수정이 필요하다.
class CAnimation
< m_CurrentAnimationEndFunc >
- EndFunction()을 지정되지 않은 경우에만 들어올 공통 진입 EndFunction()을 CAnimation에 만들어 준다.
< SetCurrentAnimationEndFunc() >
- 템플릿을 사용한다. 인자로는 들어온 T타입의 주소와, T타입 객체가 가지고 있는 함수 포인터를 받는다.
-- 현재 애니메이션의 공통 EndFunc이므로 이름은 인자로 받을 필요가 없다.
- bind로 묶어서 m_CurrentAnimationEndFunc에 등록한다.
< Update() >
- 이제 AnimationEnd에 도달하면, 만약 m_CurrentAnimationEndFunc가 등록되어 있을경우 해당 함수를 실행시킨다.
class CEffect
< EffectEnd() >
- 이펙트 애니메이션의 재생이 끝나면 호출될 함수.
- 우선 EEffectType이 Once로 설정되어 있다면, SetActive를 false로 전환해준다.
< Init() >
- 방금 만든 EffectEnd() 메소드를 기본 EndFunction으로 등록해 준다.
< Update() > < m_Duration > < m_Time >
- EEfectType이 m_Duration일 경우에 대한 처리를 추가한다.
-- 이 경우에는 시간을 측정해서 m_Duration이 끝날 경우 이펙트 효과를 제거해주어야 한다.
< SetDuration() >
- 이펙트 준비는 완료. 총알이 파괴될 때 이펙트를 생성하여 작동하는지 확인해 보자.
//애니메이션 시퀀스 생성
GetSceneResource()->CreateAnimationSequence("BulletSFX", "BulletSFX", TEXT("/BulletEffect/BulletEffect.bmp"));
for (int i = 0; i < 10; ++i)
{
GetSceneResource()->AddAnimationSpriteFrame("BulletSFX",
68.f * i, 0.f,
64.f, 64.f);
}
GetSceneResource()->SetColorKey("BulletSFX");
- MainScene에 우선 애니메이션을 생성해 주고,
void CBullet::CollisionBegin(CCollider* Src, CCollider* Dest)
{
CEffect* Effect = m_OwnerScene->CreateObject<CEffect>("BulletSFX");
Effect->AddAnimation("BulletSFX", "BulletSFX", true, 0.3f);
Effect->SetPivot(0.5f, 0.5f);
Effect->SetPos(Src->GetHitPoint());
SetActive(false);
}
- Bullet의 충돌 시작 함수에 이펙트를 생성해주고 실행하면,
'WIN32API FrameWork > 한단계씩 직접 구현' 카테고리의 다른 글
50. 데미지 (0) | 2022.06.02 |
---|---|
48. 스케일 조정 (0) | 2022.06.01 |
46. 충돌 처리 6 - 충돌 로직 개선 및 박스충돌 완성 (0) | 2022.05.30 |
45. 충돌 처리 5 - 실제 충돌체 생성 및 관리 (0) | 2022.05.30 |
44. 충돌 처리 4 - 사각형 충돌체 (Box Collider) (0) | 2022.05.30 |