메뉴 건너뛰기

OBG

Programming

MoA
조회 수 1009 추천 수 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살짜리가 탄젠트 역함수, 라디안도 암 ㄷㄷㄷ

 

 

?

List of Articles
번호 분류 제목 글쓴이 날짜 조회 수
공지 Tool/etc Programming 게시판 관련 2 MoA 2014.11.01 1708
43 Python [액션게임 만들기] 3. 클래스 다이어그램 기초 file OBG 2014.05.07 2769
42 Python [농장게임 만들기] 10. 상점을 추가하자 file MoA 2014.05.01 2671
41 Python [농장게임 만들기] 3. 배경을 그리자 6 file MoA 2014.04.28 2066
40 Python 파이썬에서 C모듈 사용하기 MoA 2014.02.10 1919
39 Python [농장게임 만들기] 1. Nubcake Farms 게임 소개 4 file OBG 2014.04.26 1588
38 Python [게임 만들기] 강좌 진행 예정 2 MoA 2014.04.26 1463
37 Python OpenCV 이용한 템플릿 매칭 MoA 2014.01.16 1250
36 Python [첫게임 만들기] 7. 게임 정보 표시 file MoA 2013.11.21 1035
» Python [첫게임 만들기] 3. Bunny를 회전시키자 file MoA 2013.11.21 1009
34 Python 화면 캡쳐 소스 MoA 2014.01.14 973
33 Python [액션게임 만들기] 2. 클래스 분석 file OBG 2014.05.06 968
32 Python [첫게임 만들기] 1. 게임 소개 및 실습 준비 1 file MoA 2013.11.20 908
31 Python [액션게임 만들기] 1. Street Pyghter 게임 소개 3 file OBG 2014.05.03 890
30 Python 고양이 움직이기 1 file MoA 2013.11.08 839
29 Python [농장게임 만들기] 6. 나머지 오브젝트를 그리자 1 file MoA 2014.05.01 758
28 Python [농장게임 만들기] 2. Nubcake Farms 클래스 분석 3 file OBG 2014.04.26 715
27 Python [농장게임 만들기] 8. HUD에 텍스트를 표시하자 file MoA 2014.05.01 677
26 Python [액션게임 만들기] 4. 캐릭터 선택 화면 file OBG 2014.05.07 674
25 Python [첫게임 만들기] 4. 화살을 발사해보자 file MoA 2013.11.21 674
24 Python [GUI] wxPython 기본 프로그램 file MoA 2013.11.30 660
Board Pagination Prev 1 2 ... 3 Next
/ 3
위로