Gate.h

#ifndef _Gate_H
#define _Gate_H
#include <ncurses.h>
#include <vector>
#include "IDraw.h"
#include "ICollidable.h"
#include "CollisionManager.h"
using namespace std;
class Gate : public IDraw, public ICollidable
{
public:
    Gate(vector<IDraw*>& drawableObjects,pair<int,int> first, pair<int,int> second);

    void Draw();
    void whenCollided(Snake* s);

private:
    CollisionManager& colMgr=CollisionManager::GetInstance();
    pair<int,int> firstGatePos;
    pair<int,int> secondGatePos;

};

#endif

충돌처리 매니저와 첫번째 게이트의 좌표, 두번째 게이트의 좌표를 관리한다.

Gate.cpp

#include "../Include/Gate.h"

Gate::Gate(vector<IDraw*>& drawableObjects,pair<int,int> firstPos, pair<int,int> secondPos){
    if(colMgr.CheckIfCollide(firstPos)){
        colMgr.DisableCollider(firstPos);
    }
    if(colMgr.CheckIfCollide(secondPos)){
        colMgr.DisableCollider(secondPos);
    }
    firstGatePos=firstPos;
    secondGatePos=secondPos;
    colMgr.SetNewCollider(firstGatePos,static_cast<ICollidable*>(this));
    colMgr.SetNewCollider(secondGatePos,static_cast<ICollidable*>(this));
    drawableObjects.push_back(static_cast<IDraw*>(this));
}

void Gate::Draw(){
    mvprintw(firstGatePos.first,firstGatePos.second,"O");
    mvprintw(secondGatePos.first,secondGatePos.second,"O");
}

void Gate::whenCollided(Snake* s){
    //첫번째 게이트를 뱀이 닿았을 때,
    if(s->GetHead()==firstGatePos){
        s->SetHead(secondGatePos);
        //나오는 게이트가 벽일 때, 방향전환
        if(secondGatePos.first==0) s->SetDirection('D');
        else if (secondGatePos.first==20) s->SetDirection('U');
        else if(secondGatePos.second==0) s->SetDirection('R');
        else if(secondGatePos.second==41) s->SetDirection('L');
    }
    else if(s->GetHead()==secondGatePos){
        s->SetHead(firstGatePos);
        //나오는 게이트가 벽일 때, 방향전환
        if(firstGatePos.first==0) s->SetDirection('D');
        else if (firstGatePos.first==20) s->SetDirection('U');
        else if(firstGatePos.second==0) s->SetDirection('R');
        else if(firstGatePos.second==41) s->SetDirection('L');
    }
}
  • 생성자로는 vector<IDraw*>& 을 인자로 받아와 해당 벡터에
    게이트 객체를 등록해준다.
    그 후, 충돌처리매니저를 통해 게이트 좌표를 매핑해준다.
    그 좌표에 벽이 이미 있다면 해당 벽을 충돌처리매니저에서 제거하고
    매핑해준다.

  • Draw함수는 두개의 게이트 위치에 'O'를 그려준다.

  • ICollidable인터페이스의 whenCollided함수는
    플레이어가 두 개의 게이트중 어떤 게이트를 닿았는지 체크한 후,
    다른 게이트로 플레이어의 머리를 이동시킨다.
    snake클래스의 이동은 각 몸이 다음 몸의 좌표로 이동하는 형식이므로
    머리만 순간이동시키면 해당 위치로 자연스럽게 이동한다.

    현재 보드의 한계값을 가로 42, 세로 21로 설정해둬서
    게이트가 벽에 생성될시 방향 전환하도록 만들었다.

생각

체크해야할 부분은 지금은 보드의 넓이를 가로 42, 세로 21로 지정해서
게이트위치가 벽이라면 방향을 전환해주는 식으로 하지만,
만약 보드의 넓이가 가변형이면 처리하는 부분을 추가해야한다.

작성하다가 본 허점인데, 게이트의 좌표를 잘못줘서 벽 바로 앞에 생성된다면 그대로 게임이 끝난다.
게이트가 위치가 벽 바로 앞에 있을때도 방향전환을 해줘야할 것 같다.

profile
코딩 창고!

0개의 댓글