日期:2025/04/03 10:50来源:未知 人气:53
前面内容,我们详细介绍了Python中Turtle库的使用,并用一个简单的小案例展示了如何更改默认海龟形状。不可思议!Python中海龟形状可以换,终于实现了Turtle库动画效果
一只可爱的大海龟
今天,我们来个更加复杂的内容:将默认海龟形状改变后,让变形后的图形再动起来,实现真正意义上的动画效果。
我们先来看下今天的案例
今天要实现的效果
先来分析下今天这个案例
01案例分析
第一步:移动海龟(此时还不是行人哦)到道路起点。即行人下面的一条横线。这个很好实现,具体过程是这样的:先将作图动画关闭,让海龟从初始位置移动到道路起点,此处,我的坐标值是(-400, -150),大家根据自己的情况确定。这个移动过程是需要我们抬起画笔的,这个用代码可以控制。
移动行人
第二步:画出人行道。这个过程很好实现,需要注意的是,这里将人行道画出来后,我们需要将乌龟位置(此时的还不是行人的样子)重置到道路起点。
画出道路
第三步:制作海龟(本例是行人)动画效果。从前面的文章中我们知道,其实海龟的形状是可以自定义的。但这种自定义的效果一般都是静态展示在我们面前,即使是gif动态图片也只是展示其中的一帧。
动态图片
对于gif动态图片,本质上来讲,它是一个将多幅图像数据存于一起,并逐帧显示到屏幕上,形成简单动画的图像文件。
创意
那么,我们可以将动态图片拆分为一个个gif类型的静态图片,然后逐帧设置turtle的形状(这里需要循环遍历做出循环播放的效果)不就实现了我们的动画效果吗?对于这一步实现,我们暂且留到后面进行分析。
拆分gif动图为静态图片
第四步:让动态行人走起来。前面动画效果实现后,我们间隔一段时间,让行人前进一段距离,即可实现行人效果。
行人效果
02如何逐帧提取gif图像
【逐帧提取】
这里其实有很多方法,我们使用Python中的PIL(pillow)库的Image、ImageSequence两个对象可以提取gif动态图像。具体使用如下:
from PIL import Image, ImageSequence# 首先获取图像数据
im = Image.open()# 然后将图像传入到ImageSequence.Iterator()中
iters = ImageSequence.Iterator(im)# 这里的iters里面就是gif动态文件每一帧的静态图像数据,我们可以遍历获取并添加到列表中
imagelst = []for item in iters: imagelst.append(item)有了这个图像列表,对于图像处理。就很简单了,想修改、裁剪、保存都可以。
奇思妙想
这里需要注意的是,如果我们直接从网上下载一幅图片,则图片大小不可能完全满足我们的需求,比如本例中的行人,其实如果按照原图运行,它的效果是这样的
图片遮住了道路
可以看到,图片高度太高遮住了我们画出来的道路。那么,这里我们就需要进行裁剪了。如何裁剪呢?大家都有ps吧?用ps打开生成的任意一幅静态图像,操作看下图。
如何获取截取图像大小
【截取图像】
如果图像上面四个坐标值明确了,那么截取图像相对来说就很简单了。
这个region类型和上面item类型是一样的。
03如何给海龟设置动画效果
上面问题解决了,给海龟设置动画效果就简单多了。我们知道,在使用海龟自定义形状上,需要提前注册到界面。因此,我们将上面的静态图片要存储在本地(需要使用一个文件名称,因此这一步是必须的)。
动画效果
实现过程是这样的,判断注册形状中是否存在该gif图片,如果存在,直接使用即可,如果不存在,则添加注册。将上面代码放置在一个循环体中,即实现了动画轮播。这里再循环的过程中,需要判断海龟是否移动到了画布Screen之外,然后做出相应的处理。
for item in imagelst: if not '{}.gif'.format(item[0]) in screen.getshapes(): screen.register_shape('{}.gif'.format(item[0])) t.shape('{}.gif'.format(item[0])) time.sleep(0.1)这样就解决了动态展示的问题。
04几个很关键的点
我们其实可以将海龟理解为一个画布上的画笔
画笔
这点在turtle源代码中也可以看出来。比如:
RawPen = RawTurtlegetpen = getturtle大家可以在源码中搜索一下这两句。
海龟的游乐场其实和tkinter是“近亲”
比较重要的几个海龟游乐场:ScrolledCanvas(TK.Frame)、TurtleScreenBase(提供基本的图形功能,它是tkinter和turtle.py之间的接口。)、TurtleScreen(继承自TurtleScreenBase,提供面向屏幕的方法,如setbg等。只依赖TurtleScreenBase的方法,而不依赖底层图形工具包的组件,也可以把它理解为tkinter对象)
turtle和tkinter提供的默认接口都无法正常展示gif动态图片。基于上面的分析,这点很好理解了。
05其实还有一个办法可以解决该问题
喜欢学习源代码的小伙伴可以看一下turtle.py的源代码,TurtleScreen对象实例中,有一个方法ontimer(),顾名思义,这个函数应该是类似定时器之类的东西,想了解更多关于它的内容,需要看文档了。
其实,利用它也可以实现这个功能,文末源代码中会有实现效果,但个人觉得它在展现效果上没有上面提到的这种方法流畅。大家自己比较下。
好了,今天的内容就到这里了,喜欢这个小程序的小伙伴关注我,私信“turtlegif”获取源代码!这个代码其实可以改进,欢迎留言,大家一起学习进步!
本文为作者原创、首发内容,转载请注明出处,百家号:Python高手养成