Kivy小部件表现不稳​​定

时间:2017-01-12 22:27:23

标签: python kivy

我一直在玩Kivy Pong教程,熟悉框架,看看我是否可以实现一些想法。我已经删除了大部分Pong功能,所以我只能在屏幕上弹跳球并添加一些代码以在屏幕上生成多个弹跳球,触摸时生成。这工作得很好。然后我添加了一些额外的画布说明,所以我会画一条线来指示球的移动方向。这是事情变得奇怪的地方。第一个球就像它应该的那样,在屏幕周围弹跳。但任何随后的点击都会产生离开屏幕的球,随机改变方向和速度,并且通常表现得很混乱。我一直在看我的代码,我似乎无法找到任何可能出错的迹象。我保留了对小部件的所有引用,我将它们添加到根小部件,我似乎没有在它们之间共享任何信息......无论如何,这里是代码,也许有人可以启发我。使用最新的kivy和python 3.6。

from random import randint

from kivy.app import App

from kivy.clock import Clock
from kivy.config import Config
from kivy.vector import Vector
from kivy.uix.widget import Widget
from kivy.properties import AliasProperty, ListProperty, NumericProperty, ReferenceListProperty


class Playground(Widget):
    critters = ListProperty([])

    def update(self, dt):
        for critter in self.critters:
            critter.move()
            if (critter.y  self.height):
                critter.v_y *= -1
            if (critter.x  self.width):
                critter.v_x *= -1
        self.score.text = "{}".format(len(self.critters))

    def on_touch_down(self, touch):
        critter = Critter()
        critter.pos = touch.x, touch.y
        self.critters.append(critter)
        self.add_widget(critter)


class Critter(Widget):
    angle = NumericProperty(0)
    v_x = NumericProperty(0)
    v_y = NumericProperty(0)
    velocity = ReferenceListProperty(v_x, v_y)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.velocity = Vector(5, 0).rotate(randint(0, 360))
        self.angle = Vector(*self.velocity).angle(Vector(1, 0))

    def move(self):
        self.pos = Vector(*self.velocity) + self.pos
        self.angle = Vector(*self.velocity).angle(Vector(1, 0))


class WorldApp(App):
    def build(self):
        game = Playground()
        Clock.schedule_interval(game.update, 1.0/60.0)
        return game

if __name__ == '__main__':
    Config.set('kivy', 'desktop', 1)
    Config.set('kivy', 'exit_on_escape', 1)
    Config.set('graphics', 'resizable', 0)
    WorldApp().run()

和KV文件

<Playground>
    score: score

    canvas:
        Color:
            rgb: 0.0, 0.1, 0.0
        Rectangle
            pos: self.pos
            size: self.size

    Label:
        id: score
        pos: self.parent.width - self.size[0], self.parent.height - self.size[1]
        font_size: 16
        size: self.texture_size


<Critter>
    size: 30, 30
    canvas:
        Rotate:
            angle: self.angle
            origin: self.center
            axis: 0, 0, 1
        Color:
            rgb: 0.5, 0.0, 0.0
        Ellipse:
            pos: self.pos
            size: self.size
        Color:
            rgb: 1, 1, 0.0
        Line:
            width: 2
            points: self.center[0], self.center[1], self.center[0] + self.size[0] / 2, self.center[1]

1 个答案:

答案 0 :(得分:3)

我不确定它是否会导致您的问题,但您的旋转说明不受窗口小部件规则的限制,并且会影响以后的任何窗口小部件 - 因此每个Critter的旋转都应用于每隔一个。

要避免这种情况,请在画布规则的顶部添加PushMatrix:,在底部添加PopMatrix:。这些指令有效地保存,然后在更改之前恢复到初始旋转状态。