본문 바로가기

렌파이/연출하기

스프라이트 매니저를 이용해 파티클 효과 만들기


렌파이에서 스프라이트 매니저는 파티클 이펙트라고 하는 보조 시각 효과를 만드는 데 적합한 시스템입니다. 여기서 말하는 파티클 이펙트로는 위에서 눈이 떨어진다던가 하는 익숙한 화면 효과에서부터 폭발이라던가 먼지가 이는 시각 표현 등을 예로 들 수 있습니다.

1. SnowBlossom

사실 앞서 예로 들었던 눈발이라던가 떨어지는 꽃잎같은 건 SnowBlossom 으로 간단하게 만들 수 있습니다.



이렇게 적기만 해도 게임 화면에 눈 내리는 연출을 추가할 수 있습니다. 여기에 파티클 이동 속도, 시작 방향, 갯수 등을 정하면 세로, 혹은 가로 방향에서 그 다음 방향으로 전진하는 파티클을 만들 수 있습니다. SnowBlossom 매뉴얼 항목을 확인하면 더 자세한 내용을 알아보실 수 있습니다.

화면에 추가하고픈 효과가 이것보다 복잡한 것일 때에는 스프라이트 매니저 클래스를 이용해야 합니다.

2. SpriteManager

매뉴얼에도 물론 스프라이트 시스템에 관한 설명이 있습니다. 하지만 클래스니 메소드니 그런 용어가 있는 설명글은 파이썬 좀 안다 하는 분들에게나 유용한 정보이겠죠. 이 글의 목표는 그런 거 모르고 파티클 만들자, 가 되므로 여기서는 최대한 간단하게 설명하겠습니다.


일반적인 파티클을 만든다고 했을 때, 알아두면 되는 것은 단 두 가지입니다.
하나는 SpriteManager 의 update 항목으로, 이곳에 그림을 어떻게 표시할지 결정하는 함수의 이름을 적어주면 됩니다.
나머지 하나는 create 라는 것입니다.


예제에서 사용할 비행선 그림. 파이게임 예제에 있는 그림입니다. alien1.gif



.create

create은 파티클로 사용할 디스플레이어블을 만듭니다. 이렇게 만들어진 디스플레이어블은 스프라이트매니저에서 관리할 수 있도록 추가됩니다.

사용법은 예를 들어 설명해드리겠습니다.

say 문에서 사용할 캐릭터 객체라는 걸 만들 때 다음과 같은 식으로 적는다는 건 아실 겁니다


이렇게 되면 b 에는 '백안시' 캐릭터에 대한 모든 정보가 담기게 됩니다. 이 때 b 와 속성은 공유하지만 이름은 다른 캐릭터를 e 에 저장하고 싶을 때는 다음과 같이 씁니다.


이렇게만 적어도 이름은 다르지만 '백안시' 캐릭터와 같은 속성을 갖춘 '에일린' 캐릭터의 정보가 e에 저장됩니다.
create 도 위의 .copy와 같은 방식으로 사용하면 됩니다.

캐릭터에 그랬던 것처럼 먼저 변수에 스프라이트매니저를 저장하고


sm 이라는 변수에 점 하나 찍어주고 create라고 써주면


alien1이라는 이미지를 스프라이트매니저에 추가하고, 사용할 수 있게 됩니다. 여기서는 이미지 파일 이름을 적어주었지만 이미지뿐만 아니라 디스플레이어블 모두를 스프라이트로 사용할 수 있습니다. 이제 이미지를 스프라이트매니저에서 사용하기 쉽도록 다음과 같이 적어줍니다.




② update

이제 SpriteManager의 update 에는 시간이 지남에 따라 어떻게 파티클을 표시할 것인지를 결정하는 함수를 적어주면 됩니다.

아니, 그런 걸 함수로 어떻게 결정하죠 >>

빈화면에 오른쪽으로 움직이는 별이 있다고 생각해봅시다.



이 별이 오른쪽으로 움직인다는 것을 화면에서 보여주려면

★                     - 화면 1
 ★                    - 화면 2
  ★                    - 화면 3
...

이런 식의 각 화면을 연속으로 보여주면 됩니다.
즉, 이전 화면에 있던 별을 지우고 다음 화면에서는 새 위치에 별을 그리면, 그리고 그 화면을 연속해서 표시하면 마치 별이 오른쪽으로 이동한 듯한 느낌을 받을 수 있는 겁니다.

혹시 책 귀퉁이에 그림을 그려서 책장을 넘기면 그림이 움직이도록 해 본 적 있으신지요.



스프라이트 매니저의 update에 쓸 함수도 이거랑 비슷한 역할을 한다고 보시면 됩니다. 연속으로 그림을 그려서 마치 그것이 움직이는 것처럼 보이게 하는 거죠. 다른 점이 있다면 이미지 한 장만으로도 움직이는 그림을 만들 수 있다는 겁니다.

제가 든 예가 이해가셨다면 비유를 들어서 설명해보겠습니다.

만일 책장 넘기기 그림을 update에서 사용할 함수의 형태로 만들어본다면 다음과 같습니다.



- 함수가 받는 값 = 처음 그림을 표시하고 나서부터 지금 보고 있는 그림을 그렸을 때까지의 경과한 시간.
    경과한 시간은 보통 st라고 적습니다. (st는 showtime 의 약자입니다.).
- 책장 넘기는 시간 = 함수가 반환하는 값 :
    책장을 넘기는 데 걸리는 시간이 빠를 수록 보다 그림 움직임이 부드럽게 보입니다. 되도록이면 소수점 단위로 적당한 숫자를 입력합시다.
- 책장마다 그려진 그림 ≒ 함수 내용

마지막에 등호가 아니라 약 기호를 쓴 건 두 가지가 완전히 같지는 않기 때문입니다. 함수 안에는 각 초마다 표시할 그림을 그리는 대신 함수가 다시 불려올 때마다 위치라던가 하는 것이 어떤 식으로 달라져야 하는가를 적기만 하면 됩니다.


일단 왼쪽에서 오른쪽으로 움직이는 비행선('alien1.gif')을 만든다고 가정해봅시다.
아까 'alien1.gif'를 스프라이트매니저에 추가해서 particle 변수에 저장했으니, 이렇게 쓰면 됩니다.


처음에 particle의 가로(x)위치는 0이지만, 0.01 초 후의 화면에서 particle 은 가로 상의 5px 에 위치하게 됩니다.
그림을 처음 그린 이후로 경과한 시간 * 속도 500 을 곱한 값이 particle 의 x좌표값에 저장되는 것이니까요.

그러니까 이 함수로 0.01초마다 그림을 그리게 되면,
처음에는 0px 위치에 그려지던 것이, 0.01 에는 5px위치에 그려지게 되고, 0.02 초에는 10px, 0.03 초에는 15px 에,
이런 식으로 계속 그림이 새 위치에 그려지게 되니까 보는 사람의 눈에는 그림이 점점 이동한 것처럼 보이게 됩니다.

처음부터 여기까지 내용을 정리하면 이렇게 됩니다.



파티클 효과는 보통 여러 개의 동일한 이미지로 이루어져 있는데, 그런 경우에는 어떻게 해야 하는가?
변수에 하나의 스프라이트만을 배정하는 것이 아니라 리스트를 만들어서 거기에 이미지를 여러개 추가하면 됩니다.
아래 코드를 위 코드와 비교하면서 보세요.


참고 1. 물결선을 따라 이동하도록 만들고 싶으시다거나 소용돌이 모양으로 회전하는 스프라이트같은 걸 만들고 싶으시다면 위에 예로 들었던 것 보다는 좀 더 복잡한 식을 적어야 합니다. 참고로 그 식이라는 건 저도 모릅니다...orz 이런 경우에는 삼각함수같은 것을 이용해야 할 것이니 수학지식이 필수입니다. 그리고 그 식을 이용할 때 필요한 파이썬 함수도 같이 알아야 써먹을 수 있을 겁니다.

참고 2. 스프라이트에 xalign 같은 건 사용할 수 없습니다. 그러니까 위 예에서 particle.xalign 이라고 쓰면 에러가 발생한다는 이야기. 사용할 수 있는 위치값은 오로지 x, y정도입니다.

③ event

event는 비주얼 노벨에서 보통 사용하는 파티클 효과를 만들 때는 부차적인 것입니다. 그러니 짧게 설명을 적습니다.

event는 이 스프라이트가 그려질 조건같은 것이라고 할 수 있습니다. 역시 함수를 받는데, 매뉴얼에 있는 예제는 마우스의 위치에 따라 그림이 움직이도록 만든 스프라이트라서 event 에 사용된 함수가 마우스 커서의 위치를 저장하도록 만들어져있습니다. 그리고 그 마우스의 위치를 update 함수에서 사용하고 있죠.

이 event에서 쓸 함수에는 파이게임의 이벤트 객체도 사용할 수 있습니다.
쉽게 말하면 키가 눌려졌다거나 마우스가 움직인다던가 하는 것도 인식해서 사용할 수 있다는 겁니다.



위 예제는 방향키를 누르면 이동하는 스프라이트를 화면에 그립니다. 물론 이렇게 화살표 키를 누르면 움직인다던가 하는 식의 이미지를 비주얼 노벨 등에서 사용할 일은 드물겠지만요.


3. 기타

이 글을 쓰기를 미루고 미뤄왔던 이유는 첫째, 제가 이해를 못해서(..)였고 둘째는 렌파이의 단점 중 하나에 속하는 시스템이기 때문입니다.

네코노벨을 사용하셨던 분은 아시겠지만 네코노벨에는 파티클 제작 툴이 동반배포되고, 그 툴의 사용법도 간단해서 쉽게 파티클을 만들 수 있습니다. (적어도 파티클 스크립트를 직접 짜는 것보다는 간단합니다)

하지만 렌파이는 스프라이트매니저로 파티클을 만들어야 합니다. 이는 초보자가 다루기 힘든 클래스 형태로 만들어져있고 클래스를 조금 안다고 해도 계산식을 세울 줄 알아야 그럴싸한 효과를 만들어낼 수 있습니다. 프로그래밍 언어에 능숙한 사람에게는 유용하겠습니다만[각주:1], 아닌 사람들에게는 있어봤자인 시스템인 거죠.

비주얼 노벨에서는 파티클 효과가 그다지 필요하지 않다고 볼 수도 있지만, 100%라고 장담은 못하는 것이구요. 특히나 시각 효과가 중요한 장르인데요, 괜히 비주얼 노벨이 비주얼 노벨이겠습니까.

네코노벨(바실리어트)과 렌파이는 제작된 방식이라던가 사용한 라이브러리같은 게 달라서 그런 차이점이 생기는 걸까요? 잘 모르겠습니다만, 어쨌든 후에는 렌파이에도 좀 더 편리한 파티클 제작 방식이 등장하길 기대해봅니다.
  1. 따지고보면 그다지 유용해보이지 않기도 합니다.. 스프라이트에 사용할 수 있는 속성이 굉장히 빈약하기 때문입니다. http://baekansi.hosting.paran.com/doc/html/sprites.html#sprites [본문으로]