본문으로 바로가기

200814_Store_FileIO(tsv)_Button.zip
3.81MB

 

 

 

1. Item class

  - Item Data Type 선언 ( data에 key, name, image Frame 등 정보 포함 )

  - Store class 에서 Item 생성시 data를 입력 받는다

  - data를 이용하여 Button 생성 ( Button 객체에 Item texture 설정 )

  - Button Event에 ShowInfo 함수 할당

더보기
#pragma once

class Store;

struct ItemData
{
	int key;
	string name;
	int attack;
	int price;
	float frameX;
	float frameY;

	ItemData() : key(0), name(""), attack(0), price(0), frameX(0), frameY(0) {};
	ItemData(int _key, string _name, int _attack, int _price,
		float _frameX, float _frameY)
		:key(_key), name(_name), attack(_attack), price(_price),
		frameX(_frameX), frameY(_frameY) {}
	~ItemData() {}
};
//
class Item
{
public:
	Store* store;
	Quad* slot;
	Button* button;
	ItemData data;

public:
	Item();
	Item(const ItemData& _data);
	~Item();
	//
	void Update();
	void Render();
	//
	void CreateButton(wstring file);
	//
	void ShowInfo();
	void SetStore(Store* value) { store = value; }
	//
	void SetButtonTextureFrame();

};
//////////////////////////////////////////////////////////////////////////////////////////////
#include "Framework.h"
#include "Item.h"
#include "Store.h"

Item::Item()
{
}

Item::Item(const ItemData& _data)
{
	data = _data;
	//
	CreateButton(L"Textures/Store/items.png");
	//
	slot = new Quad(L"Textures/Store/slot.png", L"TextureShader");
}

Item::~Item()
{
	delete button;
}

void Item::Update()
{
	slot->Update();
	//
	button->Update();
}

void Item::Render()
{
	slot->Render();
	//
	button->Render();
}

void Item::CreateButton(wstring file)
{
	Texture* texture = Texture::Add(L"Textures/Store/items.png");
	//
	button = new Button(texture, { 10.0f, 10.0f }, { data.frameX, data.frameY });
	//
	button->SetEvent(bind(&Item::ShowInfo, this));
	//
	//button->scale = { 1.0f, 1.0f };
}

void Item::ShowInfo()
{
	if(store)
		store->selectedItemData = data;
}

void Item::SetButtonTextureFrame()
{
	Vector2 textureFrame{ data.frameX, data.frameY };
	button->SetTextureFrame(textureFrame);
}

 

2. Store class

  - Excel -> tsv 형식으로 만든 txt file을 ifstream 으로 Load

  - Load한 Data를 Item*로 생성, unordered_map 컨테이너에 저장

  - Selected Item Data는 Item class 에서 ShowInfo() 함수로 data 전달 받아 ImGui 이용하여 출력

더보기
#pragma once
//
#include "Object/GameObject/Item.h"
//
class Store : public Transform
{
private:
	unordered_map<int, Item*> items;
	UINT x;
	UINT y;

public:
	ItemData selectedItemData;

public:
	Store(UINT _x, UINT _y);
	~Store();
	//
	void Update();
	void Render();
	void PostRender();
	//
	void LoadStoreAndCreateItems();
};
//////////////////////////////////////////////////////////////////////////////////////////////
#include "Framework.h"
#include "Store.h"

Store::Store(UINT _x, UINT _y)
	:x(_x), y(_y), selectedItemData()
{
	Vector2	itemSize{ 32.0f, 32.0f }; // item frame size
	//
	LoadStoreAndCreateItems();
	// Set Store Transform
	pos = itemSize;
	scale.x = itemSize.x * x;
	scale.y = itemSize.y * y;
	// Set Item Transform
	Vector2 startPos = pos;
	//
	for (UINT j = 0; j < y; ++j)
		for (UINT i = 0; i < x; ++i)
		{
			Item* item = items[i + (j * x)];
			Vector2 ButtonPos = startPos + Vector2{ itemSize.x * i, itemSize.y * j };
			item->button->pos = ButtonPos;
			item->slot->pos = ButtonPos;
		}
}

Store::~Store()
{
	for (auto item : items)
		delete item.second;
	items.clear();
}

void Store::Update()
{
	for (auto item : items)
		item.second->Update();
}

void Store::Render()
{
	for (auto item : items)
		item.second->Render();
}

void Store::PostRender()
{
	ImGui::Text("[Store]");
	ImGui::Text("- Selected Item -");
	ImGui::Text("Key : %d", selectedItemData.key);
	//
	if(selectedItemData.name == "")
		ImGui::Text("empty");
	else
		ImGui::Text(selectedItemData.name.c_str());
	//
	ImGui::Text("Attack : %d", selectedItemData.attack);
	ImGui::Text("Price : %d", selectedItemData.price);
	ImGui::Text("frameX : %d", selectedItemData.frameX);
	ImGui::Text("frameY : %d", selectedItemData.frameY);
}

void Store::LoadStoreAndCreateItems()
{
	ifstream loadFile("Textures/Store/store.txt", ios::in);
	string key{};
	//
	while (true)
	{
		ItemData data{};
		//
		loadFile >> key;
		if (key == "key") // 처음 읽은 Data가 key 이면
		{ // 첫번째 행 전부 읽어 폐기
			string buffer{}; // 
			getline(loadFile, buffer);
			continue;
		}
		else // data 행이면 key값 형변환 해서 저장(string -> int)
		{
			//if (key == "15")
			//	int i = 0;
			data.key = stoi(key);
		}
		/* 참고 : FileStrem 은 -> int, string 을 자동 형변환 해준다 */
		// int, string, float data들을 순차적으로 저장
		loadFile >> data.name >> data.attack >> data.price >> data.frameX >> data.frameY;

		// 데이터의 key값이 새로운 값이면 아이템 생성
		items[data.key] = new Item(data);
		//
		items[data.key]->SetStore(this);

		// 더 Load 할 data가 없으면 loop 종료
		if (loadFile.eof())
			break;
	}
}

 

3. Inventory class

  - Store class와 유사한 구조

  - Buy, Sell 기능 처리

더보기
#pragma once
//
#include "Object/GameObject/Item.h"
//
class Inventory : public Transform
{
private:
	unordered_map<int, Item*> items;
	UINT x;
	UINT y;
	//
	UINT money;

public:
	Inventory(UINT _x, UINT _y);
	~Inventory();
	//
	void Update();
	void Render();
	void PostRender();
	//
	void LoadInventoryAndCreateItems();
	//
	void Buy(ItemData value);
	void Sell(ItemData value);
};
//////////////////////////////////////////////////////////////////////////////////////////////
#include "Framework.h"
#include "Inventory.h"

Inventory::Inventory(UINT _x, UINT _y)
	:x(_x), y(_y), money(100000)
{
	Vector2	itemSize{ 32.0f, 32.0f };
	//
	LoadInventoryAndCreateItems();
	// Set Store Transform
	pos = itemSize;
	pos.x += itemSize.x * 10.0f;
	scale.x = itemSize.x * x;
	scale.y = itemSize.y * y;
	// Set Item Transform
	Vector2 startPos = pos;
	//
	for (UINT j = 0; j < y; ++j)
		for (UINT i = 0; i < x; ++i)
		{
			Item* item = items[i + (j * x)];
			Vector2 ButtonPos = startPos + Vector2{ itemSize.x * i, itemSize.y * j };
			item->button->pos = ButtonPos;
			item->slot->pos = ButtonPos;
		}
}

Inventory::~Inventory()
{
	for (auto item : items)
		delete item.second;
	items.clear();
}

void Inventory::Update()
{
	for (auto item : items)
		item.second->Update();
}

void Inventory::Render()
{
	for (auto item : items)
		item.second->Render();
}

void Inventory::PostRender()
{
	ImGui::Text("[Inventory]");
	ImGui::Text("- money : %d -", money);
	for (auto item : items)
	{
		//ImGui::Text("Key : %d", item.second->data.key);
		if (item.second->data.name == "")
			continue;
		else
			ImGui::Text(item.second->data.name.c_str());
	}
}

void Inventory::LoadInventoryAndCreateItems()
{
	ifstream loadFile("Textures/Store/inventory.txt", ios::in);
	string key{};
	//
	while (true)
	{
		ItemData data{};
		//
		loadFile >> key;
		if (key == "key") // 처음 읽은 Data가 key 이면
		{ // 첫번째 행 전부 읽어 폐기
			string buffer{}; // 
			getline(loadFile, buffer);
			continue;
		}
		else // data 행이면 key값 형변환 해서 저장(string -> int)
		{
			//if (key == "15")
			//	int i = 0;
			data.key = stoi(key);
		}
		/* 참고 : FileStrem 은 -> int, string 을 자동 형변환 해준다 */
		// int, string, float data들을 순차적으로 저장
		loadFile >> data.name >> data.attack >> data.price >> data.frameX >> data.frameY;

		// 데이터의 key값이 새로운 값이면 아이템 생성
		items[data.key] = new Item(data);

		// 더 Load 할 data가 없으면 loop 종료
		if (loadFile.eof())
			break;
	}
}

void Inventory::Buy(ItemData data)
{
	int keyIdx = 0;
	while (true)
	{
		if (keyIdx >= 16)
			return;
		//
		if (items[keyIdx]->data.name != "none")
		{
			++keyIdx;
			continue;
		}
		else
			break;
	}
	items[keyIdx]->data = data;
	items[keyIdx]->SetButtonTextureFrame();
	//
	money -= data.price;
}

void Inventory::Sell(ItemData data)
{ // 미구현
	money += data.price;
}

 

4. Game Scene

  - store, inventory 관리

  - buy, sell Button 기능

더보기
#pragma once
//
#include "Object/GameObject/Store.h"
#include "Object/GameObject/Inventory.h"
//
class StoreScene : public Scene
{
private:
	Store* store;
	Inventory* inven;
	//
	Button* buyButton; // Right
	Button* sellButton; // Left
	//
public:
	StoreScene();
	~StoreScene();
	//
	virtual void Update() override;
	virtual void Render() override;
	virtual void PostRender() override;
	//
	void CreateButton();
	//
	void BuyItem();
	void SellItem();
};
//////////////////////////////////////////////////////////////////////////////////////////////
#include "Framework.h"
#include "StoreScene.h"

StoreScene::StoreScene()
{
	// Set Camera
	CAMERA->scale = { 2.0f, 2.0f };
	//
	store = new Store(4, 4);
	inven = new Inventory(4, 4);
	//
	CreateButton();
}

StoreScene::~StoreScene()
{
	delete inven;
	delete store;
}

void StoreScene::Update()
{
	store->Update();
	inven->Update();
	//
	buyButton->Update();
	sellButton->Update();
}

void StoreScene::Render()
{
	store->Render();
	inven->Render();
	//
	buyButton->Render();
	sellButton->Render();
}

void StoreScene::PostRender()
{
	ImGui::Text("================================");
	store->PostRender();
	ImGui::Text("================================");
	inven->PostRender();
}

void StoreScene::CreateButton()
{
	// Create Button
	Texture* texture{};
	texture = Texture::Add(L"Textures/Store/Right.png");
	buyButton = new Button(texture); // Right
	texture = Texture::Add(L"Textures/Store/Left.png");
	sellButton = new Button(texture); // Left
	// Set Button pos
	buyButton->pos = store->pos;
	buyButton->pos.x += (store->scale.x + 16.0f);
	sellButton->pos = inven->pos;
	sellButton->pos.x -= (sellButton->scale.x + 48.0f);
	//
	buyButton->SetEvent(bind(&StoreScene::BuyItem, this));
	sellButton->SetEvent(bind(&StoreScene::SellItem, this));
}

void StoreScene::BuyItem()
{
	inven->Buy(store->selectedItemData);
}

void StoreScene::SellItem()
{
	inven->Sell(store->selectedItemData);
}