프로그래밍 공부
작성일
2023. 11. 14. 19:10
작성자
WDmil
728x90

저번에 만들었던 인벤토리를 조금 수정해서 상점UI를 만들어보자.

 

함수포인터를 응용한 디자인 패턴중 하나가 옵저버 패턴이 있는데, 이 방법을 사용해서 상점 UI를 구현할것이다.

 

전에 만들었던 인벤토리 형태는, Button이 전역으로 설정된 mouseBag객체에 데이터를 보내주는 형태로 되어있다.

 

이걸 기반으로, 상점과 인벤토리의 차이점을 짚어보자.

 

상점 인벤토리
구매와 판매가 이루어져야한다. 보관만 하면된다.
구매하지 않은 상품은 가져가서는 안된다. 아이템은 보관만 하고 언제든 가져갈 수 있다.
아이템의 가격을 참조해서 전체 가격을 제공해야한다. 아이템의 가격은 상관없이 데이터를 저장만 하면된다.
판매할 상품과 구매할 상품을 구분해야한다. 구분할 필요가 없다.

 

위와같은 차이점이 나타남을 정리함으로써 알 수 있다.

 

그렇다면, 이를 어떻게 해결할것인지 생각해보자.

 


내가 선택한 object가 Player의 것인지 아닌지를 판별한다.

 

저장할 공간이 Player가 접근할 수 있는지 아닌지를 판별한다.

 

객체에 가격 변수를 추가한다.

 

위 3가지만 추가하면 모든 항목이 해결될것이다.

 

구매와 판매가 이루어지는것은 Button만 추가하면 될것이고, 구매할 항목과 판매할 항목의 구분은 소유권으로 확인하면 된다.

 

구매하지 않은 상품은 접근이 불가능하게 설정하면 될것이고.

 

아이템의 가격을 참조하는것은 가격변수를 추가한다음, 포괄하는 UI가 관리하면 된다.

 

판매할 상품과 구매할 상품을 구분해야하는것은. 아이템의 소유권을 판별하면 된다.

 

UI를 구현해보자.


class ShopUI : public Quad
{
public:
	ShopUI(wstring textureFile);
	~ShopUI();

	void Update();
	void PostRender();
	void GUIRender();
	void insertblock(Block* block);

	void SetDrag() { isDrag = !isDrag; }

	void IsOpenUI(bool input);

private:
	void InventoryRender();
	void InventoryposUpdate();
    
private:
	Vector3 dragoffset;

	unordered_map<UINT, InvenBlock*> Itemmap;
	Vector3 ItemmapBase = { -18 * 4, -18 * 3 - 4, 0.0f };

	unordered_map<UINT, InvenBlock*> Buymap;
	Vector3 BuymapBase = { 18 * 2, -18 * 3 - 4, 0.0f };

	Transform* moneypos;

	bool isDrag = false;
	int Buymapmoney = 0;
};

상점 UI의 Header이다. 해당 UI는 각 객체의 상호작용이 Inventory와 크게 다르지 않은 구성을 띄고있다.

 

그러나, 가지고있는 map의 차이점이 있음으로. 해당 사항을 공통으로 관리할것 이 아니라면. 생성작용을 따로 해야한다.

 

상점 UI에서는 아이템의 가격정보만 알아오면 된다.

 

private:
	UINT count = 0; // InvenBlock에 들어있는 블록의 개수
	Vector3 mainPos; // InvenBlock의 위치
	Block* block = nullptr; // InvenBlock에 들어있는 블록의 포인터
	Quad* hashud = nullptr;

	bool hasPlayer = true;
	bool canInput = true;
	bool canPop = true;
};

아이템을 관리하는 객체에 bool형태의 변수 3개를 추가해주자.

 

hasPlayer는 이것이 Player 의 소유인지 아닌지를 판별한다.

 

canInput은 해당 칸 안에 Player가 넣을 수 있는지 아닌지를 판별한다.

 

canPop은, 해당칸 안의 객체를 Player가 가져갈 수 있는지 아닌지를 판별한다.

void ShopUI::InventoryRender()
{
	if (GetRender()) {
		FOR(24)
		{
			Itemmap[i]->PostRender();
			Buymap[i]->PostRender();
		}

		Font::Get()->RenderText(to_string(Buymapmoney), moneypos->GetGlobalPosition());

		Vector3 def(-80, 0, 0);
		if(Buymapmoney < 0)
			Font::Get()->RenderText("-", moneypos->GetGlobalPosition() + def);
		else
			Font::Get()->RenderText("+", moneypos->GetGlobalPosition() + def);

	}
}

void ShopUI::InventoryposUpdate()
{
	int moneyResult = 0;
	FOR(24) 
	{
		Itemmap[i]->Update();
		Buymap[i]->Update();
		if (Buymap[i]->GetBlock() != nullptr)
		{
			if (Buymap[i]->GetHasPlayer())
				moneyResult += Buymap[i]->GetBlock()->GetBlockData().cash * Buymap[i]->GetCount();
			else
				moneyResult -= Buymap[i]->GetBlock()->GetBlockData().cash * Buymap[i]->GetCount();
		}
	}

	Buymapmoney = moneyResult;
}

위와같이 UI객체에 인벤토리 의 각 항목을 update하고, 정보데이터를 각각 저장하여 사용한다.

 

Update된 가격정보를 반영하고, 반영된 가격정보를 Font로 UI하단에 출력할 수 있도록 한다.

이런 형태로 UI가 구성된다.

728x90