在Kivy中创建D-pad(约束移动)

时间:2017-11-02 05:08:17

标签: python-2.7 layout pycharm kivy d-pad

我很擅长使用Kivy进行任务,我对一个具体问题感到难过。我的目标是创建一个方向键,如下图所示,蓝色圆圈将从图像的中心开始,并且可以被拖动,但圆圈只能沿箭头所示的方向行进(向上,向下,向左,向右)并且不能超过箭头。现在,我只关心图形布局,所以我所做的只是一个下面有拖动行为的小部件。是否有某种方法可以限制圆圈的运动?

图像: The current achievable graphical layout for the d-pad

Python代码:

from kivy.uix.widget import Widget
from kivy.uix.behaviors import DragBehavior
from kivy.app import App

class Circle(DragBehavior, Widget):

    def on_touch_move(self, touch):
        tx, ty = touch.pos
        sx, sy = self.pos
        return super(Circle, self).on_touch_move(touch)

class Test(Widget):
    pass

class TestApp(App):
    def build(self):
        return Test()

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

Kivy档案:

<Circle>:
    size: 100,74
    drag_rectangle: self.x+36, self.y+28, 16, 25
    drag_timeout: 10000000
    drag_distance: 0
    canvas:
        Color:
            rgba: 0,0,1,.5
        Ellipse:
            pos: self.pos
            size: self.size


<Test>:
    canvas.before:
        Color:
            rgba: 1,1,1,1
       Rectangle:
            size: root.width,root.height
            pos: 0,0
    canvas:
        Color:
            rgba: 1,1,1,1
        Rectangle:
            size: root.width,root.height
            pos: 0,0
            source: 'icons/XY_bar.png'
    Circle:
        pos: root.width/2.3,root.height/2.25

1 个答案:

答案 0 :(得分:0)

这只是一些提示,蓝色圆圈并不完全限于轴

的.py

from kivy.uix.widget import Widget
from kivy.uix.behaviors import DragBehavior
from kivy.app import App
from kivy.properties import ObjectProperty, NumericProperty
from kivy.clock import Clock


class Circle(DragBehavior, Widget):

    def on_touch_move(self, touch):
        if self.collide_point(*touch.pos):
            if self.parent.redliney <= touch.pos[1] <= self.parent.redliney + 100:
                return super(Circle, self).on_touch_move(touch)
            elif self.parent.greenlinex <= touch.pos[0] <= self.parent.greenlinex + 100:
                return super(Circle, self).on_touch_move(touch)

    def on_touch_down(self, touch):
        if self.collide_point(*touch.pos):
            if self.parent.redliney <= touch.pos[1] <= self.parent.redliney + 100:
                return super(Circle, self).on_touch_down(touch)
            elif self.parent.greenlinex <= touch.pos[0] <= self.parent.greenlinex + 100:
                return super(Circle, self).on_touch_down(touch)

    def on_touch_up(self, touch):
        if self.collide_point(*touch.pos):
            if self.parent.redliney <= touch.pos[1] <= self.parent.redliney + 100:
                return super(Circle, self).on_touch_up(touch)
            elif self.parent.greenlinex <= touch.pos[0] <= self.parent.greenlinex + 100:
                return super(Circle, self).on_touch_up(touch)


class Test(Widget):
    c = ObjectProperty()
    joystick_x = NumericProperty(0)
    joystick_y = NumericProperty(0)
    redlinex = NumericProperty(0)
    redliney = NumericProperty(0)
    greenlinex = NumericProperty(0)
    greenliney = NumericProperty(0)

    def __init__(self, **kwargs):
        super(Test, self).__init__(**kwargs)
        Clock.schedule_interval(self.update, 1/10.0)

    def update(self, *args):
        self.joystick_x = self.c.pos[0]
        self.joystick_y = self.c.pos[1]


class TestApp(App):
    def build(self):
        return Test()

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

KV

<Test>:
    c: c
    redlinex: self.pos[0] + self.size[0]/8.0
    redliney: self.pos[1] + self.size[1]/2.0 - 50
    greenlinex: self.pos[0] +self.size[0]/2.0 - 50
    greenliney: self.pos[1] + self.size[1]/8.0
    canvas.before:
        Color:
            rgba: 1,1,1,1
        Rectangle:
            size: self.size
            pos: self.pos
        Color:
            rgba: .75,.75,.75,1
        Ellipse:
            pos: root.joystick_x - 50, root.joystick_y - 50
            size: 200, 200
        Color:
            rgba: 1,0,0,1
        Rectangle:
            pos: root.redlinex, root.redliney
            size: 3 * self.size[0]/4.0, 100
        Triangle:
            points: root.redlinex, root.redliney, root.redlinex - 50, root.redliney + 50, root.redlinex, root.redliney + 100
        Triangle:
            points: root.redlinex + 3 * self.size[0]/4.0, root.redliney, root.redlinex + 3 * self.size[0]/4.0 + 50, root.redliney + 50, root.redlinex + 3 * self.size[0]/4.0, root.redliney + 100
        Color:
            rgba: .33, .51, .21, 1
        Rectangle:
            pos: root.greenlinex, root.greenliney
            size: 100, 3 * self.size[1]/4.0
        Triangle:
            points: root.greenlinex, root.greenliney, root.greenlinex + 50, root.greenliney - 50, root.greenlinex + 100, root.greenliney
        Triangle:
            points: root.greenlinex, root.greenliney + 3 * self.size[1]/4.0, root.greenlinex + 50, root.greenliney + 3 * self.size[1]/4.0 + 50, root.greenlinex + 100, root.greenliney + 3 * self.size[1]/4.0
    Circle:
        canvas:
            Color:
                rgba: .16, .25, .6, 1
            Ellipse:
                pos: self.pos
                size: self.size
        id: c
        pos: root.pos[0] + root.size[0]/2.0 - 50, root.pos[1] + root.size[1]/2.0 - 50
        size: 100, 100
        drag_rectangle: self.x, self.y, self.width, self.height
        drag_timeout: 10000000
        drag_distance: 0

输出

pic1

pic2