一、前言
现在看动漫,追电视剧,如果不开弹幕,感觉都失去了灵魂,不知道大家是不是也和我一样的感觉。于是突发奇想,弹幕可不可以让他显示在桌面上呢?在之前,我们已经可以在桌面上画上一堆可爱的爱心,为了让这些弹窗更加“惹人喜爱”,我们是不是可以将他们结合起来。先看效果
二、需求
我们需要实现弹幕,需要考虑好我们需要实现达到什么效果。
- 需要有弹幕滚动效果
- 有文字,有爱心
- 屏幕显示位置(上,中,下,全屏)
- 数量要多。
三、思路
已经有需求了,我们来整理一下思路:
- 实现一个窗口,窗口添加文字,或者爱心
- 让窗口滚动起来
- 控制弹幕出现的位置
- 控制弹幕的数量
要点:
- 考虑到弹窗位置多变,因此我们统一设置为区间,可控。
- 当弹幕滚动出屏幕之后,我们需要关闭弹幕或者重新开始滚动。
四、需求实现
第一步:实现窗口,添加文字或者爱心
在之前我们已经实现了一个弹窗的编写,还是比较简单的,这次,我们需要将爱心,和文字分开,方便后面的弹幕实现。
桃心弹幕
def barrage_love(self):
color="pink"
# 绘制左半边180度的一个扇形
coordinate=(50.0, 50.0, 100, 100)
self.semicircle=self.canvas.create_arc(coordinate, start=0, extent=180, fill=color, outline=color)
# 绘制右半边180度的一个扇形
coordinate =(100, 50.0, 150.0, 100)
self.semicircle2=self.canvas.create_arc(coordinate, start=0, extent=180, fill=color, outline=color)
# 绘制1个三角形,组成桃心形状
coordinate =(50.0, 75.0, 150.0, 75.0, 100, 125.0)
self.triangle=self.canvas.create_polygon(coordinate, fill=color, outline=color)
文字的话,因为是弹幕,数量肯定很多,因此我们用列表来管理我们需要的弹幕文字,这里我简单放入几个弹幕。并随机写入弹幕中。
文字弹幕
def barrage_text(self):
text_list=["∑(っ°Д°;)っ握抄","(*^▽^*)",
"!!!∑(゚Д゚ノ)ノ","Σσ(・Д・;)我我我什么都没做!!!",
"(づ ̄3 ̄)づ╭❤~","๑乛◡乛๑卡在了奇怪的地方"]
self.canvas.create_text(100,80,text=random.choice(text_list),font=("Segoe UI Black",18)#font,设置字体,大小
我们可以控制字体,以及字体的大小,按照需要设置。
print(list(tkFont.families()))
使用这行代码,查看支持的字体。
做到这里,突然发现,我们的窗口如果依次调用函数的方式,
self.barrage_love()
self.barrage_text()
会发现,桃心出来了,文字一起出来了,但我们需要的是其中一个就可以,那要如何达到这种目的呢?
if random.randint(1,3)==1 :
self.barrage_love()
else:
self.barrage_text()
可以简化为:
self.barrage_love() if random.randint(1,3)==1 else self.barrage_text()
如果随机到1,就是桃心弹幕,如果随机到2,就是文字弹幕。
第二步:让窗口滚动起来
我们已经搞定基础的弹幕准备条件,接下来就需要让我们的弹幕动起来。需要移动,因此,我们需要再次对坐标进行讨论。
之前,我们已经知道,在屏幕上的坐标轴。
在此基础上,我们需要在坐标水平移动,那移动的函数图像,就为
f ( x)= b ( b∈ R)
也就是说,当y逐渐增大,x不变。因此我们就得到了弹窗的移动路径。得到了移动路径,那如何移动窗口的位置呢?这里我们就用到窗口更新方法。update()
然后我们来实现。y增加,x不变。就得到:
def move(self):
self.y=str(int(self.y)+1)
self.tk.geometry("600x200+" + str(self.y) + "+" + str(self.x))
self.tk.update()
self.tk.destroy() if int(self.y)>=self.w else self.move()
这里,我们处理超过边界,如果超过之后,我们就关闭弹窗。另外一种方式,超过,我们进入循环,重新开始。
def move(self):
self.y=str(int(self.y)+1)
self.tk.geometry("600x200+" + str(self.y) + "+" + str(self.x))
self.tk.update()
if int(self.y)>=self.w :
self.y=-200
self.move()
else:self.move()
如果超过了,我们就将y定义为负数,保证文字从左边慢慢出来,如果设置为0,就会出现突然出现一行字的情况,而不是慢慢出现。
这里,我们使用到了递归的方法,重复去调用move方法。以达到移动的目的。
需要注意的是,当递归超过一定次数时,就会报措。因为这个是程序默认的递归次数。如果出现下面这个错误,你成功遇到了递归的第一个坑。
那如何解决这个问题呢?
这里我们需要自己设置,去修改它的默认值,防止报措。
import sys
sys.setrecursionlimit(100000000)
#我们可以通过sys.getrecursionlimit()这个方法去获取默认值。
第三步:控制弹幕出现的位置
我们已经可以控制弹幕的移动,接下来就是控制弹幕的出现位置。控制弹幕出现位置,需要修改的是窗口的坐标。因此就可以修改坐标位置。
弹幕出现在上半部分屏幕
self.w=self.tk.winfo_screenwidth()#获取宽度
self.h=self.tk.winfo_screenheight()#获取高度
self.x=str(random.randint(0, self.h/3))
self.y=str(random.randint(0, self.w))
self.tk.geometry("600x200+"+self.y+"+"+self.x)#宽x高+y+x,其中y表示y轴点,x表示x轴点
弹幕出现在中间部分屏幕
self.w=self.tk.winfo_screenwidth()#获取宽度
self.h=self.tk.winfo_screenheight()#获取高度
self.x=str(random.randint(self.h/3, self.h*2/3))
self.y=str(random.randint(0, self.w))
self.tk.geometry("600x200+"+self.y+"+"+self.x)#宽x高+y+x,其中y表示y轴点,x表示x轴点
弹幕出现在下半部分屏幕
self.w=self.tk.winfo_screenwidth()#获取宽度
self.h=self.tk.winfo_screenheight()#获取高度
self.x=str(random.randint(self.h*2/3, self.h))
self.y=str(random.randint(0, self.w))
self.tk.geometry("600x200+"+self.y+"+"+self.x)#宽x高+y+x,其中y表示y轴点,x表示x轴点
弹幕出现在整个屏幕区域
self.w=self.tk.winfo_screenwidth()#获取宽度
self.h=self.tk.winfo_screenheight()#获取高度
self.x=str(random.randint(0, self.h))
self.y=str(random.randint(0, self.w))
self.tk.geometry("600x200+"+self.y+"+"+self.x)#宽x高+y+x,其中y表示y轴点,x表示x轴点
第四步:控制弹幕的数量
接下来,我们需要将弹窗数量增加到我们需要的数量,也是为了给她惊喜是吧。增加延时,让弹窗依次延迟生成。
if __name__ == '__main__':
for i in range(10):
t=threading.Thread(target=Window)
t.start()
time.sleep(1)
第五步:各种弹幕展示
爱心弹幕
文字弹幕
爱心文字弹幕
从右往左
五、文章总结
文章主要使用模块tkinter,tkinter更新窗口方式实现移动,递归的简单应用。线程组的简单应用。函数图像 f ( x)= b ( b∈ R) 的应用。
获取完整代码:公众号回复 “爱心弹窗”