ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 벡터를 활용한 미사일을 날리기 - Cocos2D를 활용
    Algorithm with C/Math 2021. 4. 6. 19:39

    개발 환경은 cocos2d-1.0.0-x-0.9.0 와 Visual Studio 2008

    cocos2d는 Win API와는 달리, 좌표계가 좌측하단이 원점이다.

    우리가 보편적으로 쓰는 좌표계와 같다.

     

    물체를 이동시킬 때는 이동 방향 벡터를 활용해서 처리할 수 있다.

    즉, 물체의 위치와 이동 방향 벡터의 단위 벡터의 합으로 물체의 위치를 이동시킬 수 있다.

    이동 방향 벡터는 아래와 같이 구할 수 있다.

    그리고 이 이동 방향 벡터는 통상적으로 단위 벡터화를 하도록 한다.

     

     위의 이동 방향 벡터를 단위 벡터화를 하면 아래와 같은 그림이 된다.

     

    그리고, 이 미사일을 타겟의 방향으로 회전시킬 수 있는데, 이는 이 이동 방향 벡터를 통해 처리할 수 있다.

    그리고 물체의 이동은 기존의 미사일 위치에 이 이동 벡터에 적당한 비례상수를 곱해 더해서

    미사일의 이동할 위치를 구할 수 있다.

     

    즉, 전체적으로 미사일의 위치에서 타겟까지의 경로를 이동 방향 벡터로 표현하면 다음과 같다.

    이동 방향 벡터는 미사일의 위치에서 타겟의 위치롤 통해 계속 구한다.

    즉, 미사일의 위치를 이동시키고 다시 이동한 위치에서 타겟 까지의 거리를 확인하고 다시 구한다.

    그리고, 이동 방향 벡터를 결정하면, 미사일이 타겟 위치로 나아갈 방향(각도) 도 계속 구해서 회전 시킨다. 

    아래의 그림을 다시 한 번 참고 하자.

    각도는 이동 방향 벡터의 x성분과 이동 방향 벡터의 y성분을 이용해 계속 구하면 된다.

    아래의 노란색 벡터가 이 이동 방향 벡터의 x축 벡터이다.

    아래의 그림을 다시 한 번 보도록 하자.

    이는 이동 방향 벡터를 통해 미사일이 타겟쪽으로 회전을 하면서 이동을 하는 최종적인 모습이 된다.

     

    위의 내용을 프로그래밍을 하면, 아래의 두 함수가 필요하다.

    MissileAction 함수와 SetMissileVector 함수이다.

    atan2함수는 반환값이 라디언이므로 이를 각도로 변환이 필요하다.

    그 이유는 setRotation 함수는 각도를 요구하기 때문이다.

     

     

     

    아래는 초기화를 하는 내용으로, 기본적인 내용을 초기화를 하고

    그 이후에 미사일의 이동 방향 벡터를 설정한다.

     

    프로그램 실행영상

    아래의 영상에서 맨 마지막 부분에서 미사일이 부들부들 떠는 이유는

    이동 방향 벡터 때문이다.

    그 이유는 미사일과 타겟이 가까워지면 이동 방향 벡터의 x성분과 y성분은 당연히 0에 가까워진다.

    그렇기 때문에 아래와 같이 부들부들 떠는 모습이 나온다.

     

     

     

    이번에는 충돌 체크에 따라 타겟을 이동시키는 로직을 만들어 보자.

    충돌이 된 경우에는 타겟을 미사일의 발사한 방향으로 밀려나가게 만들어 보자.

    아래와 같이 타겟과 미사일이 충돌이 되었다고 하자.

     

    아래의 그림은 충돌하고 나서, 타겟을 미사일이 날아온 방향으로 타겟을 밀어낼 그림이다.

    여기서 유심히 볼 부분은 튕겨져 나가는 방향 벡터의 화살표의 길이이다.

    즉, 처음에 튕길 때는 크게 튕기고 나서, 그 이후에는 서서히 감소 시킬 것이다.

     

    아래의 함수는 미사일과 타겟 간의 충돌 체크를 판정하는 함수인데,

    이는 가장 간단한 방법인 거리로 확인을 한다.

     

    충돌 혹은 비 충돌의 경우로 나뉘는데, 비 충돌인 경우에는 타겟은 가만히 있고

    충돌인 경우에는 미사일이 날라온 방향으로 타겟을 이동시킨다.

    충돌하면 미사일이 날라온 방향으로 한 번만 타겟을 이동시킬 수도 있으나,

    튕겨져 나가는 회수를 주면 좀 더 다이나믹하게 구현할 수 있다.

    그러기 위해서 클래스 변수로 m_fPullPower와 m_fResist 을 선언을 하였다.

    m_fPullPower 변수를 이용해서 만약 100만큼 타겟의 위치를 옮겼다면

    그 다음 번에 타겟을 이동시킬 때는 50만큼 이동시키고

    그 다음에는 10만큼 이동 시키는 로직이 만들어 진다.

    즉, 충돌 시에 갈수록 천천히 튕겨져 나가는 로직임을 알 수 있다.

    m_fPullPower 가 0이하가 되면, 모든 튕김이 끝난 것이므로 다시 초기 설정을 주도록 한다.

    m_fResist 는 일종의 비례 상수 값으로 이 값을 적당히 조절해서 알아서 쓰도록 하자.

     

    그리고 아래는 위의 두 함수들을 호출하는 부분이다.

     

    아래에서 이 기능들을 추가적으로 구현하기 위해 필요한 클래스 변수들을 정의하고 초기화하는 부분이다.

     

    프로그램 실행영상

     

     

     

    이번에는 약간 번외편이긴 한데, 미사일을 좀 더 다이나믹하게 움직이도록 만들어보자.

    다음과 같이 미사일의 위치에서 타겟 까지로 이동한다고 가정하자.

    그러면 이에 따라 미사일의 이동 방향 벡터의 구할 수 있다고 하자.

     

    위에서 미사일을 이동 방향 벡터 방향으로 움직였다고 하자. 그러면 아래와 같은 그림이 된다.

     

    이동 방향 벡터를 통해 아래와 같은 그림을 다시 그려 볼 수 있다.

    즉, 이동 방향 벡터로 알아낼 수 있는 정보는 아래의 각도 theta 이다.

    이 theta를 기반으로 x축과 y축으로의 벡터를 알아 낼 수 있다.

    x축으로의 방향은 cosine(theta)이고, y축으로의 방향은 sine(theta)이다.

    이 벡터에 적당한 크기인 scala를 곱해주면, 해당 방향으로의 적당한 크기를 갖는 벡터를 만들 수 있다.

     

    위의 그림을 바탕으로, 미사일의 위치를 좀 더 다이나믹하게 이동시킬 수 있다.

     

    위의 내용을 기반으로 하는 미사일의 다이나믹한 이동을 구현해 보자.

     

    위의 함수의 호출은 Update 함수에서 호출한다.

     

    프로그램 실행영상

     

     

    소스 파일 및 이미지 파일

    AppDelegate.cpp
    0.00MB
    AppDelegate.h
    0.00MB
    HelloWorldScene.cpp
    0.01MB
    HelloWorldScene.h
    0.00MB
    missile.png
    0.00MB
    target.png
    0.00MB

    댓글

Designed by Tistory.