Как использовать Scatter для перемещения весла в официальном уроке по киви-понгу?

Закончив учебник по игре в понг с официального сайта Kivy, я продолжил их Crash Course. Там, в самом первом видео, я увидел эту волшебную вещь, которую они называют Scatter, которая в значительной степени позволяет вам готовить движущиеся объекты с помощью мыши.

Я думал, что это должно обеспечить более плавный способ управления веслами в игре Pong. Первоначальный способ заключался в том, чтобы поместить логику перемещения весла в on_touch_move() Метод объекта Pong Game (класс Pong Game наследует от Widget), и это было просто:

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

Это приводит к резкому началу, если вы начинаете перемещать курсор мыши ниже или выше весла. Я думал, что Скаттер будет работать лучше. Увы, пока я не смог заставить его работать.

Я начал с комментирования on_touch_move() метод, затем добавление объекта Scatter в качестве дочернего элемента класса Pong Game в pong.kv файл и сделать существующие объекты PongPaddle дочерними по отношению к объекту Scatter. Как это:

<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 и обе лопасти должны двигаться независимо друг от друга, я предполагал, что это, вероятно, вызовет проблему (нажатие на одну заставит оба двигаться одновременно), но все же подумал, что это будет хорошим началом.

Неудачно! Это не заставляет весла двигаться с помощью курсора мыши. Они все еще отскакивают от мяча (даже если они переместились вниз в дереве виджетов, и я не изменил код Python, кроме как закомментировал on_touch_move() метод в теле класса Pong Game - я думаю, что ссылки на экземпляры ObjectProperty для весла подключены в pong.kv файл все еще работает), но они не будут двигаться.

Весь работающий код (моя собственная версия с разбросом)

Весь работающий код (моя собственная версия без скаттера)

Есть идеи, как заставить это работать?

1 ответ

Решение

Таким образом, проблема в том, что весло прыгает на новое место и 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 мы использовали для перемещения весла.

Теперь вы заметите визуальную ошибку, как только вы это сделаете. Скаттер странный в некоторых отношениях. Удалить pos: self.pos из Paddle в файле.kv. Этот пост хорошо подводит итог:

... специфическое поведение делает разброс уникальным, и есть некоторые преимущества / ограничения, которые вы должны учитывать:

  • Дети расположены относительно 0, 0. Положение разброса не влияет на положение детей.

Таким образом, положение холста в Paddle относительно Paddle (разброс), а не экрана.

Теперь потратьте минуту, чтобы оценить игру, которую вы получили. Весла можно перемещать куда угодно, а также вращать и тому подобное. Вы можете сделать это с помощью мыши, щелкнув правой кнопкой мыши, чтобы установить мнимое "прикосновение", обозначенное красной точкой, а затем выполнить мобильные жесты, чтобы изменить их размер и повернуть. Повеселись, ты это заслужил. Мы исправим эти "ошибки" после вашего перерыва.

Итак, есть также некоторые функции Scatter, которые вам на самом деле не нужны. Отключить масштабирование, вращение и перетаскивание по x в файле.py PongPaddle учебный класс:

do_rotation = do_scale = do_translation_x = Property(False)

Не уверен, что у меня все есть, Скаттер делает много вещей, некоторые из которых вам не нужны или не нужны. По сравнению с предыдущей версией, Scatter pong требует большей точности. Вам все еще понадобится код, чтобы проверить, находится ли весло вне границ. В целом предыдущее решение мне понравилось больше.

Здесь вы найдете полный код Scatter.

Другие вопросы по тегам