[C++] 1.3 상호작용 맛보기 - 키보드 입력과 반응

Date:     Updated:

카테고리:

태그:

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


Chapter 1. 기본 기능 구현

1.3 상호작용 맛보기 - 키보드 입력과 반응

📃 TankExample.h 코드 설명

  • class 3개
    1. MyTank
      • 탱크 객체를 찍어낼 클래스
    2. MyBullet
      • 총알 객체를 찍어낼 클래스
    3. TankExample
      • Game2D를 상속받으며 update함수를 가지고 있다.
      • 게임을 실행시킴
#pragma once

#include "Game2D.h"

namespace jm
{
	class MyTank // 탱크 클래스
	{
	public:
		vec2 center = vec2(0.0f, 0.0f); // ⭐ 탱크의 현재 위치 (처음엔 원점. 사용자의 키보드 조작에 따라 계속 갱신될 것)

		void draw()  // 탱크를 그리는 함수.
		{
			beginTransformation();  
			{
				translate(center);                          // 실행순서 <6>. ✨ body는 'center'로, barrel은 'center + (0.13f, 0.1f)'로, turret은 'center + (-0.02f, 0.1f)'로 이동한다.
				drawFilledBox(Colors::green, 0.25f, 0.1f); // 실행순서 <1>. body를 그린다.
				translate(-0.02f, 0.1f);                    // 실행순서 <5>. ✨ barrel은 (0.13f, 0.1f)로, turret은 (-0.02f, 0.1f)로 이동한다.
				drawFilledBox(Colors::blue, 0.15f, 0.09f); // 실행순서 <2>. turret을 그린다.
				translate(0.15f, 0.0f);                     // 실행순서 <4>. ✨ barrel이 (0.15f, 0.0f)로 이동한다.
				drawFilledBox(Colors::red, 0.15f, 0.03f);  // 실행순서 <3>. barrel을 그린다.
			}
			endTransformation();
		}
	};

	class MyBullet // 총알 클래스
	{
	public:
		vec2 center = vec2(0.0f, 0.0f);   // ⭐총알의 현재 위치 (처음엔 원점. 시간에 따라 계속 갱신될 것)
		vec2 velocity = vec2(0.0f, 0.0f); // ⭐총알의 속도

		void draw()  // 총알 그리는 함수.
		{
			beginTransformation();
			translate(center);  // 실행순서 <3>. 아래 두 도형이 함께 평행이동한다.
			drawFilledRegularConvexPolygon(Colors::yellow, 0.02f, 8); // 실행순서 <1>.
			drawWiredRegularConvexPolygon(Colors::gray, 0.02f, 8); // 실행순서 <2>.
			endTransformation();
		}

		void update(const float& dt)  // ⭐ 총알의 위치인 center 값을 시간마다 업데이트 한다.(이 update 함수는 MyBullet 자체의 함수)
		{
			center += velocity * dt;  // ⭐ 총알의 위치가 '속도 * 시간'에 따라 바뀜. dt는 시간 간격이 됨
		}  
	};

	class TankExample : public Game2D // 게임을 실행시킬 클래스. Game2D를 상속 받음.
	{
	public:
		MyTank tank;

		MyBullet *bullet = nullptr;  // bullet은 총알이 발사 됐을 때만 존재하기 때문에 포인터로 되어있고 null 포인터로 초기화한다.

	public:
		TankExample()
			: Game2D("This is my digital canvas!", 1024, 768, false, 2)
		{}

		~TankExample()   // ⭐ 소멸자 !! nullptr 아닐때만 총알 객체 동적 메모리를 delete 시켜주는 역할을 한다.
		{
			if(bullet != nullptr) delete bullet;
		}

        // update() 은 run 안에서 ⭐무한루프⭐로 돌아가니까 아래 키들이 눌렸는지 매 프레임마다 계속 체크한다.
        // Game2D의 update함수 오버라이딩. 메인 무한 루프를 돌리는 run()안에서 호출된다.
		void update() override  
		{

			// ⭐ 탱크 이동 ! 키보드 방향키에 따라 부드럽게 움직이도록 한칸 * 1/60 만큼 움직이게.
            // getTimeStep() 함수는 Game2D에 있는 함수로 상속받아 사용할 수 있게 된 함수다. 프레임을 리턴함.
			if (isKeyPressed(GLFW_KEY_LEFT))	tank.center.x -= 0.5f * getTimeStep();
			if (isKeyPressed(GLFW_KEY_RIGHT))	tank.center.x += 0.5f * getTimeStep();
			if (isKeyPressed(GLFW_KEY_UP))		tank.center.y += 0.5f * getTimeStep();
			if (isKeyPressed(GLFW_KEY_DOWN))	tank.center.y -= 0.5f * getTimeStep();


			// ⭐ 포탄 발사 ! 포탄을 발사하는건 곧 포탄을 생성한다는 것. 스페이스바 누르면 발사
			if (isKeyPressedAndReleased(GLFW_KEY_SPACE)) 
			{
				bullet = new MyBullet;           // ⭐ 포탄 생성
				bullet->center = tank.center;    // ⭐ 탱크의 현재위치로 총알 현재위치가 정해짐 (탱크에서 발사되니까 )
				bullet->center.x += 0.2f;        // ⭐ 그래도 발포하는 곳에서 발사될 수 있게 위치 조정
				bullet->center.y += 0.1f;
				bullet->velocity = vec2(2.0f, 0.0f);  // ⭐ 속도 지정. 
			}

            // 시간에 따라 총알의 위치를 업뎃한다. 
			if (bullet != nullptr) bullet->update(getTimeStep()); 
            // ⭐ dt는 getTimeStep()의 리턴값이 된다. ( 1/60 )
            // ⭐ if ( bullet != nullptr ) 로 nullptr 체크 안하고 그냥 bullet->update 호출해버리면 런타임 에러가 발생한다. 
            // 왜냐하면 스페이스 누르기 전까진 bullet이 nullptr이라 아무것도 가리키고 있지 않은데 (총알 객체가 없는데) update을 호출 하려고 할테니까

			// rendering
			tank.draw(); // ⭐ 탱크 그리기
			if (bullet != nullptr) bullet->draw(); // ⭐ 총알은 포인터라 nullptr이 아닐때만 draw하기.
		}
	};
}



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

맨 위로 이동하기

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

댓글 남기기