5.3 로봇 청소기가 장애물을 만난다면? - 조건
벌써 세 번째 예제인 "로봇 청소기" 예제다. 이번 예제는 기존에 사용해 보지 않은 추가적인 Actor 오브젝트의 메소드(행동)가 등장하긴 하지만, 이전 장들에서 배운 기본 원리는 크게 달라지지 않기 때문에 크게 어려움은 없을 것이다.
🔢 먼저, 3-4라인에서 기존(가로 480, 세로 270) 보다 화면크기를 2배로 하였는데, 특별한 이유는 없고, 단지, 실행결과 화면을 크게 보기 위해서이다.
🔢 6번 라인에서 로봇청소기를 화면 중심에 놓기 위해 중심좌표를 가로, 세로길이 절반에 위치하도록 하였다.
🔢 8번 라인에서도 로봇청소기 오브젝트의 최초 각도를 90도로 정한 것으로 최초 실행시 화면 윗방향 쪽으로 움직이게 하기 위한 것이다.
🔢 9번 라인부터는 로봇청소기의 이동흔적을 색칠하기 위한 기본설정을 brush_init 이란 함수(메소드)를 통해 하게 된다. 3가지 인자값(argument값)이 필요한데, 각각은 브러시가 칠해질 전체영역, 굵기, 색깔이 되겠다.
🔢 12번 라인에서 드디어 처음으로 우리 게임에도 게임배경이 등장한다. 개임배경(나무스타일 바닥 이미지)을 그리는 코드인데, screen 이라는 게임화면을 가르키는 내장객체를 사용한다. screen 객체 안에는 이미 내장된 여러가지 함수(메소드)가 존재하는데(상세내용은 파이게임제로 메뉴얼 참조), 그 중에 하나가 화면에 직접 이미지를 출력할 수 있는 blit 이라는 함수(메소드)를 사용해 좌표(0, 0)부터 시작하는 마루바닥 이미지를 출력하였다.
🔢 13-14번 라인의 순서는 중요한데, 누구를 먼저 그리냐에 따라, 청소기 위쪽으로 이동경로 칠해져 보여질 수 있으므로, 이동경로를 칠하고, 그 위에 청소기를 그리는 순서가 자연스럽다 할 수 있겠다.
🔢 16번 라인에서 등장하는 update 콜백함수는 거대 게임루프 구조를 구성하는 주요 함수로서 게임에서 계속적으로 변화하거나(Actor 오브젝트가 움직이는 경우 등), 계속적으로 확인해야 하는 내용(어떤 키보드, 마우스 키가 눌렸는지 등)에 대한 코드를 적는 부분이다. 따라서, 로봇청소기가 매번 10 크기만큼의 반복이동을 위해 17번 라인에 forward(10) 을 사용해 반복적인 움직임을 만들고 있다.
🔢 마지막으로 19번 이후의 코드는 조건문으로 로봇청소기 게임화면 끝에 도달했을 때의 행동에 대해 기술한 것으로, 이 부분은 기존의 엔트리 코딩과는 조금 다른 개념이 적용되니 주의가 필요한 부분이다. 기존에 엔트리에서는 게임화면의 경계선을 벽(wall)이라고 지칭하며 마치 화면 벽(wall)을 오브젝트처럼 다루는데 벽의 경계면에서 다른 오브젝트가 서로 닿았는가(출동했는가)라는 오브젝트 간의 충돌검사 방식을 사용했다. 그러나, 파이게임제로에는 게임화면 경계면 자체는 어떠한 오브젝트가 아니다. 그래서, 화면 경계에 도달했는지에 대한 검사를 현재 끊임없이 이동 중인 로봇청소기의 현재 위치를 통해 파악한다.
예들들어 robot.top 값이 0보다 작아졌다는 것은 로봇청소기 객체가 게임화면 상단을 넘어서기 시작하는 시점이며, robot.right 값이 전체화면의 가로크기보다 커지는 시점은 게임화면 최우측을 넘어서기 시작하는 시점인 것이다. 이 때, 로봇청소기를 약간(10크기 만큼) 뒤로 후진시킨 후에 방향전환을 시도하고 있음을 유념하도록 하자. 이런식의 알고리즘이 필요한 이유는 스크린의 가장자리에 도달했을 때 곧바로 방향전환을 시도했으나 때때로 방향전환된 그 순간조차도 여전히 화면 끝에 도달한 것으로 연달아 판별되면서 계속 방향전환만 시도하다가 결국에는 다른 방향으로 이동해 빠져나가지 못하고 제자리에서 가만히 공회전만 하는 경우가 발생할 수 있는데 이를 막기 위해 의도적으로 약간 후진 후 방향전환을 시도하고 있다.
참고로 19번 라인 끝에 '\'의 표현이 궁금한 분들이 있을 것 같다. 19-20번의 두 라인(행)에 걸쳐있는 코드는 본래 19번 라인 한 행에 길게 다 코딩되어야 하는 것이었다. 그러나, 저자는 이를 의도적으로 두 라인(행)으로 분리했는데, 코드를 읽을 때 빠르고 직관적으로 읽을 수 있게 즉, 코드 가독성을 높히기 위한 의도적인 코딩이다. 그런데, 코딩에서는 이렇게 원래 한 라인의 긴 코드를 여러 라인에 걸쳐 코딩하고자 할 경우, 나누고자 하는 행의 끝 부분에 '\' 기호를 둠으로써 이 행은 완전히 끝난게 아니라 다음 행과 연결되어 진다는 표시를 반드시 해두어야만 하는 것이다.
마지막으로 해당 로봇청소기의 최종 실행결과를 보는 것으로 본 장을 마무리 하겠다.
Last updated