에디의 우당탕탕 코딩공장

[객체지향프로그래밍(2)] Midterm Test Report #1번 풀이

by 인턴 에디

📄 21년도 객체지향프로그래밍(2) 중간고사

     - 주어진 코드를 이용해 문제 해결

1️⃣When a user press a ESCAPE key, pause the game showing a confirmation panel instead of exiting from the game. The confirmation panel placed at the center of the screen, shows two buttons, displaying "Exit" and "Continue". When the user presses the "Exit" button, it will stop the game and terminate it. If the user presses the "Continue" button, it will resume the game play. The confirmation panel will be attached to the TetrisGame object when the user presses the ESCAPE key and will be disappeared when the user clicks one of the children buttons. Two buttons, "Exit" and "Continue" will be the children of the confirmation panel.

1. Create ConfirmationPanel.

   (1) GameObject.h에 shape을 모두 빈칸으로 만들어주는 오버로딩 함수 생성

void setShape() { memset(shape, ' ', capacity); }

  (2) ConfirmationPanel class 생성

#include "GameObject.h"

class ConfirmationPanel :public GameObject
{
public:
	ConfirmationPanel(const Position& pos, GameObject* parent)
		: GameObject(" ",pos , Dimension{ 20, 10 }, parent)
	{
		GameObject::setShape();
	}

};

   

  (3) Panel update 및 Pause 

//GameObject.h
virtual void stop() {}

GameObject* getfirstChild()
	{
		if (children.empty()) return nullptr;
		return children.front();
	}
//Block.h
void stop() override
	{
		speed = 0;
	}
//Tetris.h
void update() override {
        if (isPause == true)
        {
            map->getfirstChild()->stop();
        }
        if (map->isDone()) {
            isCompleted = true;
            return;
        }
        if (input->getKey(VK_ESCAPE))
        {
            if (confirmationpanel != nullptr)
            {
                return;
            }
            confirmationpanel = new ConfirmationPanel(Position{ 0,0 }, new Panel{ "ConfirmationPanel", Position{25,10 },  20, 10, this });
            isPause = true;
        }
            
    }

  (3) Create button class

#include "GameObject.h"

class Button :public GameObject
{
public:
	Button(const Position& pos, GameObject* parent)
		: GameObject("", pos, { parent->getDimension().x,parent->getDimension().y}, parent)
	{}

};
//Tetris.h
//void update() override
//동적생성으로 버튼객체를 판넬오브젝트의 자식으로 생성
confirmationpanel = new ConfirmationPanel(Position{ 0,0 }, new Panel{ "ConfirmationPanel", Position{25,10 },  20, 10, this });
 new Button{Position{0,0},new Panel{ "==Exit", Position{5,3}, 10,1, confirmationpanel } };
 new Button{Position{0,0},new Panel{ "Continue", Position{5,7}, 10, 1, confirmationpanel } }​

 

  (4) Create EventSystem

 

 

탬플릿 함수를 이용해, 이벤트 타입별로 특수화 하여 현재 event상태를 외부에 전송할 수 있도록 했다.

//사용자 지정 이벤트 타입
enum class EventType {
	nothing,
	exitGame,
	continueGame
};

 

EventSystem은 싱글톤으로 생성, GameObject 클래스에 protected 멤버로 넣었다.

class EventSystem
{
	EventType currentEventType;
	EventSystem():currentEventType(EventType::nothing)
	{}	
	static EventSystem* Instance;
public:
	static EventSystem* GetInstance() {
		if (Instance == nullptr) {
			Instance = new EventSystem;
		}
		return Instance;
	}

	EventType getCurrentEvenetType() { return currentEventType; };
	void setCurrentEventType(const EventType eventtype = EventType::nothing) 
	{ currentEventType = eventtype; }


	void startEvent(EventType eventtype)
	{
		switch (eventtype)
		{
		case EventType::exitGame:
			startEvent<EventType::exitGame>();
			break;
		case EventType::continueGame:
			startEvent<EventType::continueGame>();
			break;
		}
	}

	template <EventType T>
	void startEvent()
	{}

	template <> void startEvent<EventType::exitGame>() 
	{
		Borland::gotoxy(0, 36);
		cout << "extitGameEventStart" << endl;
		currentEventType = EventType::exitGame;
		Borland::gotoxy(0, 0);
	}
	template <> void startEvent<EventType::continueGame>() 
	{
		Borland::gotoxy(0, 36);
		cout << "continueGameEventStart" << endl;
		currentEventType = EventType::continueGame;
		Borland::gotoxy(0, 0);
	
	}
};

 

  (5) Edit Button class

//button class 멤버 함수 추가 및 update 함수 오버라이딩

//해당 버튼의 클릭범위안에 클릭 되어 있는지 체크
bool isClicked() // check isclicked in range of botton obj
{
	if (this->local2Screen().x <= input->getMousePosition().x && input->getMousePosition().x <= this->local2Screen().x + this->getDimension().x
		&& this->local2Screen().y <= input->getMousePosition().y && input->getMousePosition().y <= this->local2Screen().y + this->getDimension().y)
		return true;

	return false;
}

//왼쪽버튼 클릭 체크
void update() override
{
	if (input->getMouseButtonDown(0)&& isClicked())
	{
		eventsystem->startEvent(eventtype);
	}
}

 

  (6) Edit TetrisGame class update function

void update() override {
       //현재 이벤트 타입 받아옴.
        EventType eventType = eventsystem->getCurrentEvenetType();

        // 게임 멈출시 블록 멈춤.
        if (isPause == true)
        {
            map->getfirstChild()->stop();
        }
      /*  
        .
        .
        .*/
        
        // 이벤트 타입에 따라 이벤트 코드 작성
        if (eventType != EventType::nothing) //Event가 들어오면,
        {     
            switch (eventType)
            {
            case EventType::exitGame:
                isCompleted = true;
                confirmationpanel->setActive(false);
                confirmationpanel->getParent()->setActive(false);
                eventsystem->setCurrentEventType();
                break;
            case EventType::continueGame:
                isPause = false;
                map->getfirstChild()->move();
                confirmationpanel->setActive(false);
                confirmationpanel->getParent()->setActive(false);
                eventsystem->setCurrentEventType();
                break;
            }
        }
            
    }

 

블로그의 정보

에디의 우당탕탕 코딩 공장

인턴 에디

활동하기