강의, 책/[DirectX, C++] 게임 매니악스 알고리즘 시리즈 8

[슈팅 알고리즘] Chapter 2. 탄환 (유도 레이저)

2.13 유도 레이저 유도 레이저는 유도탄을 응용하여 만들 수 있으며, 실제로 가장 선두의 움직임은 유도탄의 움직임과 같다. 단, 유도 레이저에는 꼬리가 존재하며 꼬리들은 각자 자신의 바로 앞부분의 좌표를 향해 앞부분의 회전각도로 이동하게 된다. // 레이저의 각부분을 나타내는 구조체 typedef struct LASER_STRUCT { float X, Y; // 좌표 float VX, VY; // 속도 float OldX, OldY; // 이전 좌표 float Angle; // 회전 각도 float OldAngle; // 이전 회전 각도 struct LASER_STRUCT* Prec; // 하나 앞 부분을 가리키는 포인터 // (선두부분일 경우는 NULL) } LASER_TYPE; void MoveHo..

[슈팅 알고리즘] Chapter 2. 탄환 (유도탄)

2.12 유도탄 유도탄은 메인 캐릭터를 향해 직진하는 탄환과 달리, 발사된 후에도 방향을 바꿔가며 메인 캐릭터를 쫓아오는 탄환이다 void MoveSimpleHomingBullet( float& x, float& y, // 탄환의 좌표 float mx, float my, // 메인 캐릭터의 좌표 float speed // 탄환의 속도 ) { // 목표까지의 거리 d 구하기 float d = sqrt((mx - x) * (mx - x) + (my - y) * (my - y)); // 속도가 일정한 값(speed)가 되도록 float vx, vy; // 탄환의 속도 벡터 if (d) { vx = (mx - x) / d * speed; vy = (my - y) / d * speed; } else { // 목표..

[슈팅 알고리즘] Chapter 2. 탄환 (분열탄)

2.11 분열탄 분열탄은 처음에는 하나의 탄환으로 발사되었다가 도중에 여러 개로 분열되는 탄환을 말한다 (느리고 큰 탄환 → 작고 빠른 탄환 여러 개로 분열) 분열탄은 조준탄과 n-way 탄을 조합하여 만들거나 방향탄과 n-way 탄을 조합하여 만들 수 있다 처음에 하나의 탄환을 발사하여 일정 시간 동안 이동시키다가, 그 탄환을 삭제하고 해당 위치에서 n-way탄을 발사하면 된다 * tip. 분열탄을 사용할 때에는 딱 봐도 분열할 것 같은 분위기를 연출해주는 것이 좋다. 플레이어 입장에서 전혀 분열할 것 같지 않던 탄환이 갑자기 분열하면 재미보단 스트레스를 받기 때문

[슈팅 알고리즘] Chapter 2. 탄환 (원형탄)

2.10 원형탄 360도 전 방향으로 탄환을 발사하는 원형탄을 구현할 때에도 방향탄을 응용하면 된다 void InitCircleBullets( int n, // 탄환의 수 float speed, // 탄환의 속도 bool odd, // 홀수 패턴일 때: true float vx[], float vy[] // 원형탄의 속도 벡터 ) { // 탄환과 탄환 사이의 각도를 계산하기 float rad_step = M_PI * 2 / n; // 최초의 탄환의 각도를 계산하기 // 홀수 패턴일 경우 0에서 rad_step/2만큼 회전해 줌 float rad = odd ? rad_step / 2 : 0; // speed의 속도로 각도 rad 방향으로 날아가는 탄환의 속도 벡터 구하기 for (int i = 0; i <..

[슈팅 알고리즘] Chapter 2. 탄환 (n-way탄)

2.9 n-way탄 n-way탄이란 부채꼴 모양으로 발사되는 탄환을 말한다 이를 발사하기 위해서는 방향탄을 응용하여, 중심선을 향해 날아가는 탄환을 기준으로 θ만큼 틀어가며 발사하면 된다 void RotateVelocity( float theta, // 회전각도 float vx0, float vy0, // 원래 속도 float& vx, float& vy // 회전 후의 속도 ) { // theta를 라디안으로 변환하여 cos과 sin값 구하기 // -> 삼각함수의 인자로 라디안을 전달해야 하기 때문 float rad = M_PI / 180 * theta; float c = cos(rad), s = sin(rad); // 속도 벡터(vx0, vy0)을 회전시킨 (vx, vy) 구하기 vx = vx0 * c..

[슈팅 알고리즘] Chapter 2. 탄환 (탄환의 위치)

2.7 탄환을 제거하기 탄환의 좌측 상단 좌표를 (x0, y0), 우측 하단의 좌표를 (x1, y1)이라고 하고, 화면 테두리의 좌측 상단 좌표를 (sx0, sy0), 우측 하단의 좌표를 (sx1, sy1)이라고 했을 때 탄환이 화면 밖으로 빠져나갔는지 여부를 확인하는 방법은 아래와 같다 // 탄환이 완전히 화면 밖에 있을 조건 (x1 < sx0 || sx1

[슈팅 알고리즘] Chapter 2. 탄환 (방향탄)

2.4 방향탄 조준탄과 달리 특정 캐릭터를 향해 날아가는 게 아니라 임의의 방향으로 날아가는 탄환 void InitDirectedBullet() { // M_PI: 원주율 vx = cos(M_PI / 180 * theta) * speed; vy = sin(M_PI / 180 * theta) * speed; } 위 공식을 이용하여 각도를 가지고 탄환의 속도 벡터(방향)을 구할 수 있다 탄환을 발사할 때는 위에서 구한 속도 벡터를 좌표에 더해주면 된다 2.5 테이블을 이용한 방향탄 2.4에서는 실수형 데이터를 사용하였는데, 방향 벡터 테이블을 미리 만들어 발사하는 방법을 사용할 수도 있다 // 3의 속도로 16방향으로 향하는 방향탄 void InitDirectedBullet16_3( float& vx, fl..

[슈팅 알고리즘] Chapter 2. 탄환 (조준탄)

2.1 조준탄 (float를 이용해서 탄환을 이동) 적기에서 플레이어의 위치를 향해 발사하는 조준탄 void InitAimingBullet( float mx, float my, // 플레이어 위치 float ex, float ey, // 적 위치 float speed, float& x, float& y, // 탄환 좌표 float& vx, float& vy // 탄환 속도 벡터 ) { x = ex; y = ey; // 플레이어와 적 사이의 거리 float d = sqrt((mx - ex) * (mx - ex) + (my - ey) * (my - ey)); if (d == 0) { vx = 0; vy = speed; } else { vx = (mx - ex) / d * speed; vy = (my - ey..