[C++] 1.1 실시간 상호 작용 어플리케이션의 구조

Date:     Updated:

카테고리:

태그:

인프런에 있는 홍정모 교수님의 홍정모의 게임 만들기 연습 문제 패키지 강의를 듣고 정리한 필기입니다. 😀
🌜 공부에 사용된 홍정모 교수님의 코드들 보러가기
🌜 [홍정모의 게임 만들기 연습 문제 패키지] 강의 들으러 가기!


Chapter 1. 기본 기능 구현

1.1 실시간 상호 작용 어플리케이션의 구조

👱🏽‍♀️ 게임 엔진의 원리를 이해하기 좋은 코드들이다.

Game2D.h 설명

update 함수는 꼭 오버라이딩 해주어야 한다.

📃Game2D.h

#include "RGB.h"           // 색을 결정. R,G,B 값을 받는 생성자 有 
#include "Vector2.h"       // 2차원 좌표
#include "Vector3.h"       // 3차원 좌표
#include "Colors.h"        
// 👆 RGB를 include하여 다양한 색상 이름의 RGB 객체들을 미리 정의해 둠. const RGB yellow(255, 255, 0) 이런식으로.
#include "Timer.h"
#include "DrawFunctions.h" 
// 👆 원, 세모, 네모, 선분 등등 그림을 그리는 함수들을 모은 클래스. drawWLine, drawFilledBox 등등..

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <thread>         // std::this_thread::sleep_for
#include <iostream>
#include <vector>
#include <string>
#include <map>

namespace jm
{
	using vec2 = Vector2<float>;
	using vec3 = Vector3<float>;

	class Game2D
	{
	private:
		
		/*게임 창 해상도*/ 
		int width = 640; 
		int height = 480;

		/*게임 창 화면의 포인터*/
		GLFWwindow* glfw_window = nullptr;

		Timer timer;

		/*fps (프레임)의 역수*/
		float spf = 1.0f / 60.0f;		 // second(s) per frame

		/*키보드 입력을 받아서 그릴거냐(true) 말거냐(false) */
		std::map<int, bool> key_status;  // key_id, is_pressed
		std::map<int, bool> mbtn_status; // mouse_button_id, is_pressed
		bool draw_grid = false;

	public:                // 생성자
		Game2D()
		{}

		/* 제목(title), 해상도(width, height), 풀스크린 사용여부, 어느 모니터에 출력할지
이렇게 4가지 설정 가능 */
		Game2D(const std::string& _title, const int& _width, const int& _height,
			const bool & use_full_screen = false, const int & display_ix = 0);

		~Game2D();

		Game2D & init(const std::string& _title, const int& _width, const int& _height,
			const bool & use_full_screen = false, const int & display_ix = 0);

		초기화 하는 과정에서의 에러 출력 (거의   X)
		void reportErrorAndExit(const std::string& function_name, const std::string& message);

		bool isKeyPressed(const int& key); 
		bool isKeyReleased(const int & key);
		bool isKeyPressedAndReleased(const int& key); // 사용자가 키를 눌렀다가 뗐는지를 확인하는 함수

		bool isMouseButtonPressed(const int& mbtn);
		bool isMouseButtonReleased(const int& mbtn);
		bool isMouseButtonPressedAndReleased(const int& mbtn);

		vec2 getCursorPos(const bool& screen_coordinates = true);

		float getTimeStep(); // 한 프레임 당 시간이 얼마나 지났는지 측정해주는 함수

		void drawGrid();

		/*run과 update 아주 중요!*/ 
 		void run(); // Game2D.cpp 에 바디 있음

		virtual void update()  //가상함수인 이유 -> 꼭 오버라이딩 해서 사용하라는 의미 ! 
		{
      // 예시
			  // draw
			  // play sould
			  // physics update
			  // etc.
		}
	};
}

📜Game2D.cpp에서 void Game2D::run() 함수 부분 설명

  • while부분이 제일 중요하다. 프로그램의 메인 Loop가 된다.
Game2D.cpp 

void Game2D::run()
	{
		if (glfw_window == nullptr)
			init("This is my digital canvas!", 1280, 960, false); // initialize with default setting

		// 게임의 메인 루프
		while (!glfwWindowShouldClose(glfw_window))// main loop
		{
			// 1. ESC 누르면 종료 
			if (isKeyPressed(GLFW_KEY_ESCAPE)) {
				std::cout << "ESC key ends main loop" << std::endl;
				break;
			}
			
			// 2. 타이머 start
			timer.start();

			// 3. 렌더링 시작 전 전처리
			glfwMakeContextCurrent(glfw_window);
			glClearColor(1, 1, 1, 1);			 // while background
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
			glMatrixMode(GL_MODELVIEW);
			glPushMatrix();

			// 4. 격자 그리기
			drawGrid();

			// 5. ⭐update 함수 호출⭐
			update();	// the major worker function

			// 6. 렌더링 완료하고 마무리
			glPopMatrix();
			// post draw
			glfwSwapBuffers(glfw_window); // double buffering
			//glfwSetInputMode(glfw_window, GLFW_STICKY_KEYS, GLFW_FALSE); // not working 
			glfwPollEvents();

			//const double dt = timer.stopAndGetElapsedMilli();

			//Debugging
			//std::cout << dt << std::endl;

			//if (dt < spf) // to prevent too high fps
			//{
			//	const auto time_to_sleep = static_cast<int>((spf - dt) * 1000.0f);
			//	std::this_thread::sleep_for(std::chrono::milliseconds(time_to_sleep));
			//	
			//	//Debugging
			//	//std::cout << "sleep " << time_to_sleep << std::endl;
			//}
		}

		glfwTerminate();
	}

내가 실습한 코드

1. 빈 화면만 출력하기

#include "Game2D.h"
#include "PrimitivesGallery.h"
#include "TankExample.h"
#include "FaceExample.h"
#include "WalkingPerson.h"
#include "SolarSystem.h"

namespace jm
{
	class RotatingStarExample : public Game2D
	{
	public:
		void update() override  // Game2D의 update 함수 오버라이딩
		{

		}
	};
}

int main(void)
{
	jm::RotatingStarExample().run();
	
	return 0;
}

2. 풀 스크린의 빈 스크린 출력하기

#include "Game2D.h"
#include "PrimitivesGallery.h"
#include "TankExample.h"
#include "FaceExample.h"
#include "WalkingPerson.h"
#include "SolarSystem.h"

namespace jm
{
	class RotatingStarExample : public Game2D
	{
	public:
		void update() override  // Game2D의 update 함수 오버라이딩
		{

		}
	};
}

int main(void)
{
	/* 생성자 네번째 인수를 true로 바꿔 풀스크린 
	창 이름은 "This is my digital canvas!" */
	jm::RotatingStarExample().init("This is my digital canvas!", 1280, 960, true).run();
	
	return 0;
}

3. 별 그려보기

DrawFunction.hdrawFilledStar 함수 사용

#include "Game2D.h"
#include "PrimitivesGallery.h"
#include "TankExample.h"
#include "FaceExample.h"
#include "WalkingPerson.h"
#include "SolarSystem.h"

namespace jm
{
	class RotatingStarExample : public Game2D
	{
	public:
		void update() override  // Game2D의 update 함수 오버라이딩
		{
				drawFilledStar(Colors::gold, 0.4f, 0.25f);
				// 별의 바깥쪽 원의 반지름이 0.4f라는 의미, 별 안쪽의 원의 반지름이 0.25f라는 의미
		}
	};
}

int main(void)
{

	jm::RotatingStarExample().init("This is my digital canvas!", 1280, 960, false).run();
	
	return 0;
}

4. 회전하는 별 그려보기 (시간 개념 필요)

#include "Game2D.h"
#include "PrimitivesGallery.h"
#include "TankExample.h"
#include "FaceExample.h"
#include "WalkingPerson.h"
#include "SolarSystem.h"

namespace jm
{
	class RotatingStarExample : public Game2D
	{
		float time = 0.0f;  // 시간 0.0에서 시작
	public:
		void update() override // Game2D의 update 함수 오버라이딩
		{
				rotate(time * 180.0f); // 1초에 반바퀴 돌게끔

				drawFilledStar(Colors::gold, 0.4f, 0.25f);
				
				time += this->getTimeStep(); // 시간이 흘러야 함
		}
	};
}

int main(void)
{

	jm::RotatingStarExample().init("This is my digital canvas!", 1280, 960, false).run();
	
	return 0;
}


🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우 
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄

맨 위로 이동하기

C++ games 카테고리 내 다른 글 보러가기

댓글 남기기