기본 콘텐츠로 건너뛰기

[pygame] Cannon 게임프로젝트 7 - 사운드

 게임에서 사운드는 배경음악과 효과음 2가지가 있습니다. 이를 위해 pygame 에선 mixer 라이브러리를 제공합니다.

>

사운드 기능을 사용하기 전에 해야 할 일은 초기화 입니다. 

pygame.mixer.init 라는 함수가 있어 설정값을 주고 초기화 할 수있지만, 보통은 pygame.init() 를 사용하여 한번에 여러 라이브러리를 초기화 하는게 간단하고 편하기 때문에 보통 초기화는 다음과 같은 방법을 씁니다.

pygame.mixer.pre_init(44100,-16,2,512)  
pygame.init()   

pygame.init() 전에 pre_init 로 초기화시 사용할 초기값을 미리 설정해 주는 것 입니다. 맨 마지막 인수가 buffer 값인데 예전에는 512 로 해 주지 않으면 효과음에 지연이 생겨서 넣어 줬던 것인데 최근 pygame 문서를 보면 기본값이 512 로 바뀌었더군요. 따라서 pre_init 를 해주지 않아도 될지도 모르겠지만 pygame 버전에 따른 차이가 생길 수 있으니 저는 그냥 명시적으로 넣어줍니다. 

 

1. 배경음악

pygame.mixer.music 의 사용법은 간단합니다.

pygame.mixer.music.load('bg.ogg')

pygame.mixer.music.play()

하면 됩니다. load 함수에 리턴값 없이 그냥 저렇게 쓰면 됩니다.

play 함수는 play(3) 처럼 반복 재생회수를 넣어줄 수 있으며 -1 이면 계속 반복 재생합니다.

https://www.pygame.org/docs/ref/music.html

 그 외에 다른 함수들은 위의 링크를 보면 됩니다. 영어 단어만 봐도 대충 무슨 함수인지 알 수 있습니다. rewind, stop, pause 같은 함수들입니다.

다만 몇가지만 설명해 드리자면.... 

>

pygame.mixer.queue('xxx.ogg') 

위의 queue 함수는 지금 재생되는 음악이 끝나고 다음에 재생될 파일을 미리 지정해 주는 것입니다. 

>

set_endevent 함수는 음악이 끝났을때 event 를 발생시킵니다.

 MUSIC_END = pygame.USEREVENT + 1

우선 위와 같이 이벤트 메시지를 정의해 줍니다.

pygame.mixer.music.set_endevent(MUSIC_END)

위와 같이 end 메시지를 받겠다고 설정해 준 뒤에...

 while True:        
    ev = pygame.event.get()
    for event in ev:
        if event.type == MUSIC_END :
            print("Music End")
        break

이벤트 메시지 처리하는 곳에서 위 처럼 해당 메시지를 처리해 주면 됩니다.

 

2. 효과음

효과음의 경우는....

f_snd = pygame.mixer.Sound('fire.ogg')

이렇게 효과음 파일을 로딩한 후에....

f_snd.play()

효과음이 필요한 곳에 위와 같이 쓰면 됩니다. 매우 간단합니다. 

https://www.pygame.org/docs/ref/mixer.html

나머지는 위의 문서를 참고 하시면 됩니다. music 에서 처럼 stop, fadeout 같은 함수들이 있습니다.

다만 channel 에 대해서 간단히 이야기 할까 합니다.

>

pygame.mixer 의 채널은 알아서 관리 됩니다만 직접 지정해서 사용할 수도 있습니다. 

op_snd = pygame.mixer.Sound('op.ogg')
ch0 = pygame.mixer.Channel(0)
 
while True:         
    if not ch0.get_busy():
        ch0.play(op_snd)

위의 경우는 get_busy 함수를 이용해서 ch0 의 효과음의 재생이 끝났는지 확인해 보고 다시 효과음을 내도록 하고 있습니다. 

위와 같이 효과음의 채널을 좀 더 세세하게 제어 하고 싶다면 직접 채널을 만들어서 사용 해야 합니다.

 

댓글

이 블로그의 인기 게시물

드래곤즈 도그마 일본어 음성 패치

드래곤즈 도그마는 캡콤의 오픈월드 RPG 게임으로 액션성이 매우 뛰어난 게임입니다. 이 게임은 원래 콘솔게임이었고 일본어와 일본음성이 존재했으나, 스팀에서 판매되는 PC 판의 경우 일본어는 제외되어 있습니다. 하지만, 능력자들이 음성의 일본어 패치를 제작하여 배포하고 있습니다.   http://www.nexusmods.com/dragonsdogma/mods/108/? 제 경우는 일본어를 거의 못하지만 간단한 게임용 일본어 정도는 알아듣기에 일본어쪽이 게임에 좀더 몰입할 수 있었습니다. 그리고 개인적인 의견으로는 일본어 더빙쪽이 조금 더 잘 되어 있는것 같습니다. 영어가 더 익숙하신 분들은 반대일 수도 있겠지만요. 설치 방법은 다음과 같습니다. 1. 위의 파일을 받아 압축을 푼 후에 스팀 게임 설치 디렉토리로 이동합니다. 2. "SteamApps\common\DDDA" 위치에 모두 복사해 넣으세요. 중복되는 파일은 덮어 씌우시고요. 3. "nativePC\rom" 폴더로 이동하여 patchall.bat 파일을 실행하면 창이 하나 뜨면서 패치가 시작됩니다. 4. 패치완료후에 창을 닫고 게임을 즐기면 됩니다. ^^; 주의 하실 점은, 이 패치는 기존의 영어음성을 덮어 씌우는 형식입니다. 따라서 영어음성으로 다시 바꾸시려면 무결성 검사로 게임을 원본으로 되돌려야 합니다. 음성을 따로 영어/일어 로 선택하여 즐기실 수는 없습니다.

VirtualBox 에 Lubutu 설치

 얼마전에 antix linux 를 설치했었는데 아무래도 늘 이용하던 패키지들이(앱들이) 아니다 보니 이런저런 시간지연(?)이 좀 되어서 천천히 알아가기로 하고 일단 익숙한 xubuntu 를 설치해서 쓰고자 했습니다만... 제가 보통 쓰는 virtualbox 에서 xubuntu 가 설치완료가 안되더군요. 중간에 멈춰버립니다. 부팅해보면 설치는 대충된거 같은데 뭔가 마지막 프로세스를 완료하지 못해서인지 로그인도 안됩니다.  몇번 해보다 안되서 그냥 루분투를 설치했습니다. 루분투는 잘 설치되네요. 루분투는 개인적으론 좀 애매하다고 생각해서....일반적인 데스크탑으로 쓰기엔 xubuntu 정도는 되야 하지 않나 생각합니다.  루분투는 넷북에 설치해 본 바로도 xubuntu 보다 빠르다는 느낌이 없어서 말이죠. 저사양 배포판일텐데.....뭐..넷북이 워낙에 느려서 그럴수도 있지만 antix 리눅스 설치해 본 바로는 lubuntu 보단 낫더라고요. virtualbox에 xubuntu 가 설치가 안되서 예상외로 시간을 좀 까먹었네요. 쩝....

pygame 에서 이미지 회전하는 방법

 pygame 에서 transform.rotate 를 사용해서 이미지를 회전시켜 보면 생각과는 달리 요상하게 회전합니다.    따라서 이를 해결해 보고자 검색해 보다 다음 링크를 찾았습니다. https://stackoverflow.com/questions/4183208/how-do-i-rotate-an-image-around-its-center-using-pygame/54714144 위 링크를 보면 파이게임의 이미지 회전이 왜 그렇게 이상한지 알 수 있고 답변하신 분이 blitRotate 라는 함수를 만들어 놓아서 이용할 수 있습니다.  제 소스에 가져와서 테스트를 해 봤는데 제 생각대로 회전 하더군요.  def blitRotate(image, pos, originPos, angle):       #calcaulate the axis aligned bounding box of the rotated image     w, h       = image.get_size()     box        = [pygame.math.Vector2(p) for p in [(0, 0), (w, 0), (w, -h), (0, -h)]]     box_rotate = [p.rotate(angle) for p in box]     min_box    = (min(box_rotate, key=lambda p: p[0])[0], min(box_rotate, key=lambda p: p[1])[1])     max_box    = (max(box_rotate, key=lambda p: p[0])[0], max...