# 5.3 로봇 청소기가 장애물을 만난다면? - 조건

벌써 세 번째 예제인 "로봇 청소기" 예제다. 이번 예제는 기존에 사용해 보지 않은 추가적인 Actor 오브젝트의 메소드(행동)가 등장하긴 하지만, 이전 장들에서 배운 기본 원리는 크게 달라지지 않기 때문에 크게 어려움은 없을 것이다.

{% code lineNumbers="true" %}
```python
from pgzhelper import *

WIDTH = 960
HEIGHT = 540

robot = Actor('cleaner', (WIDTH / 2, HEIGHT / 2))
robot.scale = 0.3
robot.angle = 90
robot.brush_init((WIDTH, HEIGHT), 50, 'white')

def draw():
    screen.blit('floor', (0, 0))
    robot.brush_draw()
    robot.draw()

def update():
    robot.move_forward(10)

    if robot.top < 0 or robot.right > WIDTH \
        or robot.bottom > HEIGHT or robot.left < 0:
        robot.move_back(10)
        robot.angle += 133
```
{% endcode %}

🔢 먼저, 3-4라인에서 기존(가로 480, 세로 270) 보다 화면크기를 2배로 하였는데, 특별한 이유는 없고, 단지, 실행결과 화면을 크게 보기 위해서이다.

🔢 6번 라인에서 로봇청소기를 화면 중심에 놓기 위해 중심좌표를 가로, 세로길이 절반에 위치하도록 하였다.

🔢 8번 라인에서도 로봇청소기 오브젝트의 최초 각도를 90도로 정한 것으로 최초 실행시 화면 윗방향 쪽으로 움직이게 하기 위한 것이다.

🔢 9번 라인부터는 로봇청소기의 이동흔적을 색칠하기 위한 기본설정을 **brush\_init** 이란 함수(메소드)를 통해 하게 된다. 3가지 인자값(argument값)이 필요한데, 각각은 브러시가 칠해질 전체영역, 굵기, 색깔이 되겠다.

🔢 12번 라인에서 드디어 처음으로 우리 게임에도 게임배경이 등장한다. 개임배경(나무스타일 바닥 이미지)을 그리는 코드인데, **screen** 이라는 게임화면을 가르키는 내장객체를 사용한다. screen 객체 안에는 이미 내장된 여러가지 함수(메소드)가 존재하는데([상세내용](https://pygame-zero.readthedocs.io/en/stable/builtins.html#screen)은 파이게임제로 메뉴얼 참조), 그 중에 하나가 화면에 직접 이미지를 출력할 수 있는 **blit** 이라는 함수(메소드)를 사용해 좌표(0, 0)부터 시작하는 마루바닥 이미지를 출력하였다.

🔢 13-14번 라인의 순서는 중요한데, 누구를 먼저 그리냐에 따라, 청소기 위쪽으로 이동경로 칠해져 보여질 수 있으므로, 이동경로를 칠하고, 그 위에 청소기를 그리는 순서가 자연스럽다 할 수 있겠다.&#x20;

🔢 16번 라인에서 등장하는 **update** **콜백함수는 거대 게임루프 구조를 구성하는 주요 함수로서 게임에서 계속적으로 변화하거나(Actor 오브젝트가 움직이는 경우 등), 계속적으로 확인해야 하는 내용(어떤 키보드, 마우스 키가 눌렸는지 등)에 대한 코드를 적는 부분이다.** 따라서, 로봇청소기가 매번 10 크기만큼의 반복이동을 위해 17번 라인에 **forward(10)** 을 사용해 반복적인 움직임을 만들고 있다.

🔢 마지막으로 19번 이후의 코드는 조건문으로 로봇청소기 게임화면 끝에 도달했을 때의 행동에 대해 기술한 것으로, 이 부분은 기존의 엔트리 코딩과는 조금 다른 개념이 적용되니 주의가 필요한 부분이다. _기존에 엔트리에서는 게임화면의 경계선을 벽(wall)이라고 지칭하며 마치 화면 벽(wall)을 오브젝트처럼 다루는데 벽의 경계면에서 다른 오브젝트가 서로 닿았는가(출동했는가)라는 오브젝트 간의 충돌검사 방식을 사용했다._ **그러나, 파이게임제로에는 게임화면 경계면 자체는 어떠한 오브젝트가 아니다. 그래서,&#x20;**_**화면 경계에 도달했는지에 대한 검사를 현재 끊임없이 이동 중인 로봇청소기의 현재 위치를 통해 파악한다.**_

예들들어 robot.top 값이 0보다 작아졌다는 것은 로봇청소기 객체가 게임화면 상단을 넘어서기 시작하는 시점이며, robot.right 값이 전체화면의 가로크기보다 커지는 시점은 게임화면 최우측을 넘어서기 시작하는 시점인 것이다. 이 때, 로봇청소기를 약간(10크기 만큼) 뒤로 후진시킨 후에 방향전환을 시도하고 있음을 유념하도록 하자. 이런식의 알고리즘이 필요한 이유는 스크린의 가장자리에 도달했을 때 곧바로 방향전환을 시도했으나 때때로 방향전환된 그 순간조차도 여전히 화면 끝에 도달한 것으로 연달아 판별되면서 계속 방향전환만 시도하다가 결국에는 다른 방향으로 이동해 빠져나가지 못하고 제자리에서 가만히 공회전만 하는 경우가 발생할 수 있는데 이를 막기 위해 의도적으로 약간 후진 후 방향전환을 시도하고 있다.

참고로 19번 라인 끝에 '\\'의 표현이 궁금한 분들이 있을 것 같다. _19-20번의 두 라인(행)에 걸쳐있는 코드는 본래 19번 라인 한 행에 길게 다 코딩되어야 하는 것이었다. 그러나, 저자는 이를 의도적으로 두 라인(행)으로 분리했는데, 코드를 읽을 때 빠르고 직관적으로 읽을 수 있게 즉, 코드 가독성을 높히기 위한 의도적인 코딩이다._ 그런데, **코딩에서는 이렇게 원래 한 라인의 긴 코드를 여러 라인에 걸쳐 코딩하고자 할 경우, 나누고자 하는 행의 끝 부분에 '\\' 기호를 둠으로써 이 행은 완전히 끝난게 아니라 다음 행과 연결되어 진다는 표시를 반드시 해두어야만 하는 것이다.**

마지막으로 해당 로봇청소기의 최종 실행결과를 보는 것으로 본 장을 마무리 하겠다.

<figure><img src="https://3827255905-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fd15BjHzo0klcYpoHnPr6%2Fuploads%2FIFAeoAECjHe8yJAvubCO%2FScreen%20Recording%202024-07-17%20at%2016.59.34.gif?alt=media&#x26;token=c3bfae7a-f8ee-4333-8d18-b812f3d72350" alt=""><figcaption></figcaption></figure>
