当前位置: 首页 > news >正文

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

前言

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

我们的下一步目标是完成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 pygamepygame.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 pygamepygame.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 = Trueelif event.key == pygame.K_RIGHT:# 按右键,需要切下一首歌,所以需要将当前索引加一# 为什么要取模呢?因为播放列表的长度是有限,为了能够列表循环播放,我们需要对列表进行取模# 所以这段代码的执行结果如下:(0 + 1) % 2 = 1对应小小 (1 + 1) % 2 = 0对应情人知己  (1 + 1) % 2  (2 + 1) % 2  (3 + 1) % 2current_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 + 1pygame.mixer.music.load(playlist[current_song_index])pygame.mixer.music.play()elif event.key == pygame.K_LEFT:current_song_index = current_song_index - 1pygame.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两种事件类型,通过按键调节音频的音量。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 黑马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录 Day4
  • STM32 IIC详解(软件模拟)
  • 【GameFramework扩展应用】6-1、接入热更新框架HybridCLR
  • 服务器,云、边缘计算概念简单理解
  • 爬虫管理解决方案:让数据收集变得高效且合规
  • Redis基础教程(十五):Redis GEO地理信息查询与管理
  • 使用Apache Beam进行统一批处理与流处理
  • 【卡尔曼滤波器】DR_CAN :1_递归算法_做估计 学习笔记
  • 人脸检测+调整分辨率+调整帧率
  • 【HBZ分享】如何规避TCP的洪水攻击
  • LangChain 入门案例教程
  • github 下载提速的几种方法
  • 仕考网:公务员考试面试时间一般多长?
  • 利用Python进行数据分析PDF下载经典数据分享推荐
  • C 语言中如何实现图结构?
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • C# 免费离线人脸识别 2.0 Demo
  • GraphQL学习过程应该是这样的
  • java8-模拟hadoop
  • Java的Interrupt与线程中断
  • Linux快速复制或删除大量小文件
  • Markdown 语法简单说明
  • Spark RDD学习: aggregate函数
  • TypeScript迭代器
  • WebSocket使用
  • 产品三维模型在线预览
  • 大主子表关联的性能优化方法
  • 如何设计一个微型分布式架构?
  • 深入 Nginx 之配置篇
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 项目实战-Api的解决方案
  • Android开发者必备:推荐一款助力开发的开源APP
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • ​zookeeper集群配置与启动
  • # wps必须要登录激活才能使用吗?
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • #《AI中文版》V3 第 1 章 概述
  • #define,static,const,三种常量的区别
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • (1)SpringCloud 整合Python
  • (1)STL算法之遍历容器
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (WSI分类)WSI分类文献小综述 2024
  • (二)linux使用docker容器运行mysql
  • (二十一)devops持续集成开发——使用jenkins的Docker Pipeline插件完成docker项目的pipeline流水线发布
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (过滤器)Filter和(监听器)listener
  • (力扣题库)跳跃游戏II(c++)
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (三)Honghu Cloud云架构一定时调度平台
  • (算法)Game
  • (一)Docker基本介绍
  • (一)Kafka 安全之使用 SASL 进行身份验证 —— JAAS 配置、SASL 配置