如何让小部件(球)从屏幕底部开始--Python / Kivy

时间:2018-05-24 22:20:37

标签: python kivy

我试图在Python和Kivy中进行基本的视觉练习,但是我仍然坚持使用这部分代码,如何让球从屏幕底部开始?

这里是.py文件:

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ReferenceListProperty,\
    ObjectProperty
from kivy.vector import Vector
from kivy.clock import Clock


class PongBall(Widget):
    velocity_x = NumericProperty(0)
    velocity_y = NumericProperty(0)
    velocity = ReferenceListProperty(velocity_x, velocity_y)


    def move(self):
        self.pos = Vector(*self.velocity) + self.pos


class PongGame(Widget):
    ball = ObjectProperty(None)

    def serve_ball(self, vel=(0, 4)):
        self.ball.center = self.center
        self.ball.velocity = vel

    def update(self, dt):
        self.ball.move()

        # bounce ball off bottom or top or left or right
        if (self.ball.y < self.y) or (self.ball.top > self.top):
            self.ball.velocity_y = -2
            self.ball.velocity_x = -4

        # bounce ball off 
        if(self.ball.x < 0):
            self.ball.velocity_x  = 4
            self.ball.velocity_y  = 0

        if(self.ball.x + self.ball.width > self.right):
            self.ball.velocity_x *= -1
            self.ball.velocity_y  = 4

class PongApp(App):
    def build(self):
        game = PongGame()
        game.serve_ball()
        Clock.schedule_interval(game.update, 1.0 / 60.0)
        return game


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

.kv文件:

<PongBall>:
    size: 50, 50 
    canvas:
        Ellipse:
            pos: self.pos
            size: self.size          

<PongGame>:
    ball: pong_ball

    PongBall:
        id: pong_ball
        center: self.parent.center

此代码使小部件从屏幕中心开始,我试图在底部开始,但没有成功

感谢您的任何提示!

1 个答案:

答案 0 :(得分:0)

您的问题是PongBall的初始位置是PongGame的中心:

<PongGame>:
    ball: pong_ball

    PongBall:
        id: pong_ball
        center: self.parent.center # <---

您必须做的是在您创建初始位置时建立。另一个错误是您在显示窗口之前启动游戏,而不是在 build()中启动它,您必须在on_start()中执行此操作:

<强> *。PY

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ReferenceListProperty,\
    ObjectProperty
from kivy.vector import Vector
from kivy.clock import Clock


class PongBall(Widget):
    velocity_x = NumericProperty(0)
    velocity_y = NumericProperty(0)
    velocity = ReferenceListProperty(velocity_x, velocity_y)

    def move(self):
        self.pos = Vector(*self.velocity) + self.pos


class PongGame(Widget):
    ball = ObjectProperty(None)

    def serve_ball(self, vel=(0, 4)):
        self.ball.center = self.initial_pos
        self.ball.velocity = vel

    def update(self, dt):
        self.ball.move()

        # bounce ball off bottom or top or left or right
        if self.ball.y < self.y or self.ball.top > self.top:
            self.ball.velocity_y = -2
            self.ball.velocity_x = -4

        # bounce ball off 
        if self.ball.x < 0:
            self.ball.velocity_x  = 4
            self.ball.velocity_y  = 0

        if self.ball.x + self.ball.width > self.right:
            self.ball.velocity_x *= -1
            self.ball.velocity_y  = 4

class PongApp(App):
    def build(self):
        game = PongGame()
        return game

    def on_start(self):
        self.root.serve_ball()
        Clock.schedule_interval(self.root.update, 1.0 / 60.0)


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

<强> *。KV

<PongBall>:
    size: 50, 50 
    canvas:
        Ellipse:
            pos: self.pos
            size: self.size          

<PongGame>:
    ball: pong_ball
    initial_pos: [self.center_x , pong_ball.height/2]
    PongBall:
        id: pong_ball

build()中,获取小部件的大小不正确,因为这些是在启动之前更新的瞬间,使用on_start()来获取初始位置所依赖的大小很方便。