5.5 팔 벌려 뛰기 횟수를 세어봐요 - 변수

우리는 엔트리 블록코딩에서 오브젝트들의 에니메이션을 일상적으로 활용해봤었다. 파이게임제로에서도 그렇게 할 수 있을까? 당연히 가능하다. 게임에서 애니메이션은 일상과 같기 때문이다. 이번 예제에서는 Actor객체의 에니메이션을 처음으로 사용해 보겠다.

from pgzhelper import *

WIDTH = 480
HEIGHT = 270

boy = Actor('boy_1', (WIDTH / 2, HEIGHT / 2))
boy.images = ['boy_1', 'boy_2', 'boy_3']

times = 0
pressed = False

def draw():
    screen.fill('white')
    boy.draw()
    game.time.sleep(0.5)
    screen.draw.text('Times: ' + str(times), (20, 20), color='black')

def update():
    global times, pressed
    if pressed:
        if boy.next_image() == 0:
            times += 1
            pressed = False

def on_mouse_down():
    global pressed
    pressed = True

🔢 7번 라인에서 images 라는 객체속성이 등장했다. 이름에서 알 수 있듯이, 여러 이미지들을 리스트 형태로 저장해 놓고 있는데, 목적은 오브젝트의 이미지 애니메이션을 위한 것이다. 리스트에 이미지 3개(boy_1, boy_2, boy_3)은 결국 엔트리에서 봤던 팔벌려 뛰는 아이 오브젝트가 갖고 있던 3장의 이미지(모양)와 동일하다.

🔢 에니메이션 얘기가 나온 김에 관련 코드를 먼저 검토하면, 엔트리에서 애니메이션을 위해서 각각의 3장의 이미지를 연속 로테이션 시키면서 애니메이션을 생성했던 기억이 있을 것이다. 그때 이미지 간의 이동을 위해 사용했던 블록으로 "다음 모양으로 바꾸기" 라는 블록을 사용했었을 텐데 21번 라인에서 사용한 next_image 라는 함수가 바로 그 블록과 대칭되는 역할을 하는 메소드(함수)이다. 단, Actor 객체의 외관 이미지의 변경에 화면 상의 변경에 관한 내용으로 update() 콜백함수 내에서 이뤄져야 하는 점을 유의하기 바란다.

next_image 메소드를 수행 후 결과로 리턴하는 값은 image 리스트 상에 어느 이미지로 옮겨갔는지 그 위치값(인덱스값)을 결과값으로 돌려준다. 21번 라인은 조건문인데, boy.next_image() == 0 이라는 조건은 결국, 이미지간의 로테이션이 한바퀴 다 완료하고 다시 맨 처음 이미지(인덱스값이 0)로 돌아왔다면 즉, 3장의 이미지로 구성된 팔벌려 뛰기 모든 부분동작을 다 완료했는지의 여부를 확인하는 것이다. 이때야 말로 현재까지 진행한 팔벌려 뛰기 총 회수를 세기에 딱 적합한 시점이 아닐 수 없다. 총 회수는 9번 라인에서 선언한 전역(global) 변수인 times 변수에 누적 합산해 놓는다.

🔢 10번 라인에서 선언한 pressed 라는 전역변수의 용도를 이해하겠는가? 마우스 버튼을 누를 경우에만(27번 라인에 의해서 pressed 값이 True가 된 경우에만) 애니메이션을 진행시키기 위한 목적이다. 따라서, 애니메이션이 종료된 후에는 23번 라인처럼 다시 False로 초기화 해 놓는 것이 필요하다. 그래야만, 다시금 마우스 버튼 눌림에 따른 애니메이션을 계속 이어나갈 수 있기 때문이다.

🔢 참고로 15번 라인의 game.time.sleep() 메소드는 이 앱의 구현상 반드시 필요한 것은 아니나 팔벌려 뛰기동작 애니메이션이 너무 빨리 진행되는 것을 늦춰 동작을 자세히 구분해 보기 위한 것으로 이미지 프레임 사이에 0.5초의 기다림을 준 것이다.

이미 우리는 기존 장들에서 배운 사전 지식들이 쌓여있어서 새롭게 등장한 것들 위주로 빠르게 익혀나갈 수 있었다. 끝으로 이 예제의 실행결과를 살펴보는 것으로 이 장을 마무리 하겠다.

Last updated