Kivy:用画布为图像制作动画的正确方法是啥?

Posted

技术标签:

【中文标题】Kivy:用画布为图像制作动画的正确方法是啥?【英文标题】:Kivy: what is the proper method for animating images with canvas?Kivy:用画布为图像制作动画的正确方法是什么? 【发布时间】:2018-06-16 21:12:08 【问题描述】:

我不完全了解如何正确使用画布处理带有动画的图像。

查看附加的 sn-p,我在其中将动画图标加载到图像中并同时执行以下操作: (1) add_widget 图片 (2) 创建一个 Rectangle canvas 指令,texture = Image's texture

图像动画 矩形纹理没有

我已经阅读了所有 Kivy 手册并阅读了 Image 和 Canvas,我认为 Image 是一个很好的高级类,具有所有这些图像动画处理,而 Canvas 更像是一个原始的低级绘图画布.

所以这是我的问题 - 在 Canvas 上处理动画的 Kivy 正确架构是什么?我查看了动画,但这似乎是更多类似矩阵的动画,例如平移、缩放、旋转。

这是我现在正在做的事情: 我有大地图窗口的游戏,然后是帮助窗口中的一堆游戏 UX 游戏 UX 帮助窗口我做了所有的 kivy 布局等,并且通常使用图像,所以我的图标动画效果很好

但是在游戏地图中,我使用的是画布:

使用此范例绘制我所有的游戏对象:

r=Rectangle(texture=some_Image.texture)
map.canvas.add(r)

当需要重新绘制世界时:

1)map.canvas.clear()

2) 以新的位置和状态绘制所有的东西 (为了更快,我应该只跟踪脏对象和位置并绘制它们,但老实说,即使每次绘制都具有这种核级清晰,我也能获得出色的 fps)

这当然比创建和销毁数百个小部件类更快更轻——地图画布的用途是什么——对吧?

但问题是我的 zip 文件中带有动画的图标没有动画

问:我认为画布有误吗?我应该改为为每个游戏对象添加一个图像吗? (并利用所有动画图像支持?)

from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.image import Image
from kivy.app import App
from kivy.graphics import Rectangle


class MainApp(App):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.root = RelativeLayout()

        # use any zip file of an animated image
        self.animated_icon = Image(source='factory_icon.zip')

        # If I add an Image, the icon animates
        self.root.add_widget(self.animated_icon)

        # If I add the Image's texture on to a Rectangle instruction, no animation
        r = Rectangle(texture=self.animated_icon.texture, size=(100, 100), pos=(100, 100))
        self.root.canvas.add(r)

    def build(self):
        return self.root


if __name__ == '__main__':
    MainApp().run()

【问题讨论】:

【参考方案1】:

Image.texture 属性随时间变化。它在内部调度方法以在动画进行时对其进行更新。此更改不会传播到您的矩形,因为您使用在更新之间的某个特定时间点捕获的纹理值创建了它。考虑这个例子(我用.gif文件做动画,但原理应该是一样的):

from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.image import Image
from kivy.app import App
from kivy.graphics import Rectangle


class MainApp(App):
    def __init__(self, **kwargs):
        super(MainApp, self).__init__(**kwargs)
        self.root = RelativeLayout()

        animated_icon = Image(source='test.gif')
        animated_icon.bind(texture=self.update_texture)

        self.r = Rectangle(texture=animated_icon.texture, size=(500, 255), pos=(100, 100))
        self.root.canvas.add(self.r)

    def update_texture(self, instance, value):
        self.r.texture = value

    def build(self):
        return self.root


if __name__ == '__main__':
    MainApp().run()

在这里,我将自己的 update_texture 方法绑定到图像的 texture 属性,因此每次更改时,我都可以相应地更新矩形。

【讨论】:

以上是关于Kivy:用画布为图像制作动画的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用算法制作动画 GIF 的最佳方法是啥?

使用画布的 HTML5 中的逐帧动画

Kivy,从python文件更改画布的源图片

一种在画布中“切换”图像的方法,就好像它是 gif

为啥在 html5 中使用画布制作动画?

工件出现在 iOS 上动态生成的动画画布图像上