Kivy Pong 官方教程中如何使用 Scatter 移动球拍?

How to use Scatter to move paddles in the official Kivy Pong tutorial?

完成 Pong Game tutorial from the official Kivy site I went on with their Crash Course. There in the very first video 我看到了他们称之为 Scatter 的神奇东西,它几乎可以让你摆脱-使用鼠标移动 UI 东西的盒子。

我认为这应该为 控制球拍 Pong Game 提供更流畅的方式。最初的方法是将球拍移动逻辑放在 PongGame 对象的 on_touch_move() 方法中(PongGame class 继承自小部件),它很简单:

if touch.x < self.width / 3:  # if you clicked in 1/3 of the window to the left
    player1.center_y = touch.y  # level the first paddle's center vertically with the mouse click position

如果您碰巧开始将鼠标光标移动到桨的下方或上方,这会导致开始时出现震动。我认为 Scatter 会更好用。唉,到目前为止我没能成功。

我开始的是注释掉 on_touch_move() 方法,然后添加一个 Scatter 对象作为 PongGame class 在 pong.kv 文件中并使现有的 PongPaddle 对象成为 [=38 的子对象=]分散对象。像这样:

<PongGame>:
    Scatter:
        do_scale: False
        do_rotation: False
        do_translation_x: False

        PongPaddle:
            id: player_left
            x: root.x
            center_y: root.center_y  

        PongPaddle:
            id: player_right
            x: root.width - self.width
            center_y: root.center_y

因为我使用了单个 Scatter 对象并且两个桨都需要独立移动我预想这可能会导致问题(单击一个会让两者同时移动)但我认为这将是一个好的开始。

运气不好!这不会使桨随鼠标光标移动。他们仍然弹球(即使他们在小部件树中向下移动并且除了在 PongGame[=55 中注释掉 on_touch_move() 方法之外我没有更改 Python 代码=] class body - 我猜 pong.kv 文件中连接的桨的 ObjectProperty 实例的引用仍然有效),但它们不会移动。

Whole runnable code (my own version with the scatter)

Whole runnable code (my own version without the scatter)

有什么让它发挥作用的想法吗?

所以问题是桨跳到一个新位置,on_touch_move 方法负责。在没有分散的可运行代码中,我将第 84-88 行更改为:

def on_touch_move(self, touch):
    if touch.x < self.width / 3:
        self.player1.center_y += touch.dy
    if touch.x > self.width - self.width / 3:
        self.player2.center_y += touch.dy

基本上,触摸包含 y 的增量值(y 改变了多少),因此您可以像移动鼠标一样移动桨,而不是将桨中心移动到鼠标的 y。这使得游戏非常流畅和漂亮。我真的想知道为什么他们一开始不这样做。

不过有一个问题 - 球拍现在可能会远离游戏屏幕。这可以通过检查桨的中心是否在屏幕外(使用 PongGame 高度)轻松解决。我将把它留作练习,但请随时询问您是否遇到困难。

所以,既然您很好奇,那么有一种方法可以使用 Scatter 来做到这一点。所以,首先,Scatter 本身是被拖动、调整大小和旋转的小部件,它不是布局(它可以,但我们只需要桨本身移动,而不是整个屏幕)。所以,Paddle 继承自 Scatter。删除我们用于移动桨的 on_touch

现在您会注意到执行此操作后会出现视觉错误。 Scatter 在某些方面很奇怪。删除 .kv 文件中 Paddlepos: self.posThis post 总结得很好:

...specific behavior makes the scatter unique, and there are some advantages / constraints that you should consider:

  • The children are positioned relative to 0, 0. The scatter position has no impact of the position of children.

所以canvas在Paddle中的位置是相对于Paddle(散点)的,而不是屏幕。

现在花点时间欣赏一下您得到的游戏。桨叶可以移动到任何地方,也可以旋转等等。您可以使用鼠标右键单击以设置由红点指示的假想 "touch",然后执行移动类型的手势来调整大小和旋转。玩得开心,你应得的。我们会在您休息后修复这些 "bugs"。

好的,还有一些您并不真正需要的 Scatter 功能。通过 .py 文件中的 x 禁用缩放、旋转和拖动 PongPaddle class:

do_rotation = do_scale = do_translation_x = Property(False)

不确定我是否得到了所有东西,Scatter 可以做很多事情,其中​​一些是您不需要或不需要的。与之前的版本相比,Scatter pong 需要更高的精度。您仍然需要代码来检查球拍是否也超出了边界。总的来说,我更喜欢以前的解决方案。

Here 您将找到带有 Scatter 的完整代码。