利用Python绘制端午节祝福动画
作者:会编程的小Y
话不多说,我就先展示效果了,如果想要代码的可以直接下载代码包
1.准备
1.1资源下载
我们下载代码包解压后目录应该如下
其中background1~background3分别是3张背景图片,其中ITCKRIST.TTF是字体文件,端午节.mp3则是背景音乐,端午节.py就是源码了。
1.2安装依赖
我们在正式开始编码前需要先安装一些依赖项,我在下面的列表中分别展示了依赖及作用
库 | 作用 |
---|---|
random | 随机数支持 |
time | 提供程序暂停 |
pygame | 提供音乐播放 |
pyglet | 读取图片 |
cocos | 菜单,粒子动画 |
我们使用按下win+r,输入cmd打开终端。
依次输入命令来安装依赖。
pip install -U pygame pip install -U pyglet pip install -U cocos2d
我们可以输入来检查安装是否成功
pip list
如果动手能力比较差的小伙伴可以直接运行代码包中的run.bat来安装依赖。失败的可以自行百度。
2.原理详解
2.1粒子动画
我们的程序中主要的便是粒子动画。究竟什么是粒子动画?
粒子动画是一种通过使用许多小的可视元素(粒子)来创建动态图像效果的技术。每个粒子都有自己的位置、速度、加速度、颜色等属性,并在时间上进行微调,以产生各种动态效果,如烟雾、火焰、水波、流星等。
其原理基于物理学和数学原理。在粒子动画中,每个粒子的运动都可以通过牛顿力学描述,如力、速度、加速度等。通常,需要应用一些物理效应,例如引力、摩擦和碰撞来模拟到达目标时的行为。
除了物理模型之外,还可以使用数学方法产生粒子动画效果。例如,使用噪声函数生成随机值,以模拟自然环境中的不规则性。
总的来说,粒子动画是一种非常有趣和令人惊叹的艺术形式,能够创建各种炫酷的视觉效果。
至于如何实现粒子动画在后面我会带大家实现。
2.2结构分析
我们的程序由一个窗口实现。而窗口则又有2个场景组成。
菜单层:又公共的background层和MainMenu菜单层组成
主场景:由动画层和背景层组成
我相信大家已经理解窗口的结构了
3.代码实现
3.1模块导入
# 导入必要的模块和库 from random import randint from time import sleep import pygame from pygame import init from pygame.mixer import music from cocos.menu import * from cocos.director import director from cocos.scene import Scene from cocos.actions import * from cocos.layer import Layer from cocos.text import Label from cocos.particle_systems import * from cocos.sprite import Sprite from cocos.scenes import * from pyglet.gl import * from pyglet import resource from pyglet.image import Animation
3.2定义公共类
# 音乐类,用来管理音乐播放 class Music: def __init__(self): init() try: music.load("端午节.mp3")#加载音乐 except: print("cannot find mp3") def play(self): music.play() # 自定义的一些粒子效果类 class MySpiral(Spiral): def __init__(self): super().__init__() self.total_particles = randint(300, 500) self.size = randint(7, 12) self.duration = randint(13, 20) self.position = (randint(100, 750), randint(100, 550)) class MyFlower(Flower): def __init__(self): super().__init__() self.total_particles = randint(300, 500) self.size = randint(12, 18) self.duration = randint(13, 20) self.position = (randint(50, 750), randint(50, 550)) class MyFlowerworks(Fireworks): def __init__(self): super().__init__() self.total_particles = randint(300, 500) self.size = randint(7, 12) self.duration = randint(13, 20) self.position = (randint(50, 750), 50) class MyExplosion(Explosion): def __init__(self): super().__init__() self.total_particles = randint(300, 500) self.size = randint(7, 12) self.duration = randint(13, 20) self.position = (randint(50, 750), randint(50, 550)) # 背景图层类,用来加载和绘制背景图像 class BackgroundLayer(Layer): def __init__(self): super().__init__() try: self.images = [resource.image("background1.png"), resource.image("background2.png"), resource.image("background3.png")]#加载图片 except: print("cannot find background image!") else: self.image = Animation.from_image_sequence(self.images, 2) self.idx = randint(0, 2) def draw(self):#绘制函数 glPushMatrix() self.transform() self.images[self.idx].blit(0, 0) glPopMatrix()
3.3定义菜单
# 菜单图层类,用来创建开始游戏的按钮和倒计时 class MenuLayer(Menu): def __init__(self): super().__init__("六一快乐") self.music = Music() music.play() self.time = 0 self.font_title["font_size"] = 64 self.font_title["color"] = (255, 128, 255, 255) self.menu_halign = CENTER self.menu_valign = CENTER self.items = [] self.items.append(MenuItem("Start", self.on_stats)) self.create_menu(self.items, shake(), shake_back()) self.schedule(self.update) def on_stats(self): director.push(MainScene()) def update(self, dt): self.time += dt if self.time >= 15.0: director.push(MainScene()) # 菜单场景类,用来加载菜单图层和背景图层 class MenuScene(Scene): def __init__(self): super().__init__() self.add(MenuLayer(), z=1) self.add(BackgroundLayer(), z=-1)
3.4定义主场景
# 游戏图层类,用来实现游戏界面和倒计时 class MainLayer(Layer): is_event_handler = True def __init__(self): super().__init__() # 设置文字的初始状态和动画效果 self.texts = [list("祝各位端午节快乐!"), list("让我们一起欢庆吧!!")] self.idx1, self.idx2 = 0, 0 self.new_text = ["", ""] try: self.text1 = Label(text=self.new_text[0], font_size=64, font_name="Kristen ITC", color=(255, 128, 255, 255), anchor_x="center", anchor_y="center", ) except: print("cannot find font file!") else: self.text1.position = (400, 450) self.text1.do(reversed(RotateBy(20, 1.5)) + spawn(Repeat(RotateBy(40, 1.5) + reversed(RotateBy(40, 1.5))), ScaleBy(1.25) + reversed(ScaleBy(1.25)))) self.add(self.text1, z=0) try: self.text2 = Label(text=self.new_text[1], font_size=64, font_name="Kristen ITC", color=(255, 128, 255, 255), anchor_x="center", anchor_y="center", ) except: print("cannot find font file!") else: self.text2.position = (400, 300) self.text2.do(reversed(RotateBy(20, 1.5)) + spawn(Repeat(RotateBy(40, 1.5) + reversed(RotateBy(40, 1.5))), ScaleBy(1.25) + reversed(ScaleBy(1.25)))) self.add(self.text2, z=0) # 添加背景图片,设置其初始位置 self.background = Sprite(BackgroundLayer().image) self.background.position = (400, 300) self.add(self.background, z=-1) # 通过循环添加部分粒子效果 for i in range(randint(15, 21)): self.systems = [MyFlower(), MyFlowerworks(), MyExplosion()] for j in range(randint(1, 3)): self.add(self.systems[randint(0, 2)], z=randint(3, 8)) self.add(MySpiral()) # 设置倒计时值,并设置定时器 self.time1 = 0 self.time2 = 0 self.schedule(self.update_systems) self.schedule(self.update_text) # 更新文字部分的动画效果,实现逐字显示 def update_text(self, dt): self.time1 += dt if self.time1 >= 1.0: if self.idx1 <= len(self.texts[0]) - 1: self.new_text[0] += self.texts[0][self.idx1] self.text1.element.text = self.new_text[0] self.idx1 += 1 if self.idx2 <= len(self.texts[1]) - 1 and self.idx1 >= 8: self.new_text[1] += self.texts[1][self.idx2] self.text2.element.text = self.new_text[1] self.idx2 += 1 self.time1 = 0 # 更新粒子效果,每隔一段时间添加新的效果 def update_systems(self, dt): self.time2 += dt if self.time2 >= randint(15, 20): for i in range(randint(15, 21)): self.systems = [MyFlower(), MyFlowerworks(), MyExplosion()] for j in range(randint(1, 3)): self.add(self.systems[randint(0, 2)], z=randint(3, 8)) self.time2 = 0 self.add(MySpiral()) # 游戏场景类,用来加载游戏图层和背景图层 class MainScene(Scene): def __init__(self): super().__init__() self.add(MainLayer(), z=2) self.add(BackgroundLayer(), z=0)
3.5创建窗口
if __name__ == '__main__': director.init(resizable=True, caption="六一快乐", width=800, height=600) director.run(MenuScene())
4.完整代码
# 导入必要的模块和库 from random import randint from time import sleep import pygame from pygame import init from pygame.mixer import music from cocos.menu import * from cocos.director import director from cocos.scene import Scene from cocos.actions import * from cocos.layer import Layer from cocos.text import Label from cocos.particle_systems import * from cocos.sprite import Sprite from cocos.scenes import * from pyglet.gl import * from pyglet import resource from pyglet.image import Animation # 音乐类,用来管理音乐播放 class Music: def __init__(self): init() try: music.load("端午节.mp3") except: print("cannot find mp3") def play(self): music.play() # 自定义的一些粒子效果类 class MySpiral(Spiral): def __init__(self): super().__init__() self.total_particles = randint(300, 500) self.size = randint(7, 12) self.duration = randint(13, 20) self.position = (randint(100, 750), randint(100, 550)) class MyFlower(Flower): def __init__(self): super().__init__() self.total_particles = randint(300, 500) self.size = randint(12, 18) self.duration = randint(13, 20) self.position = (randint(50, 750), randint(50, 550)) class MyFlowerworks(Fireworks): def __init__(self): super().__init__() self.total_particles = randint(300, 500) self.size = randint(7, 12) self.duration = randint(13, 20) self.position = (randint(50, 750), 50) class MyExplosion(Explosion): def __init__(self): super().__init__() self.total_particles = randint(300, 500) self.size = randint(7, 12) self.duration = randint(13, 20) self.position = (randint(50, 750), randint(50, 550)) # 背景图层类,用来加载和绘制背景图像 class BackgroundLayer(Layer): def __init__(self): super().__init__() try: self.images = [resource.image("background1.png"), resource.image("background2.png"), resource.image("background3.png")] except: print("cannot find background image!") else: self.image = Animation.from_image_sequence(self.images, 2) self.idx = randint(0, 2) def draw(self): glPushMatrix() self.transform() self.images[self.idx].blit(0, 0) glPopMatrix() # 菜单图层类,用来创建开始游戏的按钮和倒计时 class MenuLayer(Menu): def __init__(self): super().__init__("六一快乐") self.music = Music() music.play() self.time = 0 self.font_title["font_size"] = 64 self.font_title["color"] = (255, 128, 255, 255) self.menu_halign = CENTER self.menu_valign = CENTER self.items = [] self.items.append(MenuItem("Start", self.on_stats)) self.create_menu(self.items, shake(), shake_back()) self.schedule(self.update) def on_stats(self): director.push(MainScene()) def update(self, dt): self.time += dt if self.time >= 15.0: director.push(MainScene()) # 菜单场景类,用来加载菜单图层和背景图层 class MenuScene(Scene): def __init__(self): super().__init__() self.add(MenuLayer(), z=1) self.add(BackgroundLayer(), z=-1) # 游戏图层类,用来实现游戏界面和倒计时 class MainLayer(Layer): is_event_handler = True def __init__(self): super().__init__() # 设置文字的初始状态和动画效果 self.texts = [list("祝各位端午节快乐!"), list("让我们一起欢庆吧!!")] self.idx1, self.idx2 = 0, 0 self.new_text = ["", ""] try: self.text1 = Label(text=self.new_text[0], font_size=64, font_name="Kristen ITC", color=(255, 128, 255, 255), anchor_x="center", anchor_y="center", ) except: print("cannot find font file!") else: self.text1.position = (400, 450) self.text1.do(reversed(RotateBy(20, 1.5)) + spawn(Repeat(RotateBy(40, 1.5) + reversed(RotateBy(40, 1.5))), ScaleBy(1.25) + reversed(ScaleBy(1.25)))) self.add(self.text1, z=0) try: self.text2 = Label(text=self.new_text[1], font_size=64, font_name="Kristen ITC", color=(255, 128, 255, 255), anchor_x="center", anchor_y="center", ) except: print("cannot find font file!") else: self.text2.position = (400, 300) self.text2.do(reversed(RotateBy(20, 1.5)) + spawn(Repeat(RotateBy(40, 1.5) + reversed(RotateBy(40, 1.5))), ScaleBy(1.25) + reversed(ScaleBy(1.25)))) self.add(self.text2, z=0) # 添加背景图片,设置其初始位置 self.background = Sprite(BackgroundLayer().image) self.background.position = (400, 300) self.add(self.background, z=-1) # 通过循环添加部分粒子效果 for i in range(randint(15, 21)): self.systems = [MyFlower(), MyFlowerworks(), MyExplosion()] for j in range(randint(1, 3)): self.add(self.systems[randint(0, 2)], z=randint(3, 8)) self.add(MySpiral()) # 设置倒计时值,并设置定时器 self.time1 = 0 self.time2 = 0 self.schedule(self.update_systems) self.schedule(self.update_text) # 更新文字部分的动画效果,实现逐字显示 def update_text(self, dt): self.time1 += dt if self.time1 >= 1.0: if self.idx1 <= len(self.texts[0]) - 1: self.new_text[0] += self.texts[0][self.idx1] self.text1.element.text = self.new_text[0] self.idx1 += 1 if self.idx2 <= len(self.texts[1]) - 1 and self.idx1 >= 8: self.new_text[1] += self.texts[1][self.idx2] self.text2.element.text = self.new_text[1] self.idx2 += 1 self.time1 = 0 # 更新粒子效果,每隔一段时间添加新的效果 def update_systems(self, dt): self.time2 += dt if self.time2 >= randint(15, 20): for i in range(randint(15, 21)): self.systems = [MyFlower(), MyFlowerworks(), MyExplosion()] for j in range(randint(1, 3)): self.add(self.systems[randint(0, 2)], z=randint(3, 8)) self.time2 = 0 self.add(MySpiral()) # 游戏场景类,用来加载游戏图层和背景图层 class MainScene(Scene): def __init__(self): super().__init__() self.add(MainLayer(), z=2) self.add(BackgroundLayer(), z=0) if __name__ == '__main__': director.init(resizable=True, caption="六一快乐", width=800, height=600) director.run(MenuScene())
5.结语
在这个端午节的日子里,让我们沐浴在传统文化的氛围中,品尝粽子的美味,赛龙舟的热闹,感受古老的习俗和民族精神的魅力。让我们在这个节日里,紧紧团聚在一起,共同传承和守护这个千年的传统节日,祝福所有人都能在端午节里收获快乐和幸福!!!
以上就是利用Python绘制端午节祝福动画的详细内容,更多关于Python绘制端午节动画的资料请关注脚本之家其它相关文章!