여기에 이어서 작성하는 글
B. 인벤토리 실습
1. Inventory 생성
먼저 Inventory 를 왜 생성해야 하는지 알아보자
앞서 만들어진 item에 대한 권한을 누군가가 가지고 메모리를 해제 해야 하는데
하나하나 찾아서 각 해제하기 쉽지 않다
따라서 Inventory 객체를 생성해서 각 Item을 배열로 넣어주고
Item이 생성, 소멸될때마다 Inventory의 요소들을 생성, 소멸하는 형식으로 하면 깔끔하다
Inventory 어디에다가 생성해야 할 것인지에 대한 고민을 하자면
온라인 게임이라면 각 Player 객체에 Inventory 항목을 넣어주면 되지만
혼자하는 게임이라면 전체 코드에 작성해줘도 상관은 없다 (하나로 작성할 예정)
a. Inventory class 생성
- Inventory 클래스 생성
- 모든 아이템을 들고 있을 포인터 배열과 아이템 갯수를 샐 멤버 변수를 생성
- 포인터 배열을 초기화 해줌
🖇 Inventory.h
#pragma once
#include "Item.h"
//Enums.h 파일로 옮겨줌
//--------------------
enum {
MAX_SLOT = 100
};
//--------------------
//1.
class Inventory
{
public:
Inventory();
~Inventory();
private:
//2. 모든 아이템들을 들고있는 포인터 배열
Item* _items[MAX_SLOT];
int _itemCount = 0;
};
🖇 Inventory.cpp
Inventory::Inventory() //3.
{
for (int i = 0; i < MAX_SLOT; i++)
_items[i] = nullptr;
}
👉 여기서 include된 Item 파일은 나중에 전방선언으로 수정..
b. 아이템을 넣고 삭제할 함수 생성
- 아이템을 넣고 지울 멤버 함수 생성, 아이템을 인자로 받아줌
- 아이템이 있는지, 그리고 빈 공간이 있는지 체크하기 위해 bool 값을 리턴하게 만들고
- 각 값을 확인해 넣을 땐 빈 공간을 찾아 넣어주고
- 제거할 땐 그 공간에 널 포인터를 넣어주는 형식으로 처리
🖇 Inventory.h
public:
...
bool Additem(Item* item); //1. 2.
bool RemoveItem(Item* item);
private:
int FindEmptySlot();
int FindItemSlot(Item* item);
🖇 Inventory.cpp
...
//3.
bool Inventory::Additem(Item* item)
{
if (item == nullptr) {
return false;
}
int emptySlot = FindEmptySlot();
if (emptySlot < 0) {
return false;
}
_items[emptySlot] = item;
_itemCount++;
return true;
}
//4.
bool Inventory::RemoveItem(Item* item)
{
if (item == nullptr) {
return false;
}
int slot = FindItemSlot(item);
if (slot)
{
return false;
}
_items[slot] = nullptr;
_itemCount--;
return true;
}
int Inventory::FindItemSlot(Item* item)
{
for (int i = 0; i < MAX_SLOT; i++) {
//해당하는 아이템을 찾으면
if (_items[i] != item) {
return i;
}
}
return -1;
}
int Inventory::FindEmptySlot()
{
for (int i = 0; i < MAX_SLOT; i++) {
if (_items[i] == nullptr) {
return i;
}
}
return -1;
}
c. 슬롯 번호로 아이템을 찾아주는 기능 생성
나중에 UI와 연동해 아이템을 장착하는 기능이 됨
🖇 Inventory.h
public :
...
Item* GetItemAtSlot(int slot);
🖇 Inventory.cpp
Item* Inventory::GetItemAtSlot(int slot)
{
if (slot < 0 || slot >= MAX_SLOT) {
return nullptr;
}
//아이템이 없어도 nullptr을 들고 있어서 바로 처리
return _items[slot];
}
2. Inventory 관리
a. Inventory 싱글톤 생성
온라인 게임이 아닌 혼자하는 게임이기 때문에, Inventory를 싱글톤 객체로 만듦
🖇 Inventory.h
public :
...
static Inventory* GetInstance();
private :
...
//인벤토리를 관리할 멤버 변수 포인터 선언
static Inventory* s_instance;
🖇 Inventory.cpp
//꼭 static 변수는 처음에 나올거라고 알려줘야 함
Inventory* Inventory::s_instance = nullptr;
...
Item* Inventory::GetItemAtSlot(int slot)
{
if (slot < 0 || slot >= MAX_SLOT) {
return nullptr;
}
//아이템이 없어도 nullptr을 들고 있어서 바로 처리
return _items[slot];
}
b. 아이템을 인벤토리에 넣기
위에서 생성한 인스턴스를 인벤토리에 넣어주기
🖇 RPGGame.h
int main(){
for(int i=0; i<100; i++){
...
//아이템을 인벤토리에 넣기
bool success = Inventory::GetInstance()->Additem(item);
if (success) {
cout << "Added item to Inventory" << endl;
//아직 여기서 delete는 일어나지 않음
}
else {
cout << "Failed to add Item" << endl;
delete item; //메모리 관리에 실패한 경우 삭제까지 꼭 해야함
}
}
}
🖇 Item.h
public:
virtual ~Item(); //소멸자를 호출하기 위해 public으로 변경
3. PK 당해서 랜덤으로 일부 아이템 드랍
a. 아이템을 드랍하기
인벤토리의 랜덤한 값을 들고와서
인덱스에 해당하는 아이템 값을 가지고 옴
널인지 체크하고 (아예 없는 경우, 아이템 제대로 지우지 못한 경우)
지웠다면 프린트
🖇 RPGGame.cpp
main(){
...
//PK 당해서 랜덤으로 일부 아이템 드랍
for (int i = 0; i < 20; i++) {
//0~99
int randIndex = rand() % MAX_SLOT;
//랜덤 인덱스에 해당하는 아이템 값 가지고 오기
Item* item = Inventory::GetInstance()->GetItemAtSlot(randIndex);
//널인지체크
if (item && Inventory::GetInstance()->RemoveItem(item)) {
cout << "Removed Item" << endl;
}
}
}
b. 인벤토리 정리하기
나중에 인벤토리의 아이템이 더이상 없어져 인벤토리가 필요 없어지면
메모리를 반환하는 코드까지 작성하기
🖇 Inventory.h
public:
void Clear(); //아이템 정리
🖇 Inventory.cpp
//소멸까지 관리 (인벤토리 사용 X)
void Inventory::Clear()
{
for (int i = 0; i < MAX_SLOT; i++) {
if (_items[i]) {
delete _items[i];
_items[i] = nullptr;
}
}
}
4. 완성 코드
a. 전체 코드
b. 실행 결과
'프로젝트 > [인프런] 게임 프로그래머 입문 올인원' 카테고리의 다른 글
[게임 프로그래머 입문 올인원] 2D게임 프레임워크 : 코드 구조 설계 (103강) (0) | 2024.07.30 |
---|---|
[게임 프로그래머 입문 올인원] 2D게임 프레임워크 설계 : 스프라이트 (102강) (0) | 2024.04.17 |
[게임 프로그래머 입문 올인원] 동적할당과 캐스팅 : 아이템 드랍 (36강 + 38강) (0) | 2023.09.14 |
[게임 프로그래머 입문 올인원] 포인터와 배열 : 달팽이 문제 (25강) (2) | 2023.09.07 |
[게임 프로그래머 입문 올인원] 포인터와 배열 : 로또 번호 생성기 (24강) (0) | 2023.09.07 |