Как использовать 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.