Python飞机大战实例有感——pygame如何实现“切歌”以及多曲重奏?

目录

  • pygame如何实现“切歌”以及多曲重奏?

    • 一、pygame实现切歌

      • 初始化路径
      • 尝试一
      • 尝试二
      • 尝试三
      • 成功
      • 总结
    • 二、如何在python多线程顺序执行的情况下实现音乐和音效同时播放?
      • 尝试一
      • 尝试二
      • 尝试三
      • 尝试四
      • 成功
      • 总结

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上。

飞机大战源码

原文地址:https://www.cnblogs.com/zhangA/p/10954714.html

时间: 2024-08-29 18:33:50

Python飞机大战实例有感——pygame如何实现“切歌”以及多曲重奏?的相关文章

python 飞机大战 实例

飞机大战 #coding=utf-8 import pygame from pygame.locals import * import time import random class Base(object): def __init__(self,x,y,screen,image_name): self.x=x self.y=y self.screen=screen self.image=pygame.image.load(image_name).convert() class BaseBul

小甲鱼python基础教程飞机大战源码及素材

百度了半天小甲鱼python飞机大战的源码和素材,搜出一堆不知道是什么玩意儿的玩意儿. 最终还是自己对着视频一行行代码敲出来. 需要的同学点下面的链接自取. 下载 原文地址:https://www.cnblogs.com/144823836yj/p/10162920.html

python(pygame)滑稽大战(类似飞机大战) 教程

基于pygame实现类似飞机大战小游戏(滑稽大战) 成品已录制视频投稿B站,点击观看动画 项目稽忽悠不(github)地址(目前只上传了素材,代码还在整理中):https://github.com/BigShuang/From-simple-to-Huaji本文首发于本人简书 初始准备工作 本项目使用的python3版本(如果你用python2,我不知会怎么样) Ide推荐大家选择pycharm(不同ide应该没影响) 需要安装第三方库pygame, pygame安装方法(windows电脑,m

Python版飞机大战

前面学了java用java写了飞机大战这次学完python基础后写了个python版的飞机大战,有兴趣的可以看下. 父类是飞行物类是所有对象的父类,setting里面是需要加载的图片,你可以换称自己的喜欢的图片,敌机可以分为敌机和奖励,enemy为普通敌人的父类,award为奖励敌机的父类. 各个类的基本属性 主类的大概逻辑 具体的代码: settings配置 import pygame class Settings(object): """设置常用的属性"&quo

【python】步骤四 第二课、实现飞机大战

第二课.实现飞机大战 一.项目介绍 项目实战:飞机大战 课程目标 掌握面向对象分析和开发的思想 能对项目进行拆分,进行模块化开发 了解项目开发的基本流程 理解并运用python的包.模块相关知识 理解并运用文件读写,函数式编程 理解简单2D游戏开发的基本思路 能独立开发简单的2D游戏项目 掌握IDE的调试技巧 项目功能模块 我方飞机 敌方小型飞机 敌方中型飞机 图片资源 音效资源 游戏历史 子弹 游戏展示结果 所需技能点 python的基础,包括变量.字符串.分支.条件控制.循环等 python

python学习——飞机大战之初期

在开始正式编写飞机大战游戏之前,对pygame所提供的模块进行学习,以下代码只是验证了一些功能,并不能进行飞机大战游戏. 在开始正式的编写代码之前一定一定要先调用pygame.init()方法,并相应的调用pygame.quit()方法,这里要养成好的习惯,把成对出现的代码一并写好,以免最后忘记写,而导致错误,然后在pygame.init()与pygame.quit()之间写游戏代码. import pygame #导入pygame模块,pygame是专门设计用来设计游戏的python模块. f

500行代码,教你用python写个微信飞机大战

这几天在重温微信小游戏的飞机大战,玩着玩着就在思考人生了,这飞机大战怎么就可以做的那么好,操作简单,简单上手. 帮助蹲厕族.YP族.饭圈女孩在无聊之余可以有一样东西让他们振作起来!让他们的左手 / 右手有节奏有韵律的朝着同一个方向来回移动起来! 这是史诗级的发明,是浓墨重彩的一笔,是-- 在一阵抽搐后,我结束了游戏,瞬时觉得一切都索然无味,正在我进入贤者模式时,突然想到,如果我可以让更多人已不同的方式体会到这种美轮美奂的感觉岂不美哉? 所以我打开电脑,创建了一个 plan_game.py-- 先

pyinstaller相关问题 & pygame文件打包成exe文件 & 武装飞船 & 飞机大战

自己照书写了一个飞机大战游戏的python程序,想把它打包成一个exe文件,在查阅相关教程并经过数次尝试后终于成功. 安装打包应用 pyinstaller 在cmd命令窗口下pip install pyinstaller,安装完成. 但是由于外国的网站比较慢所以可以利用镜像来进行安装 pip install pyinstaller -i https://pypi.douban.com/simple 注意是使用https,不是http.因为https才是安全信任的网站 在cmd中输入pyinsta

基于Cocos2d-x-1.0.1的飞机大战游戏开发实例(下)

在飞机大战游戏开发中遇到的问题和解决方法: 1.在添加菜单时,我要添加一个有背景的菜单,需要在菜单pMenu中添加一个图片精灵,结果编译过了但是运行出错,如下图: 查了很多资料,调试了很长时间,整个人都要崩溃了. 最后发现引擎中CCMenu::itemForTouch函数中有遍历子节点的行为,但是循环中没有判断子节点类型是否为CCMenuItem.如图:码,这样一来,加入到pMenu中的图片精灵被当作菜单项取了出来使用,导致报错.老版本的果然又不完善的地方,整个人都不好了...果断修改引擎里的源