Kivy:如何使用画布来动画显示图片?

9

我不太理解如何正确地使用画布(canvas)来处理带有动画的图片。

请查看附加的代码片段,在其中我将一个带有动画的图标加载到Image中,并执行以下操作: (1) 将Image添加为widget (2) 创建一个Rectangle画布指令,其中texture = Image的texture

图像会动画化显示。 矩形纹理则不会。

我已经阅读了Kivy手册中的所有内容,并阅读了有关Image和Canvas的内容。我的理解是,Image是一个很好的高级类,可以处理所有这些图像动画,而Canvas则更像是一个原始的低级绘图画布。

那么这里就有一个问题:在Canvas上处理动画的Kivy-correct架构是什么?我查看了Animation,但似乎它适用于更多的矩阵动画,例如平移、缩放、旋转。

这是我目前正在做的: 我有一个大地图窗口的游戏,以及一堆辅助窗口的游戏UX。 在游戏UX辅助窗口中,我做了所有的kivy布局等工作,通常使用Images,因此我的图标呈现出流畅的动画效果。

然而,在游戏地图中,我使用canvas:

使用以下范例绘制所有游戏对象:

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个回答

4

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属性上,以便每次它改变时,我可以相应地更新矩形。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接