5.3 화면에 플래피버드(오브젝트)의 자연스러운 움직임 만들기
우리 눈에 플래피버드의 움직임이 자연스럽지 않았던 건 자연에 존재하는 실제 물리법칙 즉 중력과 유사하게 만들지 않았기 때문이다라고도 할 수도 있다. 그래서, 움직임을 실제 중력과 유사하게 구현해 보도록 하자. 우리가 아는 상식에서의 중력은 고정된 일정한 힘이며, 중력에 의해서 물체가 낙하할 때, 물체는 일정한 속도로 낙하하는게 아니라, 가속도가 붙어서 떨어질 때는 점점더 빠르게 떨어진다는 것이다. 따라서 우리도 이 두 가지(중력과 떨어지는 속도)를 두 가지 변수를 사용해 분리하자.
TITLE = 'Flappy Bird'
WIDTH = 400
HEIGHT = 708
GRAVITY = 0.3
drop_speed = 0
flappy_bird = Actor('bird1', (75, 350))
def draw():
screen.blit('background', (0, 0))
flappy_bird.draw()
def update():
global drop_speed
drop_speed += GRAVITY
flappy_bird.y += drop_speed
def on_mouse_down():
global drop_speed
drop_speed = -6.5
🔢 위에서 언급한 것처럼 자연스럽게 나는 모습을 구현하기 위해서는 몇 가지 추가적인 변수를 도입할 필요가 있다. 플래피버드가 자연낙하하게 하는 중력(아래방향으로 당기는 힘)이라는 변하지 않는 고정된 힘의 크기를 5번 라인에서 GRAVITY 라는 변수명과 함께 그 크기를 0.3이라고 정했다. 여기서 중력의 힘의 크기를 일부러 변수를 담아놓아다는 것에 주목하자. 이렇게 하는 의도는 앞으로 해당 값은 변수이름을 통해서 읽어 오겠다는 것이다. 이런 식의 테크닉을 구사하는데는 두 가지 목적이 있다.
첫째, 중력힘의 값을 변수명이 아닌 숫자값 그대로 사용했다고 하면, 당장은 몰라도 시간이 지나 나중에 나 자신 또는 내 코드를 읽게 되는 다른 동료의 코드 가독성(해독성)을 떨어뜨리게 된다. 코드를 해독하기 위해 눈으로 한 라인 한 라인 읽어나가다가 갑자기 등장한 숫자(0.3)을 보고, 그 숫자값은 도데체 어떤 값을 의미하는 숫자인지 잠시 고민하는 시간이 필요하고, 이렇게 한눈에 한번에 빠르게 읽어나가지 못하고 멈추게 하는 그 지점이 바로 가독성을 떨어뜨리는 지점인 것이다. 그런데, 우리가 이런 식으로 그 숫자값을 중력이라는 의미를 부여한 변수이름(GRAVITY)과 매칭해 놓았다면, 우리는 변수이름만 보고(이전 서에서 언급했지만, 그래서 변수이름을 의미있 잘 짓는 것이 중요!) 곧바로, 그 숫자값의 의미를 파악할 수 있다. 또 의도적으로 변수이름을 대문자로 표현한 것도 특징인데, 물론 변수가 변화하는 값을 저장하는 기본적인 목적이 있으나, 이 경우는 그러한 목적보다는 특정값을 대치하는 용도로서의 용도가 더 크기 때문에 그 의미를 부여하기 위해 대문자 표기를 하였다. 참고로 이는 일종의 프로그래머들 사이의 관습적 표현(Conding conventions)이므로 적극 활용하면 좋을 것이다.
둘째 이렇게 할 경우, 또다른 장점은 무엇이 있을까? 나중에 어떤 이유에 의해서(이전 서에서 언급했지만, 소프트웨어 특성상 생각보다 자주 코드수정이 빈번하고) 우리 게임에 새로운 요구사항이 와서 게임의 난이도를 높이기 위해 더 센 중력의 힘을 요구한다고 하자 그리고, 우리는 이에 맞춰 전반적인 코드의 재수정이 필요하다. 우리는 이미 똑똑하게 이러한 가능성을 대비해 해당 값을 변수명을 통해 코딩해 놓았지 않는가? 따라서, 이 값(GRAVITY)의 현재 값인 0.3을 예를들어 0.5으로만 바꿈으로써 이러한 코드 수정 요구사항의 빠른 대응이 가능하게 되는 것이다.
🔢 6번 라인에 도입한 drop_speed 변수는 말 그대로 값이 계속 변화하는 값이 적용되는 변수로서의 용도이기 때문에 의도적으로 소문자로만 변수명을 적었다는 것을 기억하자. 이렇게 대문자/소문자의 구분표기만으로도 그 용도가 쉽게 들어나는 용이성이 있다. drop_speed 라는 이름을 부여한 것에서 알 수 있듯이, 낙하를 만드는 힘(중력)은 고정된 것이나 실제 낙하할 때 속도는 시간이 지남에 따라 가속도가 붙어 더 빠른 속도로 증가하게 되고, 이를 표현한 값인 것이다. 해당 변수의 목적과 용도는 이해했다. 자 그런데 이번엔 전체 코드영역에서 이 변수의 정의(definition)가 어디에 위치하고 있느냐에 관한 것으로 왜 함수 안쪽 영역(scope)에 존재하지 않고, 함수 바깥쪽 영역에 존재해야 하는가에 대해 알아볼 필요가 있다. 이는 변수를 만드는 규칙에 관한 것으로, 특정 함수 안에서만 사용되는 변수는 해당 함수 안쪽에서 정의하고, 여러 함수에 걸쳐 공통으로 함께 사용해야 하는 변수는 이처럼 함수들 바깥쪽 영역에 정의하게 된다.
이처럼 drop_speed 값의 사용처는 update 함수와 on_mouse_down 함수 두 곳에서 함께 사용되고 있다는 것을 알 수 있고, 이러한 이유 때문에 해당 변수는 함수들 바깥쪽 영역에 정의되었다. 이 변수를 사용하는 함수에서의 활용을 유심히 살펴 본다면, 함수 밖에 있는 변수이고 함수 안쪽에서 그 값을 수정하려면 변수명 앞에 global 이라는 키워드(keyword)를 붙혀 함수 도입부분에서 변수명을 선언해야 하는 파이썬 문법이 존재하는 것을 발견할 수 있을 것이다. 그렇다. 파이썬 문법에서는 함수 밖에 존재하는 변수를 활용하고 있다는 의미를 명확하게 하기 위해 변수명 앞에 global(말 그대로 코드전체에서 사용가능한 변수의 의미로)를 붙히게 되어있다는 것을 기억하자. 이러한 변수들을 지칭하는 용어도 global 변수라고 불린다는 것도 함께 기억하자.
🔢 21번 라인에서 사용자가 마우스버튼을 눌러 플래피버드를 부상하려고 할 때, 낙하하는 속도를 의도적으로 음수값을 통해 뒤로 되돌림으로써 플래피버드가 상승하는 효과를 만들고 있다.
지금까지 플래피버드의 자연스러운 움직임을 만들기 위한 테크닉 적용에 대해 살펴보았고, 이를 통해 새로운 것들(파이썬 문법, 코딩관습 등)을 배울 수 있었다. 이제 다음장에서는 우리 게임무대의 두번째 Actor(배우)인 파이프 객체들을 생성하고 출현시켜 보자.
Last updated
Was this helpful?