首页 > 编程语言 >Python学习笔记36:进阶篇(二十五)pygame的使用之事件监听控制切歌和暂停,继续播放

Python学习笔记36:进阶篇(二十五)pygame的使用之事件监听控制切歌和暂停,继续播放

时间:2024-07-13 21:02:23浏览次数:12  
标签:index song Python 36 current 进阶篇 pygame 播放 event

前言

基础模块的知识通过这么长时间的学习已经有所了解,更加深入的话需要通过完成各种项目,在这个过程中逐渐学习,成长。

我们的下一步目标是完成python crash course中的外星人入侵项目,这是一个2D游戏项目。在这之前,我们先简单学习一下pygame模块。

私信我发送消息python资料,领取python crash course中文版PDF。

pygame

Pygame是一个开源的Python多媒体开发库,专门用于开发2D游戏。它是Python编程语言的一个扩展,基于 SDL (Simple DirectMedia Layer) 库,提供了丰富的功能来处理图形、声音、事件处理等游戏开发所需的基本要素,使得创建游戏变得更加简单直接。

事件处理

在pygame中,事件监听是游戏开发中非常关键的一部分,它允许你响应用户的输入和其他系统事件。

pygame使用一个事件队列来管理所有事件,这个队列包含了自从上一次检查以来发生的每一个事件。

# 点击关闭退出程序,这个后面再讲,代码可以先写上。
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()

这块代码大家眼熟不眼熟,基本上我们之前学习的模块中最后都以这个结尾,在窗口那一节的时候也简单讲过这段代码的作用,就是监听事件,假如事件类型是退出的话,调用pygame.quit()退出并清理pygame资源,exit()退出Python程序。

上面的代码就是最简单的事件监听。

接下来我们再仔细讲讲事件监听处理。

获取事件

每次游戏循环迭代时,通常会调用pygame.event.get()来获取并处理这些事件。没循环一次,我们就会根据监听的事件进行处理,根据预定的业务进行响应。

事件类型

我们通常根据事件的类型来判定我们需要响应的业务,并通过编写代码完成业务。

在pygame中,包含以下常用的类型:

  • pygame.QUIT: 当用户关闭窗口时触发。
  • pygame.KEYDOWN 和 pygame.KEYUP: 分别在按键按下和释放时触发。
  • pygame.MOUSEBUTTONDOWN, pygame.MOUSEBUTTONUP, pygame.MOUSEMOTION: 分别在鼠标按钮按下、释放和鼠标移动时触发。

这个几个类型,大家一看就知道能干嘛。这里就简单讲一下。

其实就是对常用操作的一些归纳,方便我们进行响应。比如我们监听到这次的事件类型是QUIT,业务代码就是清理资源,退出程序。

按键按下和鼠标按下移动都需要结合事件的属性,获取到确定的属性值后进行对应的业务处理。

比如按钮按下,我们需要根据属性值,获取按下的键是哪个,如果是空格,我们可以编写音乐暂停,游戏暂停的业务代码,假如是上下左右键,我们可以编写上一首下一首音量加减或者游戏人物前后左右移动的业务代码。

比如鼠标按下,我们同样根据属性值获取鼠标按下位置的坐标,假入是任务,进行人物对话触发的业务代码编写,假如是空白的地方,无响应或者进行人物移动的业务代码编写。

事件属性

获取事件属性 每个事件都有特定的属性,如event.pos可以获取鼠标事件的位置,event.key可以获取按键事件的键值。

事件队列清理

在处理完所有事件后,pygame.event.get()会自动从队列中移除已经处理过的事件。如果不需要处理某些类型的事件,可以传递事件类型作为参数给pygame.event.get()来过滤它们。

自定义事件

除了标准事件,你还可以定义自己的事件,使用pygame.USEREVENT加上一个整数来标识。

等待事件

如果你想让程序暂停直到某个事件发生,可以使用pygame.event.wait()。

代码示例

暂停播放与继续播放

接下来,我们通过代码来实现音乐的播放与暂停。

import pygame

pygame.init()
pygame.mixer.init()

# 没啥用的窗口,单纯为了关闭窗口退出音乐播放
screen = pygame.display.set_mode((1200, 800))

# 加载音乐
pygame.mixer.music.load('../day21/叶倩文 - 情人知己.wav')
# 播放
pygame.mixer.music.play()

# 控制音乐播放状态的变量,根据这个状态判定按空格时是要继续播放还是暂停播放
paused = True

# 点击关闭退出程序,这个后面再讲,代码可以先写上。
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                # 如果是播放状态
                if paused:
                    # 播放状态按空格,说明要暂停播放
                    pygame.mixer.music.unpause()
                    # 设置播放状态为False,表示当前处于暂停状态
                    paused = False
                # 不是播放状态那就是暂停状态
                else:
                    # 暂停状态按空格,表示要继续播放
                    pygame.mixer.music.pause()
                    # 设置播放状态为True,表示当前处于播放状态
                    paused = True

这里和后面的截图就不贴了,没啥用就一个窗口。

代码注释已经写的很详细了,这里稍微再讲一下。

实现上述功能,主要是想清楚实现业务的逻辑思维。前面的都是之前学过的基础代码,开窗口,加载音乐和播放都很简单,重点在于暂停播放暂停播放的连续性的处理。代码中我们通过一个状态标识来判定当前按下空格应该暂停还是继续播放,并且每次响应都要对应修改标识变量的值,如果想不明白, 仔细再想!还想不明白,私信我!

切歌

切歌其实就是识别按键的值是不是就行,当然还要注意的是music模块没有提供上一首下一首的功能,我们需要特殊处理才能实现。

import pygame

pygame.init()
pygame.mixer.init()

# 没啥用的窗口,单纯为了关闭窗口退出音乐播放
screen = pygame.display.set_mode((1200, 800))

# 定义播放列表
playlist = [
    '../day21/叶倩文 - 情人知己.wav',
    '../day21/容祖儿-小小.wav'
]

# 初始化播放列表的索引
current_song_index = 0

# 加载音乐
pygame.mixer.music.load(playlist[current_song_index])
# 播放
pygame.mixer.music.play()

# 控制音乐播放状态的变量,根据这个状态判定按空格时是要继续播放还是暂停播放
paused = True

# 点击关闭退出程序,这个后面再讲,代码可以先写上。
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                # 如果是播放状态
                if paused:
                    # 播放状态按空格,说明要暂停播放
                    pygame.mixer.music.unpause()
                    # 设置播放状态为False,表示当前处于暂停状态
                    paused = False
                # 不是播放状态那就是暂停状态
                else:
                    # 暂停状态按空格,表示要继续播放
                    pygame.mixer.music.pause()
                    # 设置播放状态为True,表示当前处于播放状态
                    paused = True
            elif event.key == pygame.K_RIGHT:
                # 按右键,需要切下一首歌,所以需要将当前索引加一
                # 为什么要取模呢?因为播放列表的长度是有限,为了能够列表循环播放,我们需要对列表进行取模
                # 所以这段代码的执行结果如下:(0 + 1) % 2 = 1对应小小 (1 + 1) % 2 = 0对应情人知己  (1 + 1) % 2  (2 + 1) % 2  (3 + 1) % 2
                current_song_index = (current_song_index + 1) % len(playlist)
                pygame.mixer.music.load(playlist[current_song_index])
                pygame.mixer.music.play()
            elif event.key == pygame.K_LEFT:
                # 按左键,需要切上一首歌,所以需要将当前索引减一
                # 唯一特殊的就是当current_song_index为0时,是负数的取模运算
                current_song_index = (current_song_index - 1) % len(playlist)
                pygame.mixer.music.load(playlist[current_song_index])
                pygame.mixer.music.play()

因为music模块不提供切歌功能,我们需要自己编写代码模拟实现。

那么怎么模拟呢?我们切歌其实就是修改模块加载歌曲的路径,那么是不是把这些路径放在一起,有一定的顺序,通过某种方式可以自由的获取到这些值。

这个时候我们的目标就是可以任意访问一堆有序值里面的某个我们想要访问值。那么列表是不是很明显符合我们的要求?

我们创建了一个列表,存在歌曲路径,并且定义了一个变量作为歌曲路径的索引。我们按下按钮就对索引值就行修改,索引值一修改,加载的路径也就跟着修改了。这个时候我们就会编写出以下代码:

--snip--

# 定义播放列表
playlist = [
    '../day21/叶倩文 - 情人知己.wav',
    '../day21/容祖儿-小小.wav'
]

# 初始化播放列表的索引
current_song_index = 0

--snip--
			elif event.key == pygame.K_RIGHT:
                current_song_index = current_song_index + 1
                pygame.mixer.music.load(playlist[current_song_index])
                pygame.mixer.music.play()
            elif event.key == pygame.K_LEFT:
                current_song_index = current_song_index - 1
                pygame.mixer.music.load(playlist[current_song_index])
                pygame.mixer.music.play()

这个时候你又发现,我一直按或者,索引值会不停的变大或变小,但是列表长度是有限的,那怎么办?

这个时候你的目标是什么呢? 索引值要限制在列表大小内,大于等于0。那么取模运算是不是很符合要求。 我们只要将索引值与列表长度进行取模运算,结果是不是就是0-(len-1)的范围内,正好是列表索引值的取值范围。

那么这个时候代码就变成下面这个样子:

--snip--
 		elif event.key == pygame.K_RIGHT:
            current_song_index = (current_song_index + 1) % len(playlist)
            pygame.mixer.music.load(playlist[current_song_index])
            pygame.mixer.music.play()
        elif event.key == pygame.K_LEFT:
            current_song_index = (current_song_index - 1) % len(playlist)
            pygame.mixer.music.load(playlist[current_song_index])
            pygame.mixer.music.play()

当然,这也就是我们的终极版本了。 这个时候,我们运行代码,已经可以通过可以自由切歌,并且是在列表内循环的切歌,同时也可以通过空格来暂停和继续播放音频。

结尾

事件的监听目前就讲到了这里,文章中用歌曲的播放切歌功能,验证了事件类型为按键按下的业务处理。按键弹起的类型,通常用于长按的场景,比如音量加减,按一下加一点,长按一直加,按键弹起停止加减。这个场景的代码放在作业里自行编写,写不出或者有问题可以四私信我。

鼠标相关的事件类型明后两天看一下,能不能更出来,通过按键切歌调节音量暂停这些,同时制作几个按钮通过鼠标点击来切歌调节音量暂停这些。因为是临时写,也没有去找素材啥的,所以是在窗口实现一个简陋的播放器的功能。

因为我也是在自学,我进度几乎是平齐的,以前一天两更,现在只有一更也是因为进度赶不上。

另外的话按键的值也不止这几个,大家在编写代码的时候可以找找看其他值的使用,后面我会单独出一份对照表供大家参考。

作业

  1. 监听ygame.KEYDOWN 和 pygame.KEYUP两种事件类型,通过按键调节音频的音量。

标签:index,song,Python,36,current,进阶篇,pygame,播放,event
From: https://blog.csdn.net/weixin_48668564/article/details/140387806

相关文章

  • 对红酒品质进行数据分析(python)
    http://t.csdnimg.cn/UWg2S数据来源于这篇博客,直接下载好csv文件。这篇内容均在VScode的jupyternotebook上完成,操作可以看我的另一篇博客:http://t.csdnimg.cn/69sDJ一、准备工作1.导入数据库#功能是可以内嵌绘图,并且可以省略掉plt.show()这一步,具体作用是当你调用matplo......
  • 0基础学python-10:函数的定义,调用以及参数
    目录前言1.函数的定义2.函数的调用3.函数的参数<1>必选参数<2 >默认参数<3> 可变参数<4>关键字参数 <5> 命名关键字参数 4.注意事项前言        函数是一段完成特定任务的代码块,可以通过定义、调用和传递参数来实现代码的模块化和......
  • 基于python的学生成绩管理系统(GUI)
     利用python语言实现成绩管理系统的实现,以某班学生为例,实现以下功能:(1)   添加学生信息以及其九科成绩信息;(2)   将学生信息保存在文件中;(3)   修改和删除学生信息;(4)   查询学生信息;(5)   显示已经添加的所有学生信息。设计要求:1.具有主菜单界面显示。2.有......
  • abaqus基于python二次开发——钢结构穹顶建模
    模型示意本工作旨在建立一个上表面近乎球面的钢结构穹顶。如下图所示,该穹顶由环向梁和径向梁组成。环向梁径向梁上下截面都为工字钢。环向梁截面如下图所示,环向梁截面有一个倾斜角度,为了使其上表面尽可能与球面贴合。径向梁横截面为不经过旋转的工字形代码讲解 2......
  • 使用 pip 和 requirements.txt 安装 Python 包
    1.构建当前项目需要的软件包pip3installpipreqspip3installpip-toolspipreqs--savepath=requirements.in&&pip-compile1.根据配置文件批量安装软件包。requirements.txt在某些环境中,可使用pip3而不是pippipinstall-rrequirements.txt2.检查当前环境......
  • python——数据类型及常用操作
    1.Intint是一种基本的数据类型,可以存储任意大小的整数,定义简单,将一个值赋给变量即可可以和+-*/等运算符结合a=2b=3c=a+bprint(c)d=b-apint(d)e=a*bprint(e)fa/bprint(f)a=2print(a)2.Floatfloat表示浮点数 也就是我们常说的带有小数......
  • python进程和线程_day013
    python进程和线程概念相关进程概览线程概览Python中的多进程Python中的多线程多进程还是多线程单线程+异步I/O(协程)应用案例示例1:将耗时间的任务放到线程中以获得更好的用户体验示例2:使用多进程对复杂任务进行“分而治之”。今天我们使用的计算机早已进入多CPU或多核......
  • 使用python绘制3D柱状图+完整代码展示
    一、首先进行代码效果图的展示        这是一个简单的3D模型图的展示,我们可以从官网上看到有类似的模型代码,但是大部分都没有加上全局系统配置,整体效果很单一,看不出来有什么特色,我们可以通过了解我们的python绘图工具pyecharts库。二、了解代码这个就是我们的全局......
  • python数据可视化(5)——绘制饼图
    课程学习来源:b站up:【蚂蚁学python】【课程链接:【【数据可视化】Python数据图表可视化入门到实战】】【课程资料链接:【链接】】Python绘制饼图分析北京天气饼图,是一个划分为几个扇形的圆形统计图表,能够直接以图形的方式直接显示各个组成部分所占比例目的:查看2019年北京......
  • Python数据容器(dict字典、set集合)
    dic字典dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。字典的创建使用大括号{}包含键值对,并用冒号:分隔键和值,形成键:值对。字典的特性唯一键:字典中的每个键都必须是唯一的。值可以取任何数据类型,如字符串,数字,元组。无序(Python......