로그인

검색

MoA
조회 수 1775 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 게시글 수정 내역 댓글로 가기 인쇄 첨부
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 게시글 수정 내역 댓글로 가기 인쇄 첨부

먼저 간단한 삼각함수부터 생각하자. 아래 삼각형에서 각 A는 어떻게 구할까?

 

triangle.png

 

답은 간단하다 atan ( BC / AB ) 값을 구하면 된다. 그러므로 플레이어를 C로 바라보게 하려면 atan (BC / AB) 값 만큼 회전 시키면 된다. 선분 AB를 기준으로 하였을 때 점 C의 반대편으로 바라보게 하려면 atan (BC / AB) 의 마이너스 값만큼 회전 시키면 된다. 만약 A 위치를 원점으로 놓고 B는 (x, 0), C는 (x, y)로 놓는 다면 점 C'의 위치는 (x, -y)가 된다. atan ( y/x ) = - atan ( -y/x ) 이므로 플레이어를 회전할 각은 atan ( y/x )로 계산하면 될 것 같다.

 

하지만 다음 그림에서 점 C 방향으로 보게하려면 어떻게 계산해야할까?

 

triangle2.png

 

점 C의 좌표는 (-x, y)이다. 위에서처럼 atan ( y / (-x) )로 계산하면 atan ( -y / x ) 와 같은 값을 같게 된다. 예를 들어 x = 1, y = 1라면 두 경우 모두 atan ( -1 ) = -45도가 되어 버린다.

 

이를 위해 프로그래밍 언어에서는 보통 atan2 ( y, x ) 함수를 제공한다. 이는 x, y 각각의 부호를 판별하여 각도를 계산하게 해준다. 즉 atan2 ( -1, 1 )을 계산하면 -45도, atan2 ( 1, -1 )을 계산하면 135도가 된다.

 

이를 이용하여 플레이어를 회전시켜 보자. screen.blit(player, playerpos) 부분을 아래와 같이 바꾼다.

 

# 6.1 - 플레이어를 회전시킨다.
    mousepos= pygame.mouse.get_pos()
    angle = math.atan2(-mousepos[1]+(playerpos[1]),mousepos[0]-(playerpos[0]))
    rotPlayer = pygame.transform.rotate(player, angle*57.29)
    screen.blit(rotPlayer, playerpos)

mousepos에는 mouse.get_pos() 함수로 마우스의 좌표가 얻어진다. 두 번째 줄은 atan2( y, x )를 계산하는데 플레이어 좌표를 기준으로 계산해야 하므로 atan2 ( mouse y좌표 - player y좌표 , mouse x좌표 - player x 좌표 ) 를 계산한 것이다. 그런데 화면의 좌표는 아래 방향으로 y값이 증가하므로 (mouse y좌표 - player y좌표) 부호가 반대로 바뀌어야 한다.

 

이렇게 하여 계산된 angle값은 라디안 값이므로 degree (도)로 바꾸려면 angle * 180.0 / 3.14 = angle * 57.29를 계산하면 된다. 세 번째 줄은 이 값을 계산하여 player를 회전시킨 것이다. 그리고 회전된 player 이미지는 rotPlayer 이미지로 바뀌고 이를 playerpos 위치에 그렸다.

 

여기서 한가지 더 문제가 있다. 플레이어를 회전시키면 아래와 같이 이미지 크기가 변한다.

 

rotPlayer.png

 

회전 시켰더니 이미지 크기가 커졌다. 그리고 이미지는 왼쪽 위 좌표를 기준으로 그려지는데 이 또한 바뀌었다. 그런데 왼쪽 위 좌표를 항상 (100, 100) 위치시키면 player 위치가 이상하게 변한다. (직접 실행해서 확인해보라) 플레이어를 자연스럽게 회전시키려면 이미지의 중심 좌표를 기준으로 회전시켜야 한다. 이를 반대로 하여 회전시킨 후 중심 좌표를 똑같게 만들어도 된다. 이미지의 중심 좌표는 왼쪽 위 꼭지점에서 (이미지 가로크기/2 , 이미지 세로크기/2 ) 만큼 이동한 위치이므로 이 중심좌표를 왼쪽위 꼭지점으로 옮기게 하려면 다음과 같이 하면 된다.

 

    # 6.1 - 플레이어를 회전시킨다.
    mousepos = pygame.mouse.get_pos()
    angle = math.atan2(-mousepos[1]+(playerpos[1]),mousepos[0]-(playerpos[0]))
    rotPlayer = pygame.transform.rotate(player, angle*57.29)
    playerRotPos = (playerpos[0]-rotPlayer.get_rect().width/2, playerpos[1]-rotPlayer.get_rect().height/2)
    screen.blit(rotPlayer, playerRotPos)

직접 실행해보고 결과를 확인해 보길 바란다.

 

덧1 : 나의 경우엔 y좌표 부호를 반대로 하여 계산하였는데 취향에 따라 y 부호는 그대로 하고 rotation 시킬 때 반대로 회전시킬 수도 있다. 하지만 수학 공부 좀 한 사람에게는 계산이 많아지면 더 헷갈릴 수도 있다.

덧2 : 13살짜리가 탄젠트 역함수, 라디안도 암 ㄷㄷㄷ

 

 

?

  1. Programming 게시판 관련

  2. [GUI] Tkinter, wxPython

  3. [첫게임 만들기] 9. 사운드

  4. [첫게임 만들기] 8. Win or Lose

  5. [첫게임 만들기] 7. 게임 정보 표시

  6. [첫게임 만들기] 6. 적을 해치우자

  7. [첫게임 만들기] 5. 적을 생성하자

  8. Simple Add-On Wait Dialog in MFC

  9. [첫게임 만들기] 4. 화살을 발사해보자

  10. [첫게임 만들기] 3. Bunny를 회전시키자

  11. [첫게임 만들기] 2. 배경 그리기, Bunny 움직이게 하기

  12. [첫게임 만들기] 1. 게임 소개 및 실습 준비

  13. 고양이 밖으로 못나가게 하기

  14. 고양이 움직이기

  15. CSS, 자바스크립트 강좌

  16. 슬라이더 컨트롤에 툴팁 삽입 (동적 툴팁)

  17. 태스크 대화상자 (Task Dialog)

  18. 프린터 출력하기

  19. Flash CS5 and Version Control

  20. AS3 Code Library

  21. 영상 처리 관련 블로그

Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 11 ... 15 Next
/ 15