[英]Rotate a vertical rectangle to an horizontal one with Python Kivy - How?
[英]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
size
和pos
調整為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
每當您使用涉及Rotation
、 Scale
或Translate
with self.canvas
時,都需要這樣做。 collide_point()
仍然會查看Widget
size
和pos
,而不是Rectangle
,但至少Widget
的中心和它的Rectangle
應該重合。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.