강의, 책 41

[슈팅 알고리즘] 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..

#6. Effects

Effect 특정 코드들이 처음 컴포넌트를 렌더링 할 때에만 실행되고, state가 변경되어 리렌더링 할 때에는 실행되지 않게 하기 위해 사용할 수 있다 function App() { const [counter, setValue] = useState(0); const onClick = () => setValue((prev) => prev + 1); useEffect(() => { console.log("Call the API."); }, []); return ( {counter} click me ); } 위와 같이 useEffect의 첫번째 argument에 함수를 넣어두면, 첫번째 render 시점에만 동작하고, state가 변경되어 리렌더링되어도 여러 번 실행되지 않는다 딱 한 번만 실행되는 것이다 ..

#4. Props

Props * Props: 부모 컴포넌트로부터 자식 컴포넌트에 데이터를 보낼 수 있게 해주는 방법(인자) function SaveBtn() { return Save Changes; } function ConfirmBtn() { return Confirm; } function App() { return ( ); } 기존의 방식대로라면 버튼을 여러 개 만들 때, 각각 컴포넌트로 만들어주어서 렌더링한다 하지만 각각의 버튼에 공통된 속성들(ex. style)이 들어간다고 가정한다면, 하나의 수정사항이 생길 때마다 모든 버튼 컴포넌트를 수정해야 하는 문제가 생긴다 function Btn(props) { return ( {props.text} ; } function App() { return ( ); } 직접 생성..