Python 如何在kivy中在单个屏幕上独立旋转两个矩形部件?

Python 如何在kivy中在单个屏幕上独立旋转两个矩形部件?,python,python-3.x,kivy,kivy-language,Python,Python 3.x,Kivy,Kivy Language,我正在学习python编程,并在一个简单的游戏应用程序中工作,在这个应用程序中,我需要在单屏幕上单击两个矩形,但当我单击其中一个矩形时,两个矩形都会沿着被单击矩形的原点旋转,但另一个矩形不是这样,事实上,它的位置也不是预期的位置,当单击指定的位置(该矩形不存在的位置)时,它会在不旋转两个矩形的情况下旋转。我只需要在单击时旋转两个矩形。 很难解释,所以请尝试执行代码并找出发生了什么 from kivy.app import App from kivy.graphics import Rotate,

我正在学习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()
从kivy.app导入应用
从kivy.graphics导入旋转、矩形、椭圆、颜色
从kivy.lang导入生成器
从kivy.uix.screenmanager导入screenmanager、Screen、CardTransition
从kivy.uix.widget导入widget
从kivy.properties导入ObjectProperty、NumericProperty、ReferenceListProperty和ListProperty
从kivy.uix.floatlayout导入floatlayout
Builder.load_字符串(“”)
:
object2:object2
object3:object3
目标2:
id:Object2
中心:自旋转原点
目标3:
id:Object3
中心:自旋转原点
:
id:屏幕管理器
屏幕:
名称:“P”
浮动布局:
按钮:
pos_提示:{“x”:0.2,“y”:0.05}
尺寸提示:0.6,0.2
字体大小:(根.宽**2+根.高**2)/13**4
文字:“播放”
背景颜色:255,0,1,1
发布时:
root.transition.direction=“向上”
root.current=“stage2”
屏幕:
名称:'stage2'
第二阶段:
编号:s2
''')
类Object2(小部件):
定义初始化(self,*args,**kwargs):
Widget.\uuuu初始化(self,*args,**kwargs)
self.rect\u pos\u x=500
self.rect_pos_y=425
self.rect\u pos=self.rect\u pos\u x,self.rect\u pos\y
self.rect_width=150
自校正高度=30
self.rect\u size=self.rect\u宽度,self.rect\u高度
self.rotate\u origin\u x=self.rect\u pos\u x+self.rect\u width/2
self.rotate\u origin\u y=self.rect\u pos\u y+self.rect\u height/2
self.rotate\u origin=self.rotate\u origin\u x,self.rotate\u origin\u y
自转角=135
打印('rect 1')
使用self.canvas:
旋转(原点=self.Rotate\u原点,角度=self.angle)
颜色(rgb=(0197,68))
矩形(pos=self.rect\u pos,size=self.rect\u size)
def旋转(自):
self.canvas.clear()
自转角+=90
如果(自转角>315):
自转角=225
使用self.canvas:
旋转(原点=self.Rotate\u原点,角度=self.angle)
颜色(rgb=(0255100))
矩形(pos=self.rect\u pos,size=self.rect\u size)
def on_touch_up(自我,触摸):
如果自碰撞点(*touch.pos):
self.rotate()
打印(自角度)
类Object3(小部件):
定义初始化(self,*args,**kwargs):
Widget.\uuuu初始化(self,*args,**kwargs)
self.rect\u pos\u x=500
self.rect_pos_y=250
self.rect\u pos=self.rect\u pos\u x,self.rect\u pos\y
self.rect_width=150
自校正高度=30
self.rect\u size=self.rect\u宽度,self.rect\u高度
self.rotate\u origin\u x=self.rect\u pos\u x+self.rect\u width/2
self.rotate\u origin\u y=self.rect\u pos\u y+self.rect\u height/2
self.rotate\u origin=self.rotate\u origin\u x,self.rotate\u origin\u y
自转角=135
打印('rect 2')
使用self.canvas:
旋转(原点=self.Rotate\u原点,角度=self.angle)
颜色(rgb=(1255,0))
矩形(pos=self.rect\u pos,size=self.rect\u size)
def旋转(自):
self.canvas.clear()
自转角+=90
如果(自转角>315):
自转角=225
使用self.canvas:
旋转(原点=self.Rotate\u原点,角度=self.angle)
颜色(rgb=(0255100))
矩形(pos=self.rect\u pos,size=self.rect\u size)
def on_touch_up(自我,触摸):
如果自碰撞点(*touch.pos):
self.rotate()
打印(自角度)
类阶段2(小部件):
object2=ObjectProperty(无)
object3=ObjectProperty(无)
班级经理(屏幕经理):
通过
sm=经理()
类屏幕(应用程序):
def生成(自):
返回sm
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
ScreensApp().run()

如果在
画布
说明中包含
PushMatrix()
PopMatrix()
,则只有当前的
小部件
会受到影响。然后,如果您将
小部件
大小和
位置
调整为
矩形
,您应该会获得更好的(但不是完美的)
碰撞点
性能:

    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

无论何时对self.canvas使用
时,都需要执行此操作,其中涉及
旋转
缩放
、或
平移
collide\u point()
仍将查看
小部件的大小和
位置,而不是
矩形
,但至少
小部件的中心与其
矩形
应该重合。

你的
触摸式上的方法是使用
collide\u point()
它将触摸点与
小部件
pos
大小
进行比较,而不是与
矩形
进行比较。感谢您帮助@JohnAnderson,但这可能不是问题所在,即使在单击矩形之前,第二个矩形的位置也不是它应该的位置…如果可以,请运行代码一次,以查看输出是什么,因为讨论问题确实很困难…但就问题而言