TL;DR

В названии поста большой спойлер! Я разрабатывал проект логотипа и подумал, что обнаружил ошибку. Оказывается, я использовал старую версию Matter.JS и приступил к обновлению пакета CLJS JS.

Ограничения

В прошлый раз я дошел до того, что определил мир с помощью структуры данных ClojureScript. Запуск кода приведет к тому, что пара круглых тел упадет и подпрыгнет.

Чтобы начать строить структуру логотипа, мне нужно соединить объекты вместе. В Matter.JS тела вы соединяете тела вместе, используя ограничения. Я собираюсь более подробно рассказать об ограничениях в другом посте, но они соединяют тела вместе с помощью своего рода невидимой нити, которая может быть твердой, как металлический стержень, или эластичной, как эластичная.

Как и в моих первых экспериментах с Matter.JS, в Coding Train есть учебник, охватывающий все методы, необходимые для их определения и использования.

Я начал так же, как и в этом уроке, и создал ограничение, чтобы соединить два моих круглых тела вместе. Вы можете себе представить, как я мог построить буквы логотипа таким образом.

В будущем я преобразую каждую букву во что-то, что Matter.JS называет составным, но, поскольку «мир» сам по себе является составным, это не должно иметь большого значения. Композит — это просто тело, представляющее собой набор других тел, ограничений и композитов, поэтому он создает иерархическую структуру.

Мышеловка

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

К счастью, Matter.JS предоставляет MouseConstraint именно для этой цели. Его настройка включает создание объекта Mouse, который фиксирует все события мыши. Вы передаете объект Mouse объекту MouseConstraint при его создании. Добавьте ограничение к вашему World, и вы можете начать щелкать тела и перетаскивать их.

Только мой не работал! Что бы я ни делал, я не мог заставить его запускать правильные события. MouseConstraint работает, когда указатель мыши находится на одном конце веревки/стержня/резинки, а любое тело, по которому вы щелкаете, прикрепляется к другому.

Ловушка для жуков

Я начал отлаживать его. Инструменты для этого отличные. Иметь исходные карты для кода ClojureScript, чтобы вы могли устанавливать точки останова, — это фантастика. Добавьте инструменты BinaryAge для регистрации объектов, и эти инструменты станут довольно продвинутыми.

До этого я экспериментировал с соотношением пикселей, поскольку это проблема в учебнике, которому я следовал. Однако похоже, что Processing.JS не поддерживает эту идею и вместо этого масштабирует систему координат. Это заставило меня еще больше задуматься о создании версии Quil, поддерживаемой P5.js. Она быстро становится предпочтительной библиотекой, похожей на обработку JavaScript, и, похоже, находится в более активной разработке.

Вернемся к отладке! Я обнаружил, что могу присоединяться к событиям объекта Mouse, и они срабатывали правильно. Однако метод update из MouseConstraint, в котором происходит основная часть логики, так и не был вызван. Еще немного покопавшись, я увидел, что он вызывается не через событие мыши, а через событие с именем tick. Это событие запускается Runner Matter.JS каждый раз, когда он обновляет файл World. Я не использовал это и вручную вызывал update для моего объекта Engine в функции update-state моего Quil скетча.

Сначала я попробовал обходной путь и сам вызвал событие tick. Внезапно все заработало! «Я тоже нашел ошибку», — подумал я, но потом понял, что Даниэль Шиффман перестал использовать Runner в туториале, и его работа сработала.

Просматривая форумы, GitHub и Stack Overflow по связанным проблемам, я наткнулся на эту проблему, идентифицированную как ошибка и теперь закрытую. Так почему же мой код не работал? Пользователь, сообщивший об ошибке, даже опубликовал тот же обходной путь, который использовал я.

Ранее я заметил, что версия Matter.JS в пакете CLJSJS устарела, и, глядя на выпуски, я видел последнюю версию 0.10.0. В пакете была версия 0.9.1, поэтому это исправление не включалось.

Внешний ремонт

Я глубоко вздохнул и решил обновить пакет. Руководство по созданию новых пакетов хорошо написано и заставило меня понять, что это не будет той ужасной задачей, о которой я подумал сначала.

Установка boot была простой через Homebrew

brew install boot-clj

Я создал форк репозитория, клонировал его и начал с обновления файла build.boot, чтобы получить версию 0.10.0. Это было так же просто, как обновить номера версий и создать контрольную сумму, загрузив zip-файл и запустив:

openssl md5 matter-js-0.10.0.zip

Основная часть работы была связана с обновлением экстернов. Я знаю, что есть инструменты, чтобы сделать это для вас, но я решил сначала запустить diff двух версий и посмотреть, какие объекты и методы были новыми.

Оказалось, что их не так много! Я добавил их в файл matter.ext.js и установил новый пакет. Это означало, что я мог обновить номер версии моего пакета в моем файле project.clj, и он начал бы использовать мою новую версию.

Гордясь собой, я перезапустил все и обнаружил, что это не работает! Я успешно подключил новую версию Matter.JS, но события по-прежнему не запускались.

Именно в этот момент я обнаружил небольшую ссылку вверху страницы релизов Matter.JS на GitHub.

Были спрятаны еще два релиза 0.11.0 и 0.12.0. Немного подавленный, я снова настраиваюсь на процесс, но на этот раз с использованием последней версии 0.12.0.

На этот раз все было не так просто, и нужно было обновить ряд новых объектов и методов. Глобальное изменение, связанное с обработкой вызовов require, также означало, что мне нужно было пройти через множество изменений.

Однако на этот раз я все обновил и перезапустил свой проект, чтобы обнаружить, что я все исправил! Это было очень приятное чувство, и играть с этими двумя желтыми кругами стало еще приятнее.

Пулл-реквест

Прежде чем я отправлю запрос на вытягивание с этими обновлениями, нужно выполнить некоторую работу по уборке. Прежде всего, я вручную добавил все новые объекты и методы для работы с такими вещами, как плагины. Я еще ничего не тестировал, так что это было бы хорошим началом! Я также сделал пару коммитов, прежде чем исправить это, поэтому мне также нужно привести в порядок историю.

А пока, если вы хотите установить его самостоятельно, вы можете клонировать мой форк. Вам придется делать такие вещи, как настройка boot самостоятельно, и, честно говоря, это, вероятно, не стоит хлопот. Я бы просто использовал обходной путь:

(.trigger js/Matter.Events engine "tick")

Это работает — конечно, если у вас есть объект engine для передачи — так зачем его исправлять?

Я обновлю этот пост ссылкой на запрос на вытягивание, когда отправлю его. Таким образом, если вы заинтересованы, вы можете отследить это. Кстати, вы можете просто получить уведомление, когда он закроется, через Скажи мне, когда он закроется. Это полезный инструмент, который означает, что вам не нужно следить за проблемами и получать все обновления, прежде чем кто-то их исправит.

Первоначально опубликовано на сайте bunkham.com 5 апреля 2017 г.