Python飞机大战实例有感——pygame如何实现“切歌”以及多曲重奏?
pygame如何实现“切歌”以及多曲重奏?
昨天晚上研究了好久pygame的音乐混合器mixer,出了很多问题后最终成功,不过学习本来也不可能一帆风顺的吗,下面我就来讲一讲我遇到的问题。
一、pygame实现切歌
初始化路径
# 导库,需安装
import pygame
# 把路径赋值分别给三个变量,以便之后加载。
music_file_path1 = "./sound/background.mp3"
music_file_path2 = "./sound/background1.mp3"
music_file_path3 = "./sound/dead.mp3"
# 初始化混合器
pygame.mixer.init()
尝试一
开始尝试直接加载新的音乐,想着循环里有调用play方法,是不是直接调用load方法修改路径,就能播放其他音乐了呢?
# 加载初始背景音乐
pygame.mixer.music.load(music_file_path1)
while True:
pygame.mixer.music.play()
if 死亡:
# 切换死亡音乐
pygame.mixer.music.load(music_file_path3)
for 检测按键
if 按键:
#重开游戏,并切换成初始背景音乐
pygame.mixer.music.load(music_file_path1)
if 达成条件进入第二关:
# 切换为第二关背景音乐
pygame.mixer.music.load(music_file_path2)
# 延时50ms之后进入下层循环
pygame.time.delay(50)
失败、、、没有完成切换音乐,只有播放初始音乐,切换的部分是静音的。
尝试二
是不是可以考虑多开几个线程呢?之前java我就这么捣鼓过,这个算是写的比较乱的,主要还是不懂的太多。
# 导库,系统自带的。
import threading
# 定义一个函数以便线程来执行。
def bgm(music_file_path):
pygame.mixer.music.load(music_file_path)
pygame.mixer.music.play()
...
# 新建3个子线程
thread1 = threading.Thread(bgm(music_file_path1))
thread2 = threading.Thread(bgm(music_file_path2))
thread3 = threading.Thread(bgm(music_file_path3))
# 启动线程1
thread1.strat()
while True:
if 死亡:
# 切换死亡音乐
thread3.strat()
for 检测按键
if 按键:
#重开游戏,并切换成初始背景音乐
thread1.strat()
if 达成条件进入第二关:
# 切换为第二关背景音乐
thread2.strat()
# 延时50ms之后进入下层循环
pygame.time.delay(50)
同样失败了,刚开始,运行的就是死亡时候的背景音乐,也就是说,只有最后加载的那个起作用了,在具体点说,此时的thread1, thread2, thread3已经是完全相同的了。
尝试三
加了许多改变,bgm函数里加了初始化mixer,线程改为了在循环里运行匿名线程。(因为直接在循环里thread1.start()的话,会报错,说线程只能启动一次。)
# 导库,系统自带的。
import threading
# 定义一个函数以便线程来执行。
def bgm(music_file_path):
pygame.mi
pygame.mixer.music.load(music_file_path)
pygame.mixer.music.play()
...
while True:
# 默认音乐
threading.Thread(bgm(music_file_path1)).start()
if 死亡:
# 切换死亡音乐
threading.Thread(bgm(music_file_path3)).start()
for 检测按键
if 按键:
#重开游戏,并切换成初始背景音乐
threading.Thread(bgm(music_file_path1)).start()
if 达成条件进入第二关:
# 切换为第二关背景音乐
threading.Thread(bgm(music_file_path2)).start()
# 延时50ms之后进入下层循环
pygame.time.delay(50)
现在看也觉得怎么看怎么错的,不过这倒是给我提供了一个思路,只要每次切换音乐的时候重新初始化一下mixer就能播放新的了。
成功
尝试不止三次,我只是找了3个可能比较有代表性的例子,希望大家能从中吸取经验,下面,我将展示成功的代码。
# 定义3个变量来表示是否在播放哪首音乐。
sound1, sound2, sound3 = True, True, True
# 加载初始背景音乐
pygame.mixer.music.load(music_file_path1)
pygame.mixer.music.play()
while True:
if 死亡:
# 切换死亡音乐
# 通过sound的True, False的值的改变,控制只有第一次进入这个判断条件的时候才会初始化混合器。防止出现每50ms加载一次音乐的开头50ms的情况。
if sound3:
pygame.mixer.init()
pygame.mixer.music.load(music_file_path3)
sound3 = False
sound1, sound2 = True, True
if pygame.mixer.get_busy != 1:
pygame.mixer.music.play()
for 检测按键
if 按键:
#重开游戏,并切换成初始背景音乐
if sound1:
pygame.mixer.init()
pygame.mixer.music.load(music_file_path1)
sound1 = False
sound2, sound3 = True, True
if pygame.mixer.get_busy != 1:
pygame.mixer.music.play()
if 达成条件进入第二关:
# 切换为第二关背景音乐
if sound2:
pygame.mixer.init()
pygame.mixer.music.load(music_file_path1)
sound2 = False
sound1, sound3 = True, True
if pygame.mixer.get_busy != 1:
pygame.mixer.music.play()
# 延时50ms之后进入下层循环
pygame.time.delay(50)
最终成功!
总结
二、如何在python多线程顺序执行的情况下实现音乐和音效同时播放?
这个其实挺简单的,就是我开始的时候被坑了,被坑的原因现在也不太清楚。。
尝试一
# 飞机的发射子弹类
def launch_bullet:
sound = pygame.mixer.Sound("./sound/bullet.wav")
sound.play()
# 敌机的被击毁判断
if 敌机被击毁:
sound = pygame.mixer.Sound("./sound/boom.wav")
sound.play()
真的很简单的啊,就这样就应该可以了啊,结果它报错了,说unable to open file "./sound/bullet.wav",无奈,只能换方法。。
尝试二
经过查阅发现了winsound这个模块,然后,testing...
# 导入模块,系统自带的
import winsound
# 飞机的发射子弹类
def launch_bullet:
winsound.PlaySound("./sound/bullet.wav", SND_NOSTOP)
# 敌机的被击毁判断
if 敌机被击毁:
winsound.PlaySound("./sound/boom.wav", SND_NOSTOP)
然后成功感受到了单线程的恶意。。。
尝试三
于是就用多线程吧,结合java的经验,一定手到擒来的吧!
# 再次尝试使用threading
import threading
import winsound
# 飞机的发射子弹类
def launch_bullet:
# 直接匿名函数先测试走起!
threading.Thread(winsound.PlaySound("./sound/bullet.wav", SND_NOSTOP)).start()
# 敌机的被击毁判断
if 敌机被击毁:
threading.Thread(winsound.PlaySound("./sound/boom.wav", SND_NOSTOP)).start()
有点错愕地发现失败了,跟之前一次的尝试结果一样,然后才知道原来python的多线程因为什么原因我忘了,还是顺序执行的。
尝试四
在网上了解到了多进程可以实现并发访问,于是
# 系统自带
import multiprocessing
import winsound
# 飞机的发射子弹类
def launch_bullet:
multiprocessing.freeze__support()
p = multiprocessing.Process(winsound.PlaySound("./sound/bullet.wav", SND_NOSTOP))
p.start()
# 敌机的被击毁判断
if 敌机被击毁:
multiprocessing.freeze__support()
p = multiprocessing.Process(winsound.PlaySound("./sound/boom.wav", SND_NOSTOP))
p.start()
然后每射一发子弹,就给我打开一个新窗口,我。。。。
成功
最后决定还是再给Sound一个机会,他文档上不是说只能加载wav和ogg吗?wav失败了,我再重新找一下ogg的素材吧。然后就成功了。就成功了。。。我捣鼓半天,结果是素材的原因。
# 飞机的__init__方法里
self.sound = pygame.mixer.Sound("./sound/bullet.ogg")
# 飞机的发射子弹类
def launch_bullet:
self.sound.play()
# 敌机的__init__方法里
self.sound = pygame.mixer.Sound("./sound/get_score.ogg")
# 敌机的被击毁判断
if 敌机被击毁:
self.sound.play()
具体第一次尝试为何失败我们仍未可知,也许是文件太大了?
总结
真的是一次印象挺深刻的经历,深刻到我这篇全文都是没看之前的代码敲出来的,甚至学了个新单词mixer是混合器的意思。程序源码我会放在我的github上。
Python飞机大战实例有感——pygame如何实现“切歌”以及多曲重奏?的更多相关文章
- python 飞机大战 实例
飞机大战 #coding=utf-8 import pygame from pygame.locals import * import time import random class Base(ob ...
- python飞机大战
'''新手刚学python,仿着老师敲的代码.1.敌方飞机只能左右徘徊(不会往下跑)并且不会发射子弹.2.正在研究怎么写计分.3.也参考了不少大佬的代码,但也仅仅只是参考了.加油!''' import ...
- python飞机大战简单实现
小游戏飞机大战的简单代码实现: # 定义敌机类 class Enemy: def restart(self): # 重置敌机的位置和速度 self.x = random.randint(50, 400 ...
- python飞机大战代码
import pygame from pygame.locals import * from pygame.sprite import Sprite import random import time ...
- 猜数字和飞机大战(Python零基础入门)
前言 最近有很多零基础初学者问我,有没有适合零基础学习案例,毕竟零基础入门的知识点是非常的枯燥乏味的,如果没有实现效果展示出来,感觉学习起来特别的累,今天就给大家介绍两个零基础入门的基础案例:猜数字游 ...
- 小甲鱼python基础教程飞机大战源码及素材
百度了半天小甲鱼python飞机大战的源码和素材,搜出一堆不知道是什么玩意儿的玩意儿. 最终还是自己对着视频一行行代码敲出来. 需要的同学点下面的链接自取. 下载
- python(pygame)滑稽大战(类似飞机大战) 教程
成品已录制视频投稿B站(本文目前实现了基础的游戏功能),点击观看项目稽忽悠不(github)地址:https://github.com/BigShuang/From-simple-to-Huaji 本 ...
- Python版飞机大战
前面学了java用java写了飞机大战这次学完python基础后写了个python版的飞机大战,有兴趣的可以看下. 父类是飞行物类是所有对象的父类,setting里面是需要加载的图片,你可以换称自己的 ...
- Python小游戏之 - 飞机大战美女 !
用Python写的"飞机大战美女"小游戏 源代码如下: # coding=utf-8 import os import random import pygame # 用一个常量来存 ...
随机推荐
- glyphicon 图标的使用
基本用法<span class="glyphicon glyphicon-search"></span>可以将图标放于按钮于链接中,一个大按钮,按钮的内容是 ...
- 2-17 numpy模块使用
#CURD import numpy as np data1 = np.array([1,2,3,4,5]) print(data1) data2 = np.array([[1,2], [3,4]]) ...
- bzoj 1912: [Apio2010]patrol 巡逻【不是dp是枚举+堆】
我是智障系列.用了及其麻烦的方法= =其实树形sp就能解决 设直径长度+1为len(环长) 首先k=1,直接连直径两端就好,答案是2*n-len 然后对于k=2,正常人的做法是树形dp:先求直径,然后 ...
- bzoj 4176: Lucas的数论【莫比乌斯反演+杜教筛】
首先由这样一个结论: \[ d(ij)=\sum_{p|i}\sum_{q|j}[gcd(p,q)==1] \] 然后推反演公式: \[ \sum_{i=1}^{n}\sum_{j=1}^{n}\su ...
- P3162 [CQOI2012]组装
传送门 退火大法好 我并不会正解于是只好打退火了--其他没啥好讲--只要对每一种颜色开一个vector,存一下所有这个颜色的位置,判定的时候可以去所有的颜色里二分找到前缀和后缀,把和当前点距离小的加入 ...
- [App Store Connect帮助]八、维护您的 App(5)生成产品报告
您可以生成产品报告,详细介绍您所在机构中 App 目录的信息和设置,包括 App 内购买项目,以及 Game Center排行榜和成就的元数据. 首先您以不同类型请求产品报告,之后您会收到一封电子邮件 ...
- 图的遍历---------开始开始-------o(∩_∩)o 哈哈
图的遍历 深度优先搜索(Depth First Search , DFS) --深度优先搜索--我的理解就是分身术的另一种实现方法---用分身术将所有能看到的路都走一遍----这就是深度搜索--- 下 ...
- 【转】Hive安装及使用攻略
Posted: Jul 16, 2013 Tags: HadoophiveHiveQLsql分区表 Comments: 18 Comments Hive安装及使用攻略 让Hadoop跑在云端系列文章, ...
- Hdu 5336 XYZ and Drops (bfs 模拟)
题目链接: Hdu 5336 XYZ and Drops 题目描述: 有一个n*m的格子矩阵,在一些小格子里面可能会有一些水珠,每个小水珠都有一个size.现在呢,游戏开始咯,在一个指定的空的小格子里 ...
- POJ 1258 Agri-Net(Prim求最小生成树)
Agri-Net Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 64912 Accepted: 26854 Descri ...