3장 벡터와 물리 연습문제 3.1 ~ 3.2
연습 3.1
문제
그림 3.16의 삼각형은 아래의 세점 A, B, C로 그려진 것이다.
\(A = <-1, 1>\)
\(B = <2, 4>\)
\(C = <3, 3>\)
3장에서 설명했던 벡터 연산을 사용해서 \(\theta\)를 계산하라.
풀이
Exercise_3_1전체 소스
3장 에서 다룬 삼각함수와 내적으로 풀수 있는 문제이다.
- 내적은 각의 코사인과 관계가 있다. 그래서 두 벡터 사이의 각도는 다음과 같이 표현할 수 있다.
$$\vec{a}\cdot\vec{b} = ||\vec{a}|| ||\vec{b}||\cos{\theta}$$
- 따라서 \(\theta\)는 아래와 같다.
$$ \theta = \arccos{\left( \frac{\vec{a}\cdot\vec{b}}{||\vec{a}|| ||\vec{b}||} \right)} $$
- 이를 코드로 나타내면 아래와 같다.
Exercise_3_1의 main.cpp
#include "Math.h"
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
Vector2 a, b;
float result;
a = Vector2(2.0f, 4.0f) - Vector2(-1.0f, 1.0f);
b = Vector2(3.0f, 3.0f) - Vector2(-1.0f, 1.0f);
result = Math::Acos(
Vector2::Dot(a, b) /
(a.Length() * b.Length()));
cout << "라디안: " << result << " / " << result / Math::Pi << "π" << endl
<< "도: " << result / Math::Pi * 180 << "°"<< endl;
return 0;
}
출력 결과
라디안: 0.32175 / 0.102416π
도: 18.4349°
연습 3.2
문제
3장 게임 프로젝트는 현재 우주선이 운석과 부딪히지 않는다. 아래의 조건에 맞춰서 운석과 우주선이 충돌하도록 구현하라.
- 조건1:
CircleComponent
를 만들고 반지름을 지정해야한다. - 조건2:
Ship::UpdateActor
에서 모든 운석과의 충돌을 테스트한다. - 조건3: 우주선이 운석과 충돌하면 우주선의 위치를 화면의 중심으로 초기화하고 회전값은 0으로 설정한다.
- 조건4: 추가 기능으로 우주선이 운석과 충돌한 후 1~2초 정도 화면에 출력되지 않게 구현한다.
풀이
Exercise_3_2전체 소스
- 조건1:
CircleComponent
를 만들고 반지름을 지정해야한다.- 3장에서 레이저와 운석의 충돌검사를 하는 코드와 동일하게
Ship
의 생성자에서CircleComponent
를 추가하여서 구현함.
- 3장에서 레이저와 운석의 충돌검사를 하는 코드와 동일하게
Ship.cpp에서 Ship::Ship(Game*)
Ship::Ship(Game* game)
: Actor(game)
{
SpriteComponent* sc = new SpriteComponent(this, 150);
sc->SetTexture(game->GetTexture("../Assets/ShipWithThrust.png"));
// Create InputComponent and set keys/speed
InputComponent* ic = new InputComponent(this);
ic->SetForwardKey(SDL_SCANCODE_W);
ic->SetBackKey(SDL_SCANCODE_S);
ic->SetClockwiseKey(SDL_SCANCODE_A);
ic->SetCounterClockwiseKey(SDL_SCANCODE_D);
ic->SetMaxForwardSpeed(300.0f);
ic->SetMaxAngularSpeed(Math::TwoPi);
// 충돌 검사를 위해서 CircleComponent 추가와 반지름 설정
mCircle = new CircleComponent(this);
mCircle->SetRadius(30.0f);
}
- 조건2:
Ship::UpdateActor
에서 모든 운석과의 충돌을 테스트한다.Ship
의Ship::UpdateActor(float)
에서 모든 운석에 대한 교차검사를 시행한다.- 운석 객체들의 벡터는
GetGame()->GetAsteroids()
를 통해서 가져온다. Intersect()
함수를 통해서 우주선과 운석의 교차여부를 판단하고, 우주선과 운석이 교차한다면 우주선의 상태를EPaused
로 설정하였다.EPaused
로 설정한 이유는 밑에서 설명하겠지만EPaused
로 설정된 엑터는 화면에서 사라지고 나타나도록 구현하기 위함이다. 만약EDead
로 설정할 시 죽은 객체로 간주되어 삭제되어 다시 생성을 해야하는 문제가 생긴다.
- 조건3: 우주선이 운석과 충돌하면 우주선의 위치를 화면의 중심으로 초기화하고 회전값은 0으로 설정한다.
SetPosition()
함수와SetRotation()
위치와 회전값을 초기화 하였다.
- 조건4: 추가 기능으로 우주선이 운석과 충돌한 후 1~2초 정도 화면에 출력되지 않게 구현한다.
- 리스폰 시간을 설정하는 변수
mRespawnTime
은 1.5초로 설정하였다.mRespawnTime
이 양수일 경우 우주선은EPaused
상태를 계속 유지한다. - 이렇게 게임을 하다보면 리스폰 되자마자 우주선이 운석과 충돌하는 다소 짜증나는 상황을 맞이하게 될때가 많다. 문제에서 요구한 것에서 추가적으로 리스폰 후 일정시간 동안 무적상태를 유지할 수 있는 기능을 추가했다.
mInvincibleTime
변수를 통해서 운석과 충돌 후 3.0초 동안은 충돌검사를 하지 않도록 설계하였다. EPaused
상태의 엑터는 화면에 출력되지 않기 위해서SpriteComponent::Draw(SDL_Renderer*)
함수도 일부 수정하였다.- 추가적으로
EPaused
상태에서는 엑터를 조작(움직임, 레이저발사)할 수 없도록InputComponent::ProcessInput(const uint8_t*)
함수를 일부 수정
- 리스폰 시간을 설정하는 변수
Ship.cpp에서 Ship::UpdateActor(float) 전체 수정
void Ship::UpdateActor(float deltaTime)
{
mLaserCooldown -= deltaTime;
mRespawnTime -= deltaTime;
mInvincibleTime -= deltaTime;
// 리스폰 시간이 남아있을 경우 Active 상태가 될 수 없다.
if (mRespawnTime >= 0)
return;
SetState(EActive);
// 부활후 무적시간이 남아있을 경우 운석 교차 검사 안함
if (mInvincibleTime >= 0)
return;
// 운석과 교차여부 검사
for (auto ast : GetGame()->GetAsteroids())
{
if (Intersect(*mCircle, *(ast->GetCircle())))
{
// 우주선과 운석이 교차한다면
// 우주선은 paused 상태로 설정
SetState(EPaused);
SetPosition(Vector2(512.0f, 386.0f));
SetRotation(0.0f);
mRespawnTime = 1.5f;
mInvincibleTime = 3.0f;
break;
}
}
}
SpriteComponent.cpp에서 void SpriteComponent::Draw(SDL_Renderer*) 일부 수정
void SpriteComponent::Draw(SDL_Renderer* renderer)
{
// Actor의 상태가 EActive가 아니 라면 Actor를 그리지 않음.
if (mOwner->GetState() != Actor::EActive)
return;
// ... (이하 동일) ...
InputComponent.cpp에서 void InputComponent::ProcessInput(const uint8_t*) 일부 수정
void InputComponent::ProcessInput(const uint8_t* keyState)
{
// Actor의 상태가 EActive가 아니 라면 입력을 받지 않음.
if (mOwner->GetState() == Actor::EPaused)
return;
// ... (이하 동일) ...
구현 결과물