DX11 2D Game Programming
DX11_2020_0814_금_Store_FileIO(tsv)_Button
HI2
2020. 8. 14. 17:28
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);
}