Python 一步一步教你用pyglet制作可播放音乐的扬声器类

简介: Python 一步一步教你用pyglet制作可播放音乐的扬声器类

a73c565ec8d648768149fd14f4efed54.png

扬声器

1. 绘制喇叭

本篇将教你用pyglet画一个小喇叭,如上图。这里要用到pyglety库shapes模块中的圆弧Arc和多边形Pylygon画出这个扬声器的图片:

Arc(x, y, radius, segments=None, angle=6.283185307179586, start_angle=0, closed=False, color=(255, 255, 255, 255), batch=None, group=None)


x,y 是圆弧的圆心坐标;radius 是半径;


angle是圆心角的弧度数;


start_angle是圆弧起始的弧度数,以水平线起始时,值为0;


圆弧控件没有表示粗细的参数,只能多画几个同心圆弧来加粗。


Polygon(*coordinates, color=(255, 255, 255, 255), batch=None, group=None)


coordinates是多边形的各个端点的坐标列表,也可以写成元组方式;


多边形控件是填充形状,没有粗细参数也不能只画边线。


代码如下:

import pyglet
 
window = pyglet.window.Window(800,500)
batch = pyglet.graphics.Batch()
 
color = (255, 255, 255)
pi = 3.141592653589793
arc = []
x, y = 380, 250
for i in [*range(6),*range(18,24),*range(36,42)]:
    arc.append(pyglet.shapes.Arc(x=x, y=y, radius=50-i/2, angle=pi/2, start_angle=-pi/4, color=color, batch=batch))
 
coordinates = [x+10, y+8], [x, y+8], [x, y-8], [x+10, y-8], [x+16, y-14], [x+16, y+14]
polygon = pyglet.shapes.Polygon(*coordinates, color=color, batch=batch)
 
 
@window.event
def on_draw():
    window.clear()
    batch.draw()
 
pyglet.app.run()

2. 扬声器类

改写为一个类便于调用,可以画在任意坐标处:

class Speaker:
    def __init__(self, x, y, color=(255, 255, 255)):
        self.arc = []
        pi = 3.141592653589793
        for i in [*range(6),*range(18,24),*range(36,42)]:
                self.arc.append(pyglet.shapes.Arc(x=x, y=y, radius=50-i/2, angle=pi/2, start_angle=-pi/4, color=color, batch=batch))
        coordinates = [x+10, y+8], [x, y+8], [x, y-8], [x+10, y-8], [x+16, y-14], [x+16, y+14]
        self.polygon = pyglet.shapes.Polygon(*coordinates, color=color, batch=batch)

调用代码:

import pyglet
 
window = pyglet.window.Window(800,500)
batch = pyglet.graphics.Batch()
 
class Speaker:
    def __init__(self, x, y, color=(255, 255, 255)):
        self.arc = []
        pi = 3.141592653589793
        for i in [*range(6),*range(18,24),*range(36,42)]:
            self.arc.append(pyglet.shapes.Arc(x=x, y=y, radius=50-i/2, angle=pi/2, start_angle=-pi/4, color=color, batch=batch))
        coordinates = [x+10, y+8], [x, y+8], [x, y-8], [x+10, y-8], [x+16, y-14], [x+16, y+14]
        self.polygon = pyglet.shapes.Polygon(*coordinates, color=color, batch=batch)
 
@window.event
def on_draw():
    window.clear()
    batch.draw()
 
speaker1 = Speaker(380, 250)
speaker2 = Speaker(600, 360)
pyglet.app.run()

运行效果:

3. 禁音状态

再加两条红色直线表示禁音状态,shapes.Line用法:

Line(x, y, x2, y2, width=1, color=(255, 255, 255, 255), batch=None, group=None)

x,y, x2,y2 为直线两端点的坐标;

width为直线粗细,缺省默认值为1,直线控件有粗细的。

代码如下:

import pyglet
 
window = pyglet.window.Window(800,500)
batch = pyglet.graphics.Batch()
 
class Speaker:
    def __init__(self, x, y, color=(255, 255, 255)):
        self.arc = []
        pi = 3.141592653589793
        for i in [*range(6),*range(18,24),*range(36,42)]:
            self.arc.append(pyglet.shapes.Arc(x=x, y=y, radius=50-i/2, angle=pi/2, start_angle=-pi/4, color=color, batch=batch))
        coordinates = [x+10, y+8], [x, y+8], [x, y-8], [x+10, y-8], [x+16, y-14], [x+16, y+14]
        self.polygon = pyglet.shapes.Polygon(*coordinates, color=color, batch=batch)
        self.line1 = pyglet.shapes.Line(x, y-24, x+48, y+24, width=3, color=(255, 0, 0), batch=batch)
        self.line2 = pyglet.shapes.Line(x, y+24, x+48, y-24, width=3, color=(255, 0, 0), batch=batch)
 
@window.event
def on_draw():
    window.clear()
    batch.draw()
 
speaker1 = Speaker(380, 250)
speaker2 = Speaker(600, 360)
pyglet.app.run()

运行效果:

4. 设置状态

再为Speaker类增加两个属性和一个方法,用于设置状态:

        self.line1.visible = Flase
        self.line2.visible = Flase

    def enabled(self, enabled=True):
        self.line1.visible = self.line2.visible = not enabled

调用代码:

import pyglet
 
window = pyglet.window.Window(800,500)
batch = pyglet.graphics.Batch()
 
class Speaker:
    def __init__(self, x, y, color=(255, 255, 255)):
        self.arc = []
        pi = 3.141592653589793
        for i in [*range(6),*range(18,24),*range(36,42)]:
            self.arc.append(pyglet.shapes.Arc(x=x, y=y, radius=50-i/2, angle=pi/2, start_angle=-pi/4, color=color, batch=batch))
        coordinates = [x+10, y+8], [x, y+8], [x, y-8], [x+10, y-8], [x+16, y-14], [x+16, y+14]
        self.polygon = pyglet.shapes.Polygon(*coordinates, color=color, batch=batch)
        self.line1 = pyglet.shapes.Line(x, y-24, x+48, y+24, width=3, color=(255, 0, 0), batch=batch)
        self.line2 = pyglet.shapes.Line(x, y+24, x+48, y-24, width=3, color=(255, 0, 0), batch=batch)
        self.line1.visible = self.line2.visible = False
    def set_enabled(self, enabled=True):
        self.line1.visible = self.line2.visible = not enabled
 
@window.event
def on_draw():
    window.clear()
    batch.draw()
 
speaker1 = Speaker(380, 250)
speaker2 = Speaker(600, 360)
speaker2.set_enabled(False)
 
pyglet.app.run()

运行效果:

5. 切换状态

继续增加鼠标点击切换状态的功能,增加属性和方法:

属性:

        self.x = x
        self.y = y
        self.enabled = True

方法:
    def set_enabled(self, enabled=True):
        self.enabled = enabled
        self.line1.visible = self.line2.visible = not enabled
    def on_mouse_over(self, x, y):
        return self.x <= x <= self.x+50 and self.y-35 <= y <= self.y+35

增加鼠标点击事件:

@window.event
def on_mouse_press(x, y, button, modifier):
    if speaker1.on_mouse_over(x,y):
        speaker1.enabled = not speaker1.enabled
        speaker1.set_enabled(speaker1.enabled)
    if speaker2.on_mouse_over(x,y):
        speaker2.enabled = not speaker2.enabled
        speaker2.set_enabled(speaker2.enabled)

运行效果:分别点击两个图标,就能各自切换状态

6. 播放音乐

使用 media 模块调入mp3音乐,配合Speaker类播放

media = pyglet.media.load('voice1.mp3')
sound = pyglet.media.Player()
sound.queue(media)
sound.loop = True
sound.play()

鼠标事件中增加音乐播放和暂停的代码:

@window.event
def on_mouse_press(x, y, button, modifier):
    if speaker.on_mouse_over(x,y):
        speaker.enabled = not speaker.enabled
        speaker.set_enabled(speaker.enabled)
        if speaker.enabled:
            sound.play()
        else:
            sound.pause() 

完整代码:

import pyglet
 
window = pyglet.window.Window(800,500)
batch = pyglet.graphics.Batch()
 
class Speaker:
    def __init__(self, x, y, color=(255, 255, 255)):
        self.arc = []
        pi = 3.141592653589793
        for i in [*range(6),*range(18,24),*range(36,42)]:
            self.arc.append(pyglet.shapes.Arc(x=x, y=y, radius=50-i/2, angle=pi/2, start_angle=-pi/4, color=color, batch=batch))
        coordinates = [x+10, y+8], [x, y+8], [x, y-8], [x+10, y-8], [x+16, y-14], [x+16, y+14]
        self.polygon = pyglet.shapes.Polygon(*coordinates, color=color, batch=batch)
        self.line1 = pyglet.shapes.Line(x, y-24, x+48, y+24, width=3, color=(255, 0, 0), batch=batch)
        self.line2 = pyglet.shapes.Line(x, y+24, x+48, y-24, width=3, color=(255, 0, 0), batch=batch)
        self.line1.visible = self.line2.visible = False
        self.x = x
        self.y = y
        self.enabled = True
    def set_enabled(self, enabled=True):
        self.enabled = enabled
        self.line1.visible = self.line2.visible = not enabled
    def on_mouse_over(self, x, y):
        return self.x <= x <= self.x+50 and self.y-35 <= y <= self.y+35
 
@window.event
def on_draw():
    window.clear()
    batch.draw()
 
@window.event
def on_mouse_press(x, y, button, modifier):
    if speaker.on_mouse_over(x,y):
        speaker.enabled = not speaker.enabled
        speaker.set_enabled(speaker.enabled)
        if speaker.enabled:
            sound.play()
        else:
            sound.pause()
 
speaker = Speaker(720, 450)
 
media = pyglet.media.load('voice1.mp3')
sound = pyglet.media.Player()
sound.queue(media)
sound.loop = True
sound.play()
 
pyglet.app.run()

目录
相关文章
|
3月前
|
缓存 供应链 芯片
电子元件类商品 item_get - 商品详情接口深度分析及 Python 实现
电子元件商品接口需精准返回型号参数、规格属性、认证及库存等专业数据,支持供应链管理与采购决策。本文详解其接口特性、数据结构与Python实现方案。
|
8月前
|
人工智能 Python
[oeasy]python083_类_对象_成员方法_method_函数_function_isinstance
本文介绍了Python中类、对象、成员方法及函数的概念。通过超市商品分类的例子,形象地解释了“类型”的概念,如整型(int)和字符串(str)是两种不同的数据类型。整型对象支持数字求和,字符串对象支持拼接。使用`isinstance`函数可以判断对象是否属于特定类型,例如判断变量是否为整型。此外,还探讨了面向对象编程(OOP)与面向过程编程的区别,并简要介绍了`type`和`help`函数的用法。最后总结指出,不同类型的对象有不同的运算和方法,如字符串有`find`和`index`方法,而整型没有。更多内容可参考文末提供的蓝桥、GitHub和Gitee链接。
208 11
|
11月前
|
测试技术 Python
【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本
【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本
510 31
【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本
|
9月前
|
存储 C语言 Python
[oeasy]python077_int类型怎么用_整数运算_integer_进制转化_int类
本文主要讲解了Python中`int`类型的应用与特性。首先回顾了`int`词根的溯源,探讨了整型变量的概念及命名规则(如匈牙利命名法)。接着分析了整型变量在内存中的存储位置和地址,并通过`type()`和`id()`函数验证其类型和地址。还介绍了整型变量的运算功能,以及如何通过`int()`函数将字符串转化为整数,支持不同进制间的转换(如二进制转十进制)。此外,文章提及了关键字`del`的使用场景,对比了Python与C语言中`int`的区别,并总结了整型与字符串类型的差异,为后续深入学习奠定基础。
195 1
|
12月前
|
数据采集 存储 XML
python实战——使用代理IP批量获取手机类电商数据
本文介绍了如何使用代理IP批量获取华为荣耀Magic7 Pro手机在电商网站的商品数据,包括名称、价格、销量和用户评价等。通过Python实现自动化采集,并存储到本地文件中。使用青果网络的代理IP服务,可以提高数据采集的安全性和效率,确保数据的多样性和准确性。文中详细描述了准备工作、API鉴权、代理授权及获取接口的过程,并提供了代码示例,帮助读者快速上手。手机数据来源为京东(item.jd.com),代理IP资源来自青果网络(qg.net)。
|
Java C++ Python
Python基础---类
【10月更文挑战第10天】Python类的定义
200 2
|
索引 Python
python-类属性操作
【10月更文挑战第11天】 python类属性操作列举
144 1
|
设计模式 开发者 Python
Python类里引用其他类
Python类里引用其他类
178 4
|
机器人 关系型数据库 Python
【Python篇】Python 类和对象:详细讲解(下篇)
【Python篇】Pyt hon 类和对象:详细讲解(下篇)
167 2
|
设计模式 开发者 Python
Python 类中引用其他类的实现详解
Python 类中引用其他类的实现详解
283 1

推荐镜像

更多