WinAPI/[갠플] Relic Hunters Zero 모작
                
              2021-10-02/Relic Hunters Zero 모작 일지
                GameStudy
                 2021. 10. 2. 21:33
              
                          
            1. 알파 블렌딩 구현
  1-1. 코드 공유
// Flag.h
#pragma once
...
enum class CAM_EFFECT
{
    NONE,
    FADE_IN,
    FADE_OUT,
    END
};
// Camera.h
#pragma once
#include "../Object/Object.h"
class Texture;
struct CamEffect_t
{
    CAM_EFFECT eCurEffect;      // 현재 이펙트
    float      fEffectDuration; // 이펙트 지속시간
    float      fAccTime;        // 이펙트 진행시간
};
class Camera
{
public:
    Camera();
    virtual ~Camera();
    virtual bool init();
    virtual void update();
    virtual void render(HDC _hDC);
    ...
    void fadeIn(float _fDuration)
    {
        CamEffect_t ef = {};
        ef.eCurEffect = CAM_EFFECT::FADE_IN;
        ef.fEffectDuration = _fDuration;
        ef.fAccTime = 0.f;
        m_lsCamEffect.push_back(ef);
        if (0.f == ef.fEffectDuration)
        {
            assert(nullptr);
        }
    }
    void fadeOut(float _fDuration)
    {
        CamEffect_t ef = {};
        ef.eCurEffect = CAM_EFFECT::FADE_OUT;
        ef.fEffectDuration = _fDuration;
        ef.fAccTime = 0.f;
        m_lsCamEffect.push_back(ef);
        if (0.f == ef.fEffectDuration)
        {
            assert(nullptr);
        }
    }
private:
    ...
    TextureInfo*        m_pVeil; // 장막 텍스쳐
    list<CamEffect_t>   m_lsCamEffect;  
    // list 자료구조를 이용해서, 페이드 인 & 아웃효과들을
    // 메세지 큐와 비슷하게 처리 되게끔 함.
    // 먼저 들어온 효과가 다 처리되면, 다음 효과를 처리.
};
// Camera.cpp
#include "../GameInfo.h"
#include "Camera.h"
#include "../GameManager.h"
#include "../Timer.h"
#include "../Resource/Texture.h"
#include "../Resource/ResourceManager.h"
Camera::Camera()
    : ...
    , m_eCurEffect(CAM_EFFECT::NONE)
    , m_pVeil(nullptr)
    , m_fEffectDuration(0.f)
    , m_fAccTime(0.f)
{
    ...
    ResourceManager::getInst()->loadTexture(L"veil", L"veil.bmp");    // 장막 텍스쳐 로드
    Texture* temp = ResourceManager::getInst()->findTexture(L"veil");
    m_pVeil = temp->findTexture(L"veil.bmp");
    // 장막은 따로 컬러키 지정이 필요없어서 안함.
}
Camera::~Camera()
{
}
...
void Camera::render(HDC _hDC)
{
    if (m_lsCamEffect.empty()) // 효과가 없으면 early exit.
    {
        return;
    }
    CamEffect_t& ef = m_lsCamEffect.front(); // 먼저 들어온 효과를 꺼냄.
    ef.fAccTime += fDT;
    if (CAM_EFFECT::NONE == ef.eCurEffect)
    {
        return;
    }
    float fRatio = 0.f;
    fRatio = ef.fAccTime / ef.fEffectDuration; 
    // 진행 시간에 비례해서 블랜딩 효과의 정도를 계산
    if (fRatio < 0.f) // 비율 범위 고정
    {
        fRatio = 0.f;
    }
    if (fRatio > 1.f)
    {
        fRatio = 1.f;
    }
    int iAlpha = 0; // 알파 채널의 값도 RGB 채널 처럼 0~255
    if (CAM_EFFECT::FADE_OUT == ef.eCurEffect)
    {
        iAlpha = (int)(255.f * fRatio);
    }
    else if (CAM_EFFECT::FADE_IN == ef.eCurEffect)
    {
        iAlpha = (int)(255.f * (1.f - fRatio));
    }
    BLENDFUNCTION bf = {};
    bf.BlendOp = AC_SRC_OVER;
    bf.BlendFlags = 0;
    bf.AlphaFormat = 0;
    bf.SourceConstantAlpha = iAlpha;
    int nWidth = (int)m_pVeil->BmpInfo.bmWidth;
    int nHeight = (int)m_pVeil->BmpInfo.bmHeight;
    bool bRes = false;
    bRes = AlphaBlend(_hDC, 0, 0
        , nWidth, nHeight
        , m_pVeil->hDC
        , 0, 0, nWidth, nHeight
        , bf);
    if (ef.fEffectDuration < ef.fAccTime) // 시간이 다 흐르면 효과를 제거
    {
        m_lsCamEffect.pop_front();
    }
}
...
// Scene.cpp
#include "../GameInfo.h"
#include "Scene.h"
#include "SceneResource.h"
#include "SceneCollision.h"
#include "Camera.h"
#include "../Map/MapBase.h"
Scene::Scene()
    : ...
{
    ...
    m_pCamera = new Camera;
    m_pCamera->init();
    m_dpRenderArray = new Object * [m_nRenderCapacity];
    m_dpUIWindowArray = new UIWindow * [m_nUIWindowCapacity];
}
...
bool Scene::render(HDC _dc)
{
    ...
    m_pCamera->render(_dc);  // 씬의 다른 개체들이 모두 그려 진 뒤, 장막 알파 블렌딩.
    return true;
}
...
1-2. 장막 이미지(1281 x 721)

1-3. 아쉬운 점
- 현재 구조에서는 카메라가 싱글톤으로
구현되어 있지 않고, 각 씬마다 카메라를
하나씩 갖는 구조.
- 그래서 씬 전환때, 이전 씬의 페이드 아웃
다음 씬의 페이드 인이 불가능.
- 추후에 이를 반영해서, 싱글톤으로 구현 해 보려 함.
2. 타일맵 세이브엔 로드
  2-1. 스테이지 1 완성
  2-2. 몬스터 길찾기 알고리즘.
    - DFS, BFS, 다익스트라 알고리즘을
각각 카미카제 라이트, 카미카제
      카미카제 보스에 적용 시킬 예정.
3. 개체 설치