학원/경일게임아카데미

36. 스물한번째 수업 - 2

셩잇님 2023. 1. 13. 11:52
반응형

경일게임아카데미 프로그래밍반 28기 21일차 수업 (2021. 05. 07)

 

 

 


 

 

 

삼각함수(COS, SIN)와 입사각 반사각
저번시간까지 원과 원, 원과 사각형의 충돌을 알아보았습니다. 오늘은 COS, SIN에 대하여 배워봅시다.

오늘의 수업은 총 2개의 주제를 가지고 있습니다.
1. 원의 이동각도를 사인, 코사인을 이용하여 각도를 변경하여 방향을 바꾸는 것.
2. ①을 활용하여 대포를 제작하고 대포의 각도를 조절하여 쏘는 방향을 바꾸는 것.

 

 

 


 

 

 

2의 playGround.h

#pragma once
#include "gameNode.h"

#define PI 3.14156f
#define BULLETMAX 30

struct tagBullet
{
	float x, y;	//중점 좌표
	float speed;	//총알 속도
	float angle;	//총알 각도
	float radius;	//총알 붼지름
	bool isFire;	//발사했누?
};

struct tagCannon
{
	POINT center;		//대포 중점
	POINT cannonEnd;	//대포 끝점
	int radius;		//대포 붼지름
	int cannon;		//포신(?)
	float angle;		//대포 각도
};

class playGround : public gameNode
{
private:
	tagCannon _cannon;
	tagBullet _bullet[BULLETMAX];
		
public:
	playGround();
	~playGround();

	virtual HRESULT init();
	virtual void release();
	virtual void update();
	virtual void render(HDC hdc);
	
	void bulletFire();
	void bulletMove();
};

 

 

 


 

 


2의 playGround.cpp

#include "stdafx.h"
#include "playGround.h"

playGround::playGround()
{
}

playGround::~playGround()
{
}

//초기화는 여기다 하세요 제발
HRESULT playGround::init()
{
	gameNode::init();

	_cannon.angle = PI / 2;
	_cannon.cannon = 100;
	_cannon.radius = 100;
	_cannon.center.x = WINSIZEX / 2;
	_cannon.center.y = WINSIZEY;

	for (int i = 0; i < BULLETMAX; i++)
	{
		_bullet[i].speed = 5;
		_bullet[i].radius = 20;
		_bullet[i].isFire = false;
	}
	return S_OK;
}

//메모리 해제는 여기다 하세요 제발
void playGround::release()
{
	gameNode::release();
}

//여기에다 연산하세요 제에발
void playGround::update()
{
	gameNode::update();

	if (KEYMANAGER->isStayKeyDown(VK_LEFT) && _cannon.angle <= 3.04) _cannon.angle += 0.04f;
	if (KEYMANAGER->isStayKeyDown(VK_RIGHT) && _cannon.angle >= 0.08) _cannon.angle -= 0.04f;
	if (KEYMANAGER->isOnceKeyDown(VK_SPACE)) bulletFire();

	_cannon.cannonEnd.x = cosf(_cannon.angle) * _cannon.cannon + _cannon.center.x;
	_cannon.cannonEnd.y = -sinf(_cannon.angle) * _cannon.cannon + _cannon.center.y;
	
	bulletMove();
}

//여기에다 그려라 좀! 쫌!
void playGround::render(HDC hdc)
{
	HDC backDC = this->getBackBuffer()->getMemDC();
	PatBlt(backDC, 0, 0, WINSIZEX, WINSIZEY, WHITENESS);
	// 위에 건들지마라
	//================제발 이 사이에 좀 그립시다==========================

	EllipseMakeCenter(backDC, _cannon.center.x, _cannon.center.y, 100, 100);
	LineMake(backDC, _cannon.center.x, _cannon.center.y, _cannon.cannonEnd.x, _cannon.cannonEnd.y);
	
	for (int i = 0; i < BULLETMAX; i++)
	{
		if (!_bullet[i].isFire) continue;
		EllipseMakeCenter(backDC, _bullet[i].x, _bullet[i].y, _bullet[i].radius * 2, _bullet[i].radius * 2);
	}

	//==================================================
	//여기도 건들지마라
	this->getBackBuffer()->render(hdc, 0, 0);
}

void playGround::bulletFire()
{
	for (int i = 0; i < BULLETMAX; i++)
	{
		if (_bullet[i].isFire) continue;

		_bullet[i].isFire = true;
		_bullet[i].x = cosf(_cannon.angle) * (_cannon.cannon + 3) + _cannon.center.x;
		_bullet[i].y = -sinf(_cannon.angle) * (_cannon.cannon + 3) + _cannon.center.y;
		_bullet[i].angle = _cannon.angle;
		break;
	}
}

void playGround::bulletMove()
{
	for (int i = 0; i < BULLETMAX; i++)
	{
		if (!_bullet[i].isFire) continue;

		_bullet[i].x += cosf(_bullet[i].angle) * _bullet[i].speed;
		_bullet[i].y += -sinf(_bullet[i].angle) * _bullet[i].speed;

		//화면 왼쪽으로 나가면
		if (_bullet[i].x + _bullet[i].radius < 0)
		{
			_bullet[i].isFire = false;
		}
		//화면 오른쪽으로 나가면
		if (_bullet[i].x - _bullet[i].radius > WINSIZEX)
		{
			_bullet[i].isFire = false;
		}
		//화면 위쪽으로 나가면
		if (_bullet[i].y + _bullet[i].radius < 0)
		{
			_bullet[i].isFire = false;
		}
		//화면 아래쪽으로 나가면
		if (_bullet[i].y - _bullet[i].radius > WINSIZEY)
		{
			_bullet[i].isFire = false;
		}
	}
}

 

 

 


 

 

 

수업내용
2번 수업내용은 ①을 활용하여 대포를 제작하고 대포의 각도를 조절하여 쏘는 방향을 바꾸는 것이다.

.h 파일에서는 대포(_cannon)와 총알(_bullet)을 선언해주며 이들은 각각의 구조체(struct)를 가지고 있습니다. 자세한 사항은 주석으로 표시해 놓았으니 참고!

.cpp 파일에서는 대포와 총알을 초기화해주며, VK_LEFT, RIGHT를 이용하여 앵글 값을 더하거나 빼줍니다. 마지막으로 SPACE를 누를 때 총알이 발사됩니다.

여기가 제일 중요 🤔
마지막으로 아래 코드를 설명하면

_cannon.cannonEnd.x = cosf(_cannon.angle) * _cannon.cannon + _cannon.center.x;
_cannon.cannonEnd.y = -sinf(_cannon.angle) * _cannon.cannon + _cannon.center.y;

대포의 끝 (X/Y)의 위치를 설정해주는 곳입니다.
cannonEnd.X는 코사인(캐논각도) * 캐논의 포신 + 캐논의 중점좌표 x로 설정하고
cannonEnd.Y는 (-)사인(캐논각도) * 캐논의 포신 + 캐논의 중점좌표 y로 설정합니다.

마지막으로 출력부분 (render)는 따로 어려운것 없이 원, 선(포선), 총알을 출력해주는 곳입니다.

 

 

 


 

 

 

결과화면

 

 

 

 

반응형