簡體   English   中英

如何在kivy的單個屏幕上獨立旋轉兩個矩形小部件?

[英]How to rotate two rectangle widgets independently on single screen in kivy?

我正在學習 Python 編程並開發一個簡單的游戲應用程序,在該應用程序中我需要在單個屏幕上單擊兩個矩形時旋轉它們,但是發生的情況是當我單擊其中一個時,兩個矩形都沿該矩形的原點旋轉正在被點擊,但另一個矩形不是這種情況,實際上它的位置也不是應該的位置,當點擊指定的位置(該矩形不存在的地方)時,它會旋轉而不旋轉兩個矩形. 我只需要在獨立單擊時旋轉兩個矩形。 很難解釋,所以請嘗試執行代碼並找出發生了什么。

from kivy.app import App
from kivy.graphics import Rotate, Rectangle, Ellipse, Color
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen, CardTransition
from kivy.uix.widget import Widget
from kivy.properties import ObjectProperty, NumericProperty, ReferenceListProperty, ListProperty
from kivy.uix.floatlayout import FloatLayout

Builder.load_string('''

<Stage_2>:
    object2: Object2
    object3: Object3

    Object2:
        id: Object2
        center: self.rotate_origin

    Object3:
        id: Object3
        center: self.rotate_origin

<Manager>:
    id: screen_manager

    Screen:
        name:"P"
        FloatLayout:

            Button:
                pos_hint:{"x":0.2,"y":0.05}
                size_hint: 0.6, 0.2
                font_size: (root.width**2 + root.height**2) / 13**4
                text: "Play"
                background_color: 255,0,1,1
                on_release:
                    root.transition.direction = "up"        
                    root.current = "stage2"

    Screen:
        name: 'stage2'
        Stage_2:
            id:s2

''')

class Object2(Widget):
    def __init__(self, *args, **kwargs):
        Widget.__init__(self, *args, **kwargs)
        self.rect_pos_x = 500
        self.rect_pos_y = 425
        self.rect_pos = self.rect_pos_x, self.rect_pos_y
        self.rect_width = 150
        self.rect_height = 30
        self.rect_size = self.rect_width, self.rect_height
        self.rotate_origin_x = self.rect_pos_x + self.rect_width / 2
        self.rotate_origin_y = self.rect_pos_y + self.rect_height / 2
        self.rotate_origin = self.rotate_origin_x, self.rotate_origin_y
        self.angle = 135
        print('rect 1')
        with self.canvas:
            Rotate(origin=self.rotate_origin, angle=self.angle)
            Color(rgb=(0,197,68))
            Rectangle(pos=self.rect_pos, size=self.rect_size)

    def rotate(self):
        self.canvas.clear()
        self.angle += 90
        if (self.angle > 315):
            self.angle = 225
        with self.canvas:
            Rotate(origin=self.rotate_origin, angle=self.angle)
            Color(rgb=(0, 255, 100))
            Rectangle(pos=self.rect_pos, size=self.rect_size)

    def on_touch_up(self, touch):
        if self.collide_point(*touch.pos):
            self.rotate()
            print(self.angle)
class Object3(Widget):
    def __init__(self, *args, **kwargs):
        Widget.__init__(self, *args, **kwargs)
        self.rect_pos_x = 500
        self.rect_pos_y = 250
        self.rect_pos = self.rect_pos_x, self.rect_pos_y
        self.rect_width = 150
        self.rect_height = 30
        self.rect_size = self.rect_width, self.rect_height
        self.rotate_origin_x = self.rect_pos_x + self.rect_width / 2
        self.rotate_origin_y = self.rect_pos_y + self.rect_height / 2
        self.rotate_origin = self.rotate_origin_x, self.rotate_origin_y
        self.angle = 135
        print('rect 2')
        with self.canvas:
            Rotate(origin=self.rotate_origin, angle=self.angle)
            Color(rgb=(1,255,0))
            Rectangle(pos=self.rect_pos, size=self.rect_size)

    def rotate(self):
        self.canvas.clear()
        self.angle += 90
        if (self.angle > 315):
            self.angle = 225
        with self.canvas:
            Rotate(origin=self.rotate_origin, angle=self.angle)
            Color(rgb=(0, 255, 100))
            Rectangle(pos=self.rect_pos, size=self.rect_size)

    def on_touch_up(self, touch):
        if self.collide_point(*touch.pos):
            self.rotate()
            print(self.angle)

class Stage_2(Widget):
    object2 = ObjectProperty(None)
    object3 = ObjectProperty(None)

class Manager(ScreenManager):
    pass

sm = Manager()

class ScreensApp(App):
    def build(self):
        return sm

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

如果您在canvas指令中包含PushMatrix()PopMatrix() ,則只有當前的Widget會受到影響。 然后,如果您將Widget sizepos調整為Rectangle size和位置,您應該會獲得更好(但不完美)的collide_point性能:

    with self.canvas:
        PushMatrix()
        Rotate(origin=self.rotate_origin, angle=self.angle)
        Color(rgb=(1,255,0))
        Rectangle(pos=self.rect_pos, size=self.rect_size)
        PopMatrix()
        self.pos = self.rect_pos
        self.size = self.rect_size

每當您使用涉及RotationScaleTranslate with self.canvas時,都需要這樣做。 collide_point()仍然會查看Widget sizepos ,而不是Rectangle ,但至少Widget的中心和它的Rectangle應該重合。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM