[C++] 2.2 연습 문제 풀이

Date:     Updated:

카테고리:

태그:

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


2.2 연습문제

연습 문제는 스스로 풀이했습니다. 😀
해당 챕터 보러가기 🖐 2.2 상속으로 깔끔하게
연습 문제 출처 : 홍정모 교수님 블로그


🙋 Q1. 다양한 물체들을 랜덤하게 그리고 별을 추가하자.

image

  • 별,원,세모,네모가 각각 5개씩 총 20개가 그려진다.
  • 랜덤한 위치, 랜덤한 크기, 랜덤한 색상으로 그려진다.

📜main

#include "Game2D.h"
#include "Examples/PrimitivesGallery.h"
#include "RandomNumberGenerator.h"
#include "GeometricObject.h"  // 부모클래스 하나만 상속받아 부모클래스 타입 포인터 하나로 자식 클래스들(별,원,세모,네모) 전부 접근하기
#include <vector>
using namespace std;

namespace jm
{

	class Example : public Game2D
	{
	public:
		RandomNumberGenerator rnd;
		vector <GeometricObject *> objs;    // 부모타입의 포인터를 담는 벡터. 이 곳에 부모 타입 포인터로 참조하여 자식 인스턴스들의 주소를 담을 것이다.  

		Example()
			: Game2D()
		{
			for (int i = 0; i < 5; i++)
			{
				objs.push_back(GeometricObject::makeBox(  // GeometricObject::makeBox -> '네모' 를 <동적할당 + 초기화> 하고 그 주소를 리턴하는 GeometricObject의 static 함수.  부모 타입 포인터로 참조하여 벡터에 넣어준다.
					rndColor(rnd.getInt(0, 9)),
					vec2{ rnd.getFloat(-1.0f ,1.0f), rnd.getFloat(-1.0f, 1.0f) },
					rnd.getFloat(0.01f, 0.25f),   
					rnd.getFloat(0.01f, 0.25f)**)**);

				objs.push_back(GeometricObject::makeStar(  //  GeometricObject::makeStar ->  '별' 를 <동적할당 + 초기화> 하고 그 주소를 리턴하는 GeometricObject의 static 함수.  부모 타입 포인터로 참조하여 벡터에 넣어준다.
					rndColor(rnd.getInt(0, 9)),
					vec2{ rnd.getFloat(-1.0f,1.0f), rnd.getFloat(-1.0f, 1.0f) },
					rnd.getFloat(0.01f, 0.25f),
					rnd.getFloat(0.01f, 0.25f)));

				objs.push_back(GeometricObject::makeCircle(  //  GeometricObject::makeCircle ->  '원' 를 <동적할당 + 초기화> 하고 그 주소를 리턴하는 GeometricObject의 static 함수.  부모 타입 포인터로 참조하여 벡터에 넣어준다.
					rndColor(rnd.getInt(0, 9)),
					vec2{ rnd.getFloat(-1.0f,1.0f), rnd.getFloat(-1.0f,1.0f) },
					rnd.getFloat(0.01f, 0.25f)));

				objs.push_back(GeometricObject::makeTriangle(  //  GeometricObject::makeTriangle ->  '세모' 를 <동적할당 + 초기화> 하고 그 주소를 리턴하는 GeometricObject의 static 함수.  부모 타입 포인터로 참조하여 벡터에 넣어준다.
					rndColor(rnd.getInt(0, 9)),
					vec2{ rnd.getFloat(-1.0f,1.0f), rnd.getFloat(-1.0f,1.0f) },
					rnd.getFloat(0.01f, 0.25f)));
			}
		}

		RGB rndColor(int i)   // 정수를 넣으면 매칭되는 컬러를 리턴해주는 함수
		{
			if (i == 0) return Colors::red;
			else if (i == 1) return Colors::green;
			else if (i == 2) return Colors::blue;
			else if (i == 3) return Colors::skyblue;
			else if (i == 4) return Colors::gray;
			else if (i == 5) return Colors::yellow;
			else if (i == 6) return Colors::olive;
			else if (i == 7) return Colors::black;
			else if (i == 8) return Colors::gold;
			else if (i == 9) return Colors::silver;
		}

		void update() override
		{
			for (const auto & obj : objs)   // 하나의 for문으로 벡터를 돌려 부모 포인터로 자식 객체들을 그린다.
				obj->draw();
		}
	};
}

int main(void)
{
	jm::Example().run();

	return 0;
}

📜GeometricObject.h

#pragma once

#include "Game2D.h"

namespace jm
{
	class GeometricObject
	{
	public:
		vec2 pos;
		RGB  color;

		void init(const RGB & _color, const vec2 & _pos)
		{
			color = _color;
			pos = _pos;
		}

		virtual void drawGeometry() const = 0;

		void draw()
		{
			beginTransformation();
			{
				translate(pos);
				drawGeometry();
			}
			endTransformation();
		}

		static GeometricObject * makeTriangle(const RGB & _color, const vec2 & _pos, const float & _size);  // static 함수라 객체 생성 없이 클래스 이름으로 바로 사용 가능. 구현은 cpp에서.
		static GeometricObject * makeCircle(const RGB & _color, const vec2 & _pos, const float & _size);
		static GeometricObject * makeBox(const RGB & _color, const vec2 & _pos, const float & _width, const float &_height);
		static GeometricObject * makeStar(const RGB & _color, const vec2 & _pos, const float & _os, const float &_is);
	};
}

📜GeometricObject.cpp

#include "Triangle.h"
#include "Circle.h"
#include "Box.h"
#include "Star.h"
#include "GeometricObject.h"

namespace jm
{
	GeometricObject * GeometricObject::makeTriangle(const RGB & _color, const vec2 & _pos, const float & _size)   
	{
		return new Triangle(_color, _pos, _size); // 1. 초기화 하고 2. 생성하고 (동적할당) 3. 주소 리턴 
	}
	GeometricObject * GeometricObject::makeCircle(const RGB & _color, const vec2 & _pos, const float & _size)
	{
		return new Circle(_color, _pos, _size);
	}
	GeometricObject * GeometricObject::makeBox(const RGB & _color, const vec2 & _pos, const float & _width, const float &_height)
	{
		return new Box(_color, _pos, _width, _height);
	}
	GeometricObject * GeometricObject::makeStar(const RGB & _color, const vec2 & _pos, const float & _os, const float &_is)
	{
		return new Star(_color, _pos, _is, _os);
	}
}

📜Box.h

#pragma once

#include "GeometricObject.h"

namespace jm
{
	class Box : public GeometricObject
	{
	public:
		float width, height;

		Box()
		{}

		Box(const RGB & _color, const vec2 & _pos, const float & _width,
			const float &_height)   // 매개변수들 받아 초기화(init함수 호출) 하는 생성자 
		{
			init(_color, _pos, _width, _height);
		}

		void init(const RGB & _color, const vec2 & _pos, const float & _width, 
			const float &_height)
		{
			GeometricObject::init(_color, _pos); // 자식들 모두 동일하게 가지는 멤버들은 부모 초기화 함수로

			width = _width;
			height = _height;
		}

		void drawGeometry() const override
		{
			drawFilledBox(GeometricObject::color, this->width, this->height);
		}
	};
}

📜Circle.h

#pragma once

#include "GeometricObject.h"

namespace jm
{
	class Circle : public GeometricObject
	{
	public:
		float size;

		Circle()
		{}

		Circle(const RGB & _color, const vec2 & _pos, const float & _size) // 매개변수들 받아 초기화(init함수 호출) 하는 생성자 
		{
			init(_color, _pos, _size);
		}

		void init(const RGB & _color, const vec2 & _pos, const float & _size)
		{
			GeometricObject::init(_color, _pos); // 자식들 모두 동일하게 가지는 멤버들은 부모 초기화 함수로
			size = _size;
		}

		void drawGeometry() const override
		{
			drawFilledCircle(color, size);
		}
	};
}

📜Triangle.h

#pragma once

#include "GeometricObject.h"

namespace jm
{
	class Triangle : public GeometricObject
	{
	public:
		float size;

		Triangle()
		{}

		Triangle(const RGB & _color, const vec2 & _pos, const float & _size) // 매개변수들 받아 초기화(init함수 호출) 하는 생성자 
		{
			init(_color, _pos, _size);
		}

		void init(const RGB & _color, const vec2 & _pos, const float & _size)
		{
			GeometricObject::init(_color, _pos); // 자식들 모두 동일하게 가지는 멤버들은 부모 초기화 함수로
			size = _size;
		}

		void drawGeometry() const override
		{
			drawFilledTriangle(color, size);
		}
	};
}

📜Star.h

#pragma once

#include "GeometricObject.h"

namespace jm
{
	class Star : public GeometricObject
	{
	public:
		float os, is;

		Star()
		{}

		Star(const RGB & _color, const vec2 & _pos, const float & _os,  
			const float &_is)  // 매개변수들 받아 초기화(init함수 호출) 하는 생성자 
		{
			init(_color, _pos, _os, _is);
		}

		void init(const RGB & _color, const vec2 & _pos, const float & _os,
			const float &_is)
		{
			GeometricObject::init(_color, _pos); // 자식들 모두 동일하게 가지는 멤버들은 부모 초기화 함수로

			os = _os;
			is = _is;
		}

		void drawGeometry() const override
		{
			drawFilledStar(GeometricObject::color, this->os, this->is);
		}
	};
}


🙋 Q2. 모든 물체들이 회전하게 만들기

📜Geometric.h

#pragma once

#include "Game2D.h"

namespace jm
{
	class GeometricObject
	{
	public:
		vec2 pos;
		RGB  color;
		float time = 0.0f;

		void init(const RGB & _color, const vec2 & _pos)
		{
			color = _color;
			pos = _pos;
		}

		virtual void drawGeometry() const = 0;

		void draw(const float& dt)
		{
			beginTransformation();
			{	
				translate(pos);            // 회전 먼저하고 이동 ! 
				rotate(time * 90.0f);
				drawGeometry();
			}
			endTransformation();
			
			time += dt;
		}

		static GeometricObject * makeTriangle(const RGB & _color, const vec2 & _pos, const float & _size);
		static GeometricObject * makeCircle(const RGB & _color, const vec2 & _pos, const float & _size);
		static GeometricObject * makeBox(const RGB & _color, const vec2 & _pos, const float & _width, const float &_height);
		static GeometricObject * makeStar(const RGB & _color, const vec2 & _pos, const float & _os, const float &_is);
	};
}

📜main

void update() override
		{
			for (const auto & obj : objs)
			{
				obj->draw(getTimeStep());
			}
		}


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

맨 위로 이동하기

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

댓글 남기기