Давненько я не появлялся, но вот наконец добрёл до того чтобы сделать описание к последнему уроку, который я выложил на форуме ещё в июне. Полный архив с кодом и ресурсами прилагается, поэтому листинг делать не буду — буду лишь пояснять где нужно куски кода. Собственно, в этом уроке мы подошли непосредственно к созданию «тела», которое у нас будет бегать по карте туда, куда мы ему покажем. В модулях у нас появляются два новых файла: character.py и globals.py. Смотрим на character.py: в нём я создал два классаcharacterCollSystem — вспомогательный — класс вызывает чувство дежавю — правильно, фактически то же самое что для хейтчекера и маусконтрола; и собственно character. CharacterCollSystem — класс с единственным методом — инициализацией. Если вы ознакомились с предыдущим уроками, то особых вопросов вызывать не должен. Поясню лишь, что для коллизий используются два тела — одно для определения земли — луч, направленный вниз. Второе — сфера — для определения столкновений с окружающими предметами. Чуть более подробно разберём основной класс нашего персонажа — character. Свойства: id — просто номер для дальнейшей идентификации root — корневой нод персонажа, на который мы будем лепить модельку, систему коллизий и если ещё что-то потребуется, то и это «что-то». model — анимированная моделька. Для тех кому непонятны следующие операции Code self.model=Actor.Actor(modelstr,anims) self.model.reparentTo(self.root) self.model.setBlend(frameBlend=1,blendType=1) self.model.enableBlend() self.model.loop('walk') self.model.loop('stand') self.animInterval=LerpAnimInterval(self.model, 1, 'walk', 'stand') Смотрим статью про плавное переключение анимаций. state — информирует о текущем состоянии — стоим/идём. сollsys — экземпляр нашей characterCollSystem. waypoints - говорит сама за себя Наш персонаж обладает ещё и парой методов (помимо инициализации): control — принимает в качестве аргментов строку, обозначающую действие и параметры действия, в соответстии с этим обрабатыват их. update — чуть сложнее этот метод мы при создании экземпляра персонажа внесём в таск-менеджер панды. Как видно из названия, он у нас будет отвечать за обновление — позиция, анимация и пр. На данный момент в этом методе мы проверяем есть ли вэйпойнты для персонажа, если есть, то поворачиваем и отправляем на ближайший по списку, если достигли вэйпойнта, то удаляем его. Переключаем анимации. В конце проверяем и устанавливаем персонажа обратно на землю, если он в процессе перемещения вдруг от неё «оторвался». Теперь второй новый модуль — globals.py. На нашего персонажа может влиять много других классов — локация, управление, другие персонажи. Можно конечно передавать в каждый необходимый класс ссылку на нужного персонажа, что, наверно, правильно ибо избавляет от лишних зависимостей, но тогда за всеми этими ссылками придётся следить, если вдруг нам потребуется, например удалить персонажа. Второй вариант — сделать его глобальным для нужных модулей — для этого и создаётся наш модуль globals.py. На данный момент в него я перенёс экземпляр нашего персонажа и глобальный обработчик коллизий. Из других изменений — подкорректирован модуль control.py — ведь в прошлый раз он у нас просто выводил координаты точки, куда мы клацнули мышью, теперь вместо этого он добавляет вэйпойнт персонажу с помощью метода control, упомянутого ранее. Ну и main.py — в связи с введением глобального модуля. Плюс добавил для проверки коллизий на карту кубик, через который персонаж не сможет пройти.
исходник
Забыл добавить. Если у вас версия панды старая, то может ругаться на код , сообщая, что объет не итерабелен. Для старых версий панды эта срока должна выглядеть как Code for gnode in gnodes.asList ():
|