Hamutaro
공부 좀 해라★彡/DirectX

DirectX 2D 맵 에디터 - Floor 저장, 로드, 삭제

요미 ★ 2024. 3. 29.

목차

Floor을 저장 로드를 할거면 제일 먼저 ImGui에 버튼을 생성해준다.

DirectX 2D 맵 에디터 - Floor 저장, 로드, 삭제
FloorManager에 SaveFloor(), LoadFloor() 함수를 미리 만들어 놨다.

우리의 저장 로드는 태그로 저장 되므로 Floor 생성할 때 태그를 설정해준다.

DirectX 2D 맵 에디터 - Floor 저장, 로드, 삭제

그 다음 저잘 할때 Floor.data를 읽고 Floor생성할 때 필요한 것들은 봐준다 

위에 보면 Add에 pos랑 textureFile을 받아주니까 

해당 정보들만 저장해서 로드 하면 되줄거다

Vector2 저장하는 법을 모르므로 x랑 y따로 저장해줌 -> 순서 중요!

 

DirectX 2D 맵 에디터 - Floor 저장, 로드, 삭제

이렇게 되면 저장과 로드는 잘되는 것을 볼 수 있다 ㅎ ㅎ ㅎ


지우는 것을 생각하니까 FloorManager한테 Mode로 나뉘어서 하면 어떨까 싶어졌다.

DirectX 2D 맵 에디터 - Floor 저장, 로드, 삭제

이에 맞는 함수를 미리 생각해 보았다.

DirectX 2D 맵 에디터 - Floor 저장, 로드, 삭제

ImGui에 버튼을 생성해주고 누를때 mode를 변경해주고 그에 맞는 함수를 부르면 되지 않을까..

현재 Create 기능은 씬에서 하기 때문에 가져와준다.

일단 버튼 생성

DirectX 2D 맵 에디터 - Floor 저장, 로드, 삭제

아 이렇게 하고 MapEditorScene에 잇는 Update 들을 Create에 넣을 라고 했는데 아닌거 같다는 느낌이 들었다.. 

FloorManager에서 GetMode() 를 생성해서 Scene에서 해주면 될거 같다.

DirectX 2D 맵 에디터 - Floor 저장, 로드, 삭제

ChangeMode도 SetMode로 바꿧다.

DirectX 2D 맵 에디터 - Floor 저장, 로드, 삭제

이제 지워줄라고 함수 세팅을 한다

DirectX 2D 맵 에디터 - Floor 저장, 로드, 삭제

내가 보기엔 floor에 콜라이더 REMOVE 모드 일때 클릭이벤트를 확인 하면 될거 같다.

따라서 씬에선 FloorManager Update를 REMOVE일때만 불러준다.

DirectX 2D 맵 에디터 - Floor 저장, 로드, 삭제
NONE 일때도 체크해줬다.

FloorManager에서는 floor의 클릭하는지 안하는지 체크해준다

DirectX 2D 맵 에디터 - Floor 저장, 로드, 삭제

굳이 if (mode==REMOVE)를 안줘도 되지만 가독성을 위해서 한번 더 체크해줬다.

DirectX 2D 맵 에디터 - Floor 저장, 로드, 삭제

IsClick은 마우스와 클릭했는지 확인해줌 

DirectX 2D 맵 에디터 - Floor 저장, 로드, 삭제

Remove는 vector이므로 iterator를 사용해서 지워줬다.

 

그럼 끝~!

 

영상 ↓

 

주요 코드 ↓

더보기

MapEditorScene

//MapEditorScene.h

#pragma once

class MapEditorScene : public Scene
{
private:
    const int CELL_WIDTH = 124;
    const int CELL_HEIGHT = 20;

public:
    MapEditorScene();
    ~MapEditorScene();

    void Update() override;
    void Render() override;
    void PostRender() override;

private:
    void EditBG();
    void EditTexture(Quad* quad, string key);

    void SaveBG();
    void LoadBG();

private:
    Quad* background;
    Quad* sampleTile;
};

//MapEditorScene.cpp

#include "Framework.h"
#include "MapEditorScene.h"

MapEditorScene::MapEditorScene()
{
    background = new Quad(L"Resources/Textures/BG/bg.png");
    background->SetLocalPosition(CENTER);
    background->SetTag("BG");

    LoadBG();

    sampleTile = new Quad(L"Resources/Textures/BG/Floor.png");
    sampleTile->SetActive(false);
}

MapEditorScene::~MapEditorScene()
{
    FloorManager::Delete();
}

void MapEditorScene::Update()
{
    switch (FloorManager::Get()->GetMode())
    {
    case FloorManager::CREATE:
    {
        sampleTile->SetActive(true); //생성할때 false로 설정해둠
        int x = (int)mousePos.x / CELL_WIDTH;
        int y = (int)mousePos.y / CELL_HEIGHT;

        Vector2 halfSize = Vector2(CELL_WIDTH * 0.5f, CELL_HEIGHT * 0.5f);
        Vector2 pos = Vector2(x, y) * Vector2(CELL_WIDTH, CELL_HEIGHT) + halfSize;

        sampleTile->SetLocalPosition(pos);

        if (!ImGui::GetIO().WantCaptureMouse && KEY->Down(VK_LBUTTON))
        {
            FloorManager::Get()->Add(pos, sampleTile->GetMaterial()->GetTexture()->GetFile());
        }
        break;
    }
    case FloorManager::REMOVE:
    {
        sampleTile->SetActive(false);
        FloorManager::Get()->Update();
        break;
    }
    case FloorManager::NONE:
    {
        sampleTile->SetActive(false);
        break;
    }
    default:
        break;
    }
}

void MapEditorScene::Render()
{
    FloorManager::Get()->Render();
}

void MapEditorScene::PostRender()
{
    EditBG();
    EditTexture(sampleTile, "Tile");
}

void MapEditorScene::EditBG()
{
    EditTexture(background, "BG");

    background->RenderUI();

    if (ImGui::Button("Save BG"))
    {
        SaveBG();
    }

    if (ImGui::Button("Load BG"))
    {
        LoadBG();
    }

    if (ImGui::Button("Save Floor"))
    {
        FloorManager::Get()->SaveFloor();
    }

    if (ImGui::Button("Load Floor"))
    {
        FloorManager::Get()->LoadFloor();
    }

    if (ImGui::Button("Floor Create Mode"))
    {
        FloorManager::Get()->SetMode(FloorManager::CREATE);
    }
    if (ImGui::Button("Floor Remove Mode"))
    {
        FloorManager::Get()->SetMode(FloorManager::REMOVE);
    }
    if (ImGui::Button("Floor None Mode"))
    {
        FloorManager::Get()->SetMode(FloorManager::NONE);
    }
}

void MapEditorScene::EditTexture(Quad* quad, string key)
{
    if (ImGui::Button(key.c_str()))
        DIALOG->OpenDialog(key, key, ".png,.jpg");

    if (DIALOG->Display(key))
    {
        if (DIALOG->IsOk())
        {
            string path = "Resources/Textures/BG/";
            string file = DIALOG->GetCurrentFileName();

            quad->SetTexture(ToWString(path + file));
        }

        DIALOG->Close();
    }
}

void MapEditorScene::SaveBG()
{
    background->Save();

    BinaryWriter* writer = new BinaryWriter("Resources/TextData/Shooting/BG.data");
    writer->WString(background->GetMaterial()->GetTexture()->GetFile());
    delete writer;
}

void MapEditorScene::LoadBG()
{
    background->Load();

    BinaryReader* reader = new BinaryReader("Resources/TextData/Shooting/BG.data");

    if (reader->IsFailed())
    {
        delete reader;
        return;
    }

    background->SetTexture(reader->WString());

    delete reader;
}

 

FloorManager

//FloorManager.h

#pragma once

class FloorManager : public Singleton<FloorManager>
{
public:
    enum Mode
    {
        CREATE, REMOVE, NONE
    };

private:
    friend class Singleton;

    FloorManager();
    ~FloorManager();

public:
    void Update();
    void Render();

    Mode GetMode() { return mode; }
    void SetMode(Mode mode) { this->mode = mode; }

    void Add(const Vector2& pos, wstring textureFile);
    void Remove(Floor* removeFloor);

    void SaveFloor();
    void LoadFloor();

private:
    vector<Floor*> floors;

    Mode mode = NONE;
};

//FloorManager.cpp

#include "Framework.h"

FloorManager::FloorManager()
{
}

FloorManager::~FloorManager()
{
    for (Floor* floor : floors)
        delete floor;
}

void FloorManager::Update()
{
    if (mode == REMOVE) 
    {
        for (Floor* floor : floors)
        {
            if(floor->IsClick())
                Remove(floor);
        }
    }
}

void FloorManager::Render()
{
    for (Floor* floor : floors)
        floor->Render();

    ImGui::Text(to_string(floors.size()).c_str());
}

void FloorManager::Add(const Vector2& pos, wstring textureFile)
{
    for (Floor* floor : floors)
    {
        if (floor->GetCollider()->IsPointCollision(pos))
        {
            return;
        }
    }

    Floor* floor = new Floor(textureFile);
    floor->SetLocalPosition(pos);
    floor->Update();
    floor->SetTag("Floor");

    floors.push_back(floor);
}

void FloorManager::Remove(Floor* removeFloor)
{
    vector<Floor*>::iterator iter = floors.begin();

    for (; iter != floors.end(); )
    {
        if ((*iter) == removeFloor)
        {
            ObjectManager::Get()->Add(*iter);
            (*iter)->SetActive(false);

            iter = floors.erase(iter);

            return;
        }
        else
        {
            ++iter;
        }
    }
}


void FloorManager::SaveFloor()
{
    BinaryWriter* writer = new BinaryWriter("Resources/TextData/Shooting/Floor.data");

    writer->UInt(floors.size());

    for (auto floor : floors)
    {
        //순서중요중요중요
        writer->WString(floor->GetMaterial()->GetTexture()->GetFile());
        writer->Float(floor->GetGlobalPosition().x);
        writer->Float(floor->GetGlobalPosition().y);
    }

    delete writer;
}

void FloorManager::LoadFloor()
{
    BinaryReader* reader = new BinaryReader("Resources/TextData/Shooting/Floor.data");

    if (reader->IsFailed())
    {
        delete reader;
        return;
    }

    UINT size = reader->UInt();

    FOR(size)
    {
        //순서중요중요중요
        wstring textureFile = reader->WString();
        float x = reader->Float();
        float y = reader->Float();

        Add( {x, y}, textureFile );
    }

    delete reader;
}

 

Floor

//Floor.h

#pragma once

class Floor : public Quad
{
public:
    Floor(wstring file);
    ~Floor();

    void Update() override;
    void Render() override;

    bool IsClick();
    RectCollider* GetCollider() { return collider; }

private:
    RectCollider* collider;
};

//Floor.cpp

#include "Framework.h"

Floor::Floor(wstring file)
    : Quad(file, false)
{
    collider = new RectCollider(size);
    collider->SetParent(this);
}

Floor::~Floor()
{
    delete collider;
}

void Floor::Update()
{
    UpdateWorld();
    collider->UpdateWorld();
}

void Floor::Render()
{
    Quad::Render();
    collider->Render();
}

bool Floor::IsClick()
{
    if (collider->IsPointCollision(mousePos))
    {
        if (KEY->Down(VK_LBUTTON))
        {
            return true;
        }
    }
    return false;
}