ItemManager클래스

jh Seo·2023년 7월 24일
0

ItemManager.h

코드

#ifndef _ItemManager_H
#define _ItemManager_H

#include<vector>
#include "Item.h"
#include "CollisionManager.h"
using namespace std;

class ItemManager 
{
public:
    ItemManager(vector<IDraw*>& drawableObjects );
    ~ItemManager();
    void GenerateItem(Item* item,int posX,int posY, bool isPoison);
    void CheckIfUnusedItemExist();

private:
        CollisionManager& colMgr=CollisionManager::GetInstance();
    vector<Item*> Items;
    //int maxItemCnt; 동시에 세개까지라는게 동시에 두개도 허용인지 모르겠어서 일단 보류
};

#endif

간략한 설명

멤버 변수로는 싱글턴으로 관리되는 충돌처리매니저의 인스턴스를 가지고,
[충돌처리매니저 구현]
Item객체들을 관리하는 vector를 가진다.
[아이템 구현]

ItemManager.cpp

코드

#include"../Include/ItemManager.h"
#include<cstdlib>
using namespace std;

ItemManager::ItemManager(vector<IDraw*>& drawableObjects){
    Items.push_back(new Item());
    Items.push_back(new Item());
    Items.push_back(new Item());

    for(int i=0;i<3;i++){
        drawableObjects.push_back(Items[i]);
    }
}
ItemManager::~ItemManager(){
    Items.clear();
    vector<Item*>().swap(Items);
}
void ItemManager::GenerateItem(Item* item,int tmpPosX,int tmpPosY,bool tmpIsPoison){
    //벽에 생성되면 안됨 나머지연산이라 0이 나올수 있음ㄴ
    if(tmpPosX==0)tmpPosX++;
    if(tmpPosY==0) tmpPosY++;
    item->SetItem(tmpPosX,tmpPosY,tmpIsPoison);
    item->SetState(true);
    //스네이크바디와 안겹치게 랜덤으로 나타내려면 스네이크의 전체몸을 큰 직사각형으로 하고 그 직사각형 범위외부에서 짜는게 좋을듯
}
void ItemManager::CheckIfUnusedItemExist(){
    
    int tmpPosX,tmpPosY,tmpIsPoison;
    for(Item* elem: Items){

        //item중에 사용중이 아닌 아이템이라면 해당 아이템 세팅하고 표시
        if(!elem->GetState()) {
			tmpPosX=rand()%20,tmpPosY=rand()%20,tmpIsPoison=rand()%2;
            //collider제거
            colMgr.DisableCollider(elem->getPos());
            //아이템 새로 생성
            GenerateItem(elem,tmpPosX,tmpPosY,tmpIsPoison);
            colMgr.SetNewCollider(make_pair(tmpPosX,tmpPosY),elem);
        }
    }
}

간략한 설명

  • 생성자의 인자로 Idraw인터페이스를 상속받는 객체들을 관리하는 벡터를 받는다.
    매 아이템 생성마다 새로운 객체를 생성하고 파괴하면 효율이 안 좋을 것이다.
    유니티의 object pooling기법에서 착안해서
    생성자에서 아이템을 최대 사용량만큼 미리 만들어놓는다.
    여기선 세 개로 정했다.
    그 후, vector<Item*> items에 넣고, vector<IDraw*> drawableObjects에 넣어준다.

  • 소멸자에서는 items벡터를 clear해주고 빈 벡터와 swap연산으로 초기화해준다.

  • GenerateItem함수에서는
    인자값으로 받은 아이템을 해당 위치에 생성한 후, 사용중을 true로 변경해준다.
    주의할 점은 현재 아이템 생성위치를 random에서 나온값을 나머지연산을 통해
    0~19까지 좌표값이 나오는데 0이면 벽에 생성되므로 곤란하다.
    0일땐 ++연산을 해줬다.

  • CheckIfUnusedItemExist함수에서는
    아이템벡터를 순회하며 사용중이 아닌 아이템은
    기존 위치의 콜라이더 제거 후, 좌표를 랜덤으로 뽑는다.
    해당 랜덤 위치에 GenerateItem함수로 생성하고, 충돌체 지정을 해준다.
    따라서 SnakeGame함수에서 매 주기마다 CheckIfUnusedItemExist를
    호출하기만 하면 된다.

생각

아이템 위치를 마구 랜덤으로 뽑아서 아이템끼리 겹칠수 도 있고,
게이트랑 겹치거나 플레이어 몸 중간에 나올수도 있다.

떠오르는 방법은
(1,1)부터 (20,20)까지 모든 좌표를 pair형으로 관리하며,
게이트 위치만 빼놓은 후 벡터에 넣어놓는다.
그 후, 벡터 sort함수에 랜덤을 적용해서 랜덤정렬을 시킨 후,
앞에서부터 좌표를 빼서 사용하는 방식도 좋을 것 같다.

Snake객체에도 isSnakeBody라는 함수가 있으므로
앞에서 좌표를 뺄때 isSnakeBody로 체크하면서 snakeBody가 아닌 좌표만 호출하면 플레이어 몸에서 아이템이 생성하는 문제도 해결 할 수 있을 것이다.

profile
코딩 창고!

0개의 댓글