Kivy Canvas在触摸事件后重绘

时间:2014-05-31 08:37:04

标签: python kivy



我想做一个小游戏,但我需要一些帮助......我在python和kivy都很新手。我正在使用python 3.4和kivy 1.8.0。

游戏将有一些可拖动和/或消失的绘制元素:
- 如果你点击一个点就可以拖动它 - 如果你点击任何地方,一个点就会消失

我试图让它消失,但我卡住了。 我用画布上的一些点制作了一个虚拟代码,在那里你可以看到我想要解决的问题:
- >得出一些要点 - >删除/重新定位一个点
- >透明帆布
- >重绘

不知怎的,我无法重绘它。但我设法清理画布......你能帮我吗? 另外,我想得到帮助/想法如何使其可拖动......

谢谢,这是我的代码:

from kivy.app import App
from kivy.graphics import Ellipse
from kivy.uix.boxlayout import BoxLayout
import random

class CustomLayout(BoxLayout):

    def __init__(self, **kwargs):
        super(CustomLayout, self).__init__(**kwargs)
        self.a = []
        self.points_pos()
        with self.canvas.after:
            self.draw_points()

    def points_pos(self):
        i=0
        x = random.sample(range(800), 10)
        y = random.sample(range(640), 10)
        for i in range(10):
            pos = [0,0]
            pos[0]=x[i]
            pos[1]=y[i]
            self.a.append(pos)
        print(self.a)

    def draw_points(self):
        i = 0
        for i in range(len(self.a)):
            self.circle = Ellipse(
                size = (25,25),
                pos =  (self.a[i][0],self.a[i][1])
                )

    def random_remove(self):
        point = self.a[random.randint(0,len(self.a)-1)]
        self.a.remove(point)


    def update(self):
        self.parent.canvas.clear()
        with self.canvas:
            self.draw_points()

    def on_touch_down(self, touch):
        self.random_remove()
        self.update()

class MainApp(App):

    def build(self):
        root = CustomLayout()
        return root

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

2 个答案:

答案 0 :(得分:2)

def update(self):
    self.parent.canvas.clear()
    with self.canvas:
        self.draw_points()

清除父级的画布,其中包含BoxLayout的画布。在那之后,你在BoxLayout上绘制了多少东西并不重要,它们将永远不会显示出来。

要解决此问题,您可能只想简单地执行self.canvas.clear(),但实际上这是非常低效的,并且不适合使用kivy的画布(尽管它适用于少量指令)。最好保留对所有画布说明的引用,并仅使用self.canvas.remove(...)删除不再需要的特定画面。

答案 1 :(得分:0)

由于这个问题在我除外时得到了更多的观点,我在这里留下一个有效的例子:

from kivy.app import App
from kivy.logger import Logger
from kivy.graphics import Color, Ellipse, Line
from kivy.uix.boxlayout import BoxLayout


class CustomLayout(BoxLayout):

    def __init__(self, **kwargs):
        super(CustomLayout, self).__init__(**kwargs)

        self.canvas_edge = {}
        self.canvas_nodes = {}
        self.nodesize = [25, 25]

        self.grabbed = {}

        #declare a canvas
        with self.canvas.after:
            pass

        self.define_nodes()
        self.canvas.add(self.canvas_nodes[0])
        self.canvas.add(self.canvas_nodes[1])
        self.define_edge()
        self.canvas.add(self.canvas_edge)



    def define_nodes(self):
        """define all the node canvas elements as a list"""

        self.canvas_nodes[0] = Ellipse(
            size = self.nodesize,
            pos =  [100,100]
            )

        self.canvas_nodes[1] = Ellipse(
            size = self.nodesize,
            pos =  [200,200]
            )

    def define_edge(self):
        """define all the edge canvas elements as a list"""


        self.canvas_edge = Line(
            points =  [
                self.canvas_nodes[0].pos[0] + self.nodesize[0] / 2,
                self.canvas_nodes[0].pos[1] + self.nodesize[1] / 2,
                self.canvas_nodes[1].pos[0] + self.nodesize[0] / 2,
                self.canvas_nodes[1].pos[1] + self.nodesize[1] / 2
                ],
            joint = 'round',
            cap = 'round',
            width = 3
            )


    def on_touch_down(self, touch):

        for key, value in self.canvas_nodes.items():
            if (value.pos[0] - self.nodesize[0]) <= touch.pos[0] <= (value.pos[0] + self.nodesize[0]):
                if (value.pos[1] - self.nodesize[1]) <= touch.pos[1] <= (value.pos[1] + self.nodesize[1]):
                    touch.grab(self)
                    self.grabbed = self.canvas_nodes[key]
                    return True

    def on_touch_move(self, touch):

        if touch.grab_current is self:
            self.grabbed.pos = [touch.pos[0] - self.nodesize[0] / 2, touch.pos[1] - self.nodesize[1] / 2]
            self.canvas.clear()
            self.canvas.add(self.canvas_nodes[0])
            self.canvas.add(self.canvas_nodes[1])
            self.define_edge()
            self.canvas.add(self.canvas_edge)
        else:
            # it's a normal touch
            pass

    def on_touch_up(self, touch):
        if touch.grab_current is self:
            # I receive my grabbed touch, I must ungrab it!
            touch.ungrab(self)
        else:
            # it's a normal touch
            pass

class MainApp(App):

    def build(self):
        root = CustomLayout()
        return root

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