用Python和Pygame写游戏-从入门到精通(22)
2015-06-25 21:25
295 查看
辛苦啦~ 这次是我们系统的pygame理论学习的最后一章了,把这次的音乐播放讲完了,pygame的基础知识就全部OK了。不过作为完整的教程,只有理论讲解太过枯燥了,我随后还会加一个或更多的实践篇系列,看需要可能也会追加真3D等额外的内容。
就像上次所说的,pygame.mixer并不适合播放长时间的音乐播放,我们要使用pygame.mixer.music。
pygame.mixer.music用来播放MP3和OGG音乐文件,不过MP3并不是所有的系统都支持(Linux默认就不支持MP3播放),所以最好还是都用Ogg文件,我们可以很容易把MP3转换为Ogg文件,自己搜一下吧。
我们使用pygame.mixer.music.load()来加载一个文件,然后使用pygame.mixer.music.play()来播放,这里并没有一个类似Music这样的类和对象,因为背景音乐一般般只要有一个在播放就好了不是么~不放的时候就用stop()方法来停止就好了,当然很自然有类似录影机上的pause()和unpause()方法。
Channels对象:
Music对象:
虽然很简单,不过还是提供一个例程吧,这里面音乐的播放很简单,就是上面讲过的,不过其中还有一点其他的东西,希望大家学习一下pygame中按钮的实现方法。
界面如上,运行的时候,脚本读取./MUSIC下所有的OGG和MP3文件(如果你不是Windows,可能要去掉MP3的判断),显示的也很简单,几个控制按钮,下面显示当前歌名(显示中文总是不那么方便的,如果你运行失败,请具体参考代码内的注释自己修改):
Python
这个程序虽然可以运行,还是很简陋,有兴趣的可以改改,比如显示播放时间/总长度,甚至更厉害一点,鼠标移动到按钮上班,按钮会产生一点变化等等,我们现在已经什么都学过了,唯一欠缺的就是实践而已!
所以下一次,我将开始一个实战篇,用pygame书写一个真正可以玩的游戏,敬请期待~~
辛苦啦~ 这次是我们系统的pygame理论学习的最后一章了,把这次的音乐播放讲完了,pygame的基础知识就全部OK了。不过作为完整的教程,只有理论讲解太过枯燥了,我随后还会加一个或更多的实践篇系列,看需要可能也会追加真3D等额外的内容。
就像上次所说的,pygame.mixer并不适合播放长时间的音乐播放,我们要使用pygame.mixer.music。
pygame.mixer.music用来播放MP3和OGG音乐文件,不过MP3并不是所有的系统都支持(Linux默认就不支持MP3播放),所以最好还是都用Ogg文件,我们可以很容易把MP3转换为Ogg文件,自己搜一下吧。
我们使用pygame.mixer.music.load()来加载一个文件,然后使用pygame.mixer.music.play()来播放,这里并没有一个类似Music这样的类和对象,因为背景音乐一般般只要有一个在播放就好了不是么~不放的时候就用stop()方法来停止就好了,当然很自然有类似录影机上的pause()和unpause()方法。
音效和音乐方法总结
Sound对象:方法名 | 作用 |
---|---|
fadeout | 淡出声音,可接受一个数字(毫秒)作为淡出时间 |
get_length | 获得声音文件长度,以秒计 |
get_num_channels | 声音要播放多少次 |
get_volume | 获取音量(0.0 ~ 1.0) |
play | 开始播放,返回一个Channel对象,失败则返回None |
set_volume | 设置音量 |
stop | 立刻停止播放 |
方法名 | 作用 |
---|---|
fadeout | 类似 |
get_busy | 如果正在播放,返回true |
get_endevent | 获取播放完毕时要做的event,没有则为None |
get_queue | 获取队列中的声音,没有则为None |
get_volume | 类似 |
pause | 暂停播放 |
play | 类似 |
queue | 将一个Sound对象加入队列,在当前声音播放完毕后播放 |
set_endevent | 设置播放完毕时要做的event |
set_volume | 类似 |
stop | 立刻停止播放 |
unpause | 继续播放 |
方法名 | 作用 |
---|---|
fadeout | 类似 |
get_endevent | 类似 |
get_volume | 类似 |
load | 加载一个音乐文件 |
pause | 类似 |
play | 类似 |
rewind | 从头开始重新播放 |
set_endevent | 类似 |
set_volume | 类似 |
stop | 立刻停止播放 |
unpause | 继续播放 |
get_pos | 获得当前播放的位置,毫秒计 |
界面如上,运行的时候,脚本读取./MUSIC下所有的OGG和MP3文件(如果你不是Windows,可能要去掉MP3的判断),显示的也很简单,几个控制按钮,下面显示当前歌名(显示中文总是不那么方便的,如果你运行失败,请具体参考代码内的注释自己修改):
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | # -*- coding: utf-8 -*- # 注意文件编码也必须是utf-8 SCREEN_SIZE = (800, 600) # 存放音乐文件的位置 MUSIC_PATH = "./MUSIC" import pygame from pygame.locals import * from math import sqrt import os import os.path def get_music(path): # 从文件夹来读取所有的音乐文件 raw_filenames = os.listdir(path) music_files = [] for filename in raw_filenames: # 不是Windows的话,还是去掉mp3吧 if filename.lower().endswith('.ogg') or filename.lower().endswith('.mp3'): music_files.append(os.path.join(MUSIC_PATH, filename)) return sorted(music_files) class Button(object): """这个类是一个按钮,具有自我渲染和判断是否被按上的功能""" def __init__(self, image_filename, position): self.position = position self.image = pygame.image.load(image_filename) def render(self, surface): # 家常便饭的代码了 x, y = self.position w, h = self.image.get_size() x -= w / 2 y -= h / 2 surface.blit(self.image, (x, y)) def is_over(self, point): # 如果point在自身范围内,返回True point_x, point_y = point x, y = self.position w, h = self.image.get_size() x -= w /2 y -= h / 2 in_x = point_x >= x and point_x < x + w in_y = point_y >= y and point_y < y + h return in_x and in_y def run(): pygame.mixer.pre_init(44100, 16, 2, 1024*4) pygame.init() screen = pygame.display.set_mode(SCREEN_SIZE, 0) #font = pygame.font.SysFont("default_font", 50, False) # 为了显示中文,我这里使用了这个字体,具体自己机器上的中文字体请自己查询 # 详见本系列第四部分://eyehere.net/2011/python-pygame-novice-professional-4/ font = pygame.font.SysFont("simsunnsimsun", 50, False) x = 100 y = 240 button_width = 150 buttons = {} buttons["prev"] = Button("prev.png", (x, y)) buttons["pause"] = Button("pause.png", (x+button_width*1, y)) buttons["stop"] = Button("stop.png", (x+button_width*2, y)) buttons["play"] = Button("play.png", (x+button_width*3, y)) buttons["next"] = Button("next.png", (x+button_width*4, y)) music_filenames = get_music(MUSIC_PATH) if len(music_filenames) == 0: "No music files found in ", MUSIC_PATH return white = (255, 255, 255) label_surfaces = [] # 一系列的文件名render for filename in music_filenames: txt = os.path.split(filename)[-1] "Track:", txt # 这是简体中文Windows下的文件编码,根据自己系统情况请酌情更改 txt = txt.split('.')[0].decode('gb2312') surface = font.render(txt, True, (100, 0, 100)) label_surfaces.append(surface) current_track = 0 max_tracks = len(music_filenames) pygame.mixer.music.load( music_filenames[current_track] ) clock = pygame.time.Clock() playing = False paused = False # USEREVENT是什么?请参考本系列第二部分: # //eyehere.net/2011/python-pygame-novice-professional-2/ TRACK_END = USEREVENT + 1 pygame.mixer.music.set_endevent(TRACK_END) while True: button_pressed = None for event in pygame.event.get(): if event.type == QUIT: return if event.type == MOUSEBUTTONDOWN: # 判断哪个按钮被按下 for button_name, button in buttons.iteritems(): if button.is_over(event.pos): button_name, "pressed" button_pressed = button_name break if event.type == TRACK_END: # 如果一曲播放结束,就“模拟”按下"next" button_pressed = "next" if button_pressed is not None: if button_pressed == "next": current_track = (current_track + 1) % max_tracks pygame.mixer.music.load( music_filenames[current_track] ) if playing: pygame.mixer.music.play() elif button_pressed == "prev": # prev的处理方法: # 已经播放超过3秒,从头开始,否则就播放上一曲 if pygame.mixer.music.get_pos() > 3000: pygame.mixer.music.stop() pygame.mixer.music.play() else: current_track = (current_track - 1) % max_tracks pygame.mixer.music.load( music_filenames[current_track] ) if playing: pygame.mixer.music.play() elif button_pressed == "pause": if paused: pygame.mixer.music.unpause() paused = False else: pygame.mixer.music.pause() paused = True elif button_pressed == "stop": pygame.mixer.music.stop() playing = False elif button_pressed == "play": if paused: pygame.mixer.music.unpause() paused = False else: if not playing: pygame.mixer.music.play() playing = True screen.fill(white) # 写一下当前歌名 label = label_surfaces[current_track] w, h = label.get_size() screen_w = SCREEN_SIZE[0] screen.blit(label, ((screen_w - w)/2, 450)) # 画所有按钮 for button in buttons.values(): button.render(screen) # 因为基本是不动的,这里帧率设的很低 clock.tick(5) pygame.display.update() if __name__ == "__main__": run() |
所以下一次,我将开始一个实战篇,用pygame书写一个真正可以玩的游戏,敬请期待~~
相关文章推荐
- 用Python和Pygame写游戏-从入门到精通(20)
- 用Python和Pygame写游戏-从入门到精通(19)
- 用Python和Pygame写游戏-从入门到精通(17)
- 用Python和Pygame写游戏-从入门到精通(18)
- 用Python和Pygame写游戏-从入门到精通(15)
- 用Python和Pygame写游戏-从入门到精通(14)
- Python使用__future__
- 用Python和Pygame写游戏-从入门到精通(13)
- 用Python和Pygame写游戏-从入门到精通(11)
- Python动态导入模块
- 用Python和Pygame写游戏-从入门到精通(10)
- 用Python和Pygame写游戏-从入门到精通(9)
- 【python】 入门 - 函数式编程
- 用Python和Pygame写游戏-从入门到精通(7)
- 用Python和Pygame写游戏-从入门到精通(8)
- 用Python和Pygame写游戏-从入门到精通(6)
- 用Python和Pygame写游戏-从入门到精通(5)
- 用Python和Pygame写游戏-从入门到精通(4)
- 用Python和Pygame写游戏-从入门到精通(3)
- 用Python和Pygame写游戏-从入门到精通(2)