我是kivy的新手,无法让此小部件在开始移动之前从某个位置开始。在我的kv文件中,我的窗口小部件位置设置为self.pos
,在我的fall
函数中,我使用self.pos
更改窗口小部件的位置并使它下降。唯一的问题是我无法为小部件添加原点位置。这是我的代码:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy.graphics import Line
from kivy import Config
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.properties import NumericProperty,
ReferenceListProperty,ObjectProperty
from kivy.vector import Vector
from kivy.clock import Clock
Config.set('graphics', 'multisamples', '0')
class TetrisGame(GridLayout):
block1= ObjectProperty(None)
class Block1(Widget):
vel_x = NumericProperty(0)
vel_y = NumericProperty(-1)
position = ReferenceListProperty(vel_x,vel_y)
def fall(self, pos):
self.pos = Vector(self.position) + self.pos
class TetrisApp(App):
def build(self):
game = TetrisGame()
block = Block1()
Clock.schedule_interval(block.fall, 1/60)
return block
if __name__ == '__main__':
TetrisApp().run()
.kv:
<Block1>:
canvas:
Rectangle:
size: root.width/5, root.height/20
pos: self.pos
如何解决此问题?
答案 0 :(得分:0)
from kivy.graphics import Rectangle
和from kivy.core.window import Window
block = Block1(pos=(0, Window.height))
game.add_widget(block)
return game
dt
(增量时间)添加为fall()
方法的参数。 如果dt
(delta-time)不在参数列表中,我们将遇到
TypeError: fall() takes 1 positional argument but 2 were given
。
因此,每当我们使用Kivy Clock调度函数时,都必须包含dt
作为参数。
如果我们要调度不接受dt
参数的函数,则可以使用lambda表达式编写不接受dt
的简短函数。
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.gridlayout import GridLayout
from kivy import Config
from kivy.properties import NumericProperty, ReferenceListProperty,ObjectProperty
from kivy.vector import Vector
from kivy.clock import Clock
Config.set('graphics', 'multisamples', '0')
from kivy.graphics import Rectangle
from kivy.core.window import Window
class TetrisGame(GridLayout):
block1 = ObjectProperty(None)
class Block1(Widget):
vel_x = NumericProperty(0)
vel_y = NumericProperty(-1)
position = ReferenceListProperty(vel_x,vel_y)
def __init__(self, **kwargs):
super(Block1, self).__init__(**kwargs)
with self.canvas:
self.rect = Rectangle(pos=self.pos, size=self.size)
self.bind(pos=self.update_rect)
self.bind(size=self.update_rect)
def update_rect(self, *args):
self.rect.pos = self.pos
self.rect.size = self.size
def fall(self, dt):
self.pos = Vector(self.position) + self.pos
class TetrisApp(App):
def build(self):
game = TetrisGame()
block = Block1(pos=(0, Window.height))
game.add_widget(block)
Clock.schedule_interval(block.fall, 1/60)
return game
if __name__ == '__main__':
TetrisApp().run()
#:kivy 1.11.0
<Block1>:
canvas:
Color:
rgba: 1, 0, 0, 1 # red color block
Rectangle:
size: root.width/5, root.height/20
pos: self.pos
答案 1 :(得分:0)
首先,我要指出您代码的错误,TetrisGame
是一个无用的类,因为在您的情况下,您仅将其分配给本地变量:game = TetrisGame()
,当您将其删除时,完成build()
的运行,另一方面,块被返回,因此其作用域增大。
另一个可能的错误是,您在放置时会认为:
size: root.width / 5, root.height/20
您没有更改窗口小部件的大小,只绘制了窗口小部件的一小部分,构建的返回结果是您正在绘制窗口的一部分的窗口,您要做的是创建另一个窗口小部件。窗口并在其中添加子元素。您必须在构造函数中设置大小。
要解决的主要问题是,相对于约定,千伏中的位置相对于左下角,而y +和右x +相对。
解决方案是使用Window获取窗口的大小。
*。py
from kivy.app import App
from kivy.uix.widget import Widget
from kivy import Config
from kivy.properties import NumericProperty, ReferenceListProperty
from kivy.vector import Vector
from kivy.clock import Clock
from kivy.core.window import Window
Config.set('graphics', 'multisamples', '0')
class Block1(Widget):
vel_x = NumericProperty(0)
vel_y = NumericProperty(-1)
position = ReferenceListProperty(vel_x,vel_y)
def fall(self, _):
self.pos = Vector(self.position) + self.pos
class BackGround(Widget):
pass
class TetrisApp(App):
def build(self):
background = BackGround()
block = Block1(pos=(0, Window.height), size=(Window.width/4, Window.height/20))
background.add_widget(block)
Clock.schedule_interval(block.fall, 1/60)
return background
if __name__ == '__main__':
TetrisApp().run()
*。kv
<Block1>:
canvas:
Rectangle:
size: root.size
pos: self.pos
注意:
您不应使用GridLayout ,仅当您要以网格形式放置多个小部件时才应使用GridLayout,而在这种情况下,这不是您想要的。