5.7 두더지 게임을 만들어요 - 종합
드디어 이 책의 마지막 예제에 도달한 여러분을 환영한다. 이전 예제들을 격파하고 여기까지 온 여러분들은 파이썬 코딩의 재미도 서서히 느끼고 있을 것이라 생각한다. 생각보다 텍스트코딩이 많이 어렵거나 지루하지는 않을 것으로 믿는다. 그렇다면 여러분들은 이 책이 목표했던 텍스트 코딩세계 입문이라는 소기의 목적을 충분히 얻은 것으로 여겨도 좋겠다.
마지막 예제는 지금까지 예제의 종합판이라 이전 예제보다는 확실히 난이도가 있다. 하지만, 시간이 걸릴 뿐 차근차근 이해해 나가면 될 것이다.
🔢 엔트리버전 두더지 잡기게임과 다른 점이 하나 있는데, 엔트리 버전에서는 두더지들의 위치는 고정이나, 파이게임제로 버전에서는 두더지의 위치가 초기에 랜덤(무작위, random)하게 설정된다는 것이다. 먼저 랜덤을 활용 하기 위해선 random 이란 별도의 외부 모듈이 필요하고, 따라서 2번 라인에서 해당 모듈을 import하고 있다. 14-24라인까지의 코드가 화면상에 램덤하게 위치시킬 총 6개의 두더지 Actor 오브젝트들을 만들고, 이 만들어진 6개를 moles 라는 리스트에 담아서 활용한다.
19-20 라인에서 사용한 randint 라는 메소드는 엔트리에서 사용해봤던 "무작위 수" 블록과 크게 다르지는 않다. 특정범위에 랜덤한 숫자를 무작위 선택하기 위한 범위의 최대/최소값을 인자값으로 전달해야 한다. 다만, 메소드 이름에 int(integer, 정수)가 포함되어 있는 것으로 통해 정수형 숫자범위에서 선택한다는 것에 주의하다. 참고로 만약 실수형(float, 실수)의 랜덤값이 필요한 경우에는 쉽게 예상할 수 있는데 randfloat 라는 메소드를 사용하면 된다.
randint 메소드로 전달하는 최초/최대값에는 GAP_FROM_SCR 이란 이름으로 50 픽셀의 여분(마진, margin)값을 사용하고 있는데, 목적은 다른게 아니라 랜덤하게 위치선정 할 때, 게임화면 테두리에 딱 붙어서 위치선정 되버린 경우, 출력된 두더지 이미지가 화면끝에 걸처 짤려보이거나 하는 문제를 막기 위해 화면 테두리로부터 50픽셀씩 안쪽으로 들어와서 랜덤위치값을 찾도록 그 여분값을 준 것이다.
23번 라인에 visible 이란 처음 등장한 객체속성을 사용하고 있는데, 이 속성은 Actor 객체에 내장속성이 아니다. 우리의 게임개발에 필요해서 임의의 추가한 우리만의 사용자 속성이다. 이처럼 여러분들도 필요하면 기존 객체안에 임의로 속성을 추가할 수도 있다는 것도 기억해 두자. 목적은 두더지 게임 특성상 어떤 두더지는 화면에 보이고/안보이고의 구분이 필요한데 이를 구분하기 위한 지난 장에서 언급해선 일종의 플래그변수와 같은 것이다.
🔢 게임의 재미를 위해선 임의의 두더지의 보이고/안보이고 하는 시점도 랜덤화가 필요하다. 이를 구현한 코드가 update 함수 안에 44-47번 라인의 코드이다. 우리는 게임에 사용되는 객체들의 위치, 상태 등의 정보를 업데이트하는 update 콜랙함수가 상당히 자주 호출된다는 것은 알고 있는데, 얼마나 자주인지는 잘 모르고 있었다. 드디어 그 속도를 언급할 필요가 있는데, 초당 60프레임의 속도(60FPS(Frame Per Second))로 무려 초당 60회로 상당히 빠르게 자주 콜백호출되고 있다. 문젠 60fps 속도는 우리에겐 너무 빠르다는 것인데, 지나치게 빠르지도 느리지도 않는 게임의 재미를 충족시킬 수 있는 정도의 속도 안에서 살아있는(아직 게임유저가 때려잡지 못한) 두더지들 중 랜덤하게 선택해서 보였다/숨겼다 하는게 필요하다. 그 어느정도의 속도(0~10사이값 중 0이 선택되는 경우마다)는 44라인에서 구현하였고, 살아있는 두더지들 중에 1개를 임의로 택하는 것은 random.sample 메소드와 함께 45-46라인까지 구현되었고, 47번 라인에서는 선택된 두더지의 가시성 속성(visible)을 반전시킴으로써 보이고/안보이고를 조정하고 있다.
🔢 이제 남은 코드의 상당 수는 고무망치의 애니메이션에 관한 부분이다. 지난 예제에서의 애니메이션이 한 Actor 안에 여러 이미지들의 로테이션에 의한 애니메이션이라면 이번 애니메이션은 현재 위치에서 특정 위치나 각도까지 정해진 시간 안에 이동하는 애니메이션에 관한 것이다. 고무망치는 마우스 클릭한 시점에 맞춰 고무망치가 때리는 시늉을 위해 앞쪽으로 어느정도 각도(75도)로 빠르게 기우려졌다가 다시 현재각도(40도)의 모습으로 빠르게 되돌아 와야 한다. 59번 라인의 animate 메소드의 사용이 처음 등장했고, 총 5개의 인자값을 사용했는데 정리하면 어떤 객체(여기서는 hammer)의 어떤 속성(여기서는 angle)을 얼마만의 시간(여기서는 0.1초)안에 어떤 종류(여기서는 accelerate)의 애니메이션을 할 것인가에 관한 것이다. 애니메이션의 종류로 accelerate 은 애니메이션 속도가 시간이 지나면서 가속화되는 것을 연출하는 애니메이션이다. 그 종류는 총 10가지가 준비되어 있고, 각각에 대해서는 역시나 라이브러리 메뉴얼을 통해 확인이 가능하다. 인자값 중에 마지막 값인 on_finished 의 파라미터값에 대해서도 궁금할 것이다. animation_done 이란 62번 라인에서 정의한 함수이름을 넘기고 있다. 그렇다 해당 파라미터값의 이름처럼 애니매이션이 종료된 시점에 인자값으로 넘긴 함수를 콜백호출 해주라는 것이다. 목적은 여러가지가 있을 수 있는데, 우리의 목적은 고무망치가 숙여지는 애니매이션이 끝나자마자 다시 현재 위치로 원복하는 애니메이션을 연이어서 하도록 하려는 것이다.
🔢 우리는 사용자가 두더지를 때려잡은 시점에 대한 파악은 어떻게 해야 할까? 34번 라인에 그 해답이 있다. 3가지 조건이 다 만족되어야만 한다. 고무망치 애니메이션이 앞쪽으로 숙여지는 중이어야 하고(숙여진 고무망치가 들어올려지는 동안이 아닌), 두더지는 숨겨진 상태가 아닌 화면에 보여지는 상태여야 하며, 마지막으로 고무망치와 두더지 사이에 상호간의 충돌검사가 통과하는 이 3가지가 다 만족해야만 두더지를 때려잡은 것이다. 때려잡기에 성공했기 때문에 성공의 의미로 효과음을 내고(35라인) 잡은 두더지는 두더지들의 모음인 moles 리스트에서 없에버리고(36라인), 마지막으로 획득한 점수를 카운트 해주면 된다.(37라인)
이것으로 두더지게임의 모든 코드설명이 끝났고, 마지막으로 게임실행 결과를 보는 것으로 마무리 하자.
Last updated