JavaScript:Библиотеки/p5.play
p5.play[1]
Это библиотека, добавляющая в p5.js функционал для создания игр и игровых элементов.
В ней есть класс Sprite, позволяющий управлять визуальными эффектами в 2D-пространстве, а также функционал для анимации, базового расчета столкновения объектов и последствий их столкновения, группирования спрайтов, виртуальной камеры, а также для взаимодействия с мышью и клавиатурой.
Игра на заднем фоне (имеется в виду игра на заднем фоне этой страницы, переводом которой является данная статья – прим. пер.) сделана как раз при помощи p5.play и содержит всего около 100 строчек кода. Большой список примеров/руководств (с наглядной демонстрацией того, как они работают) смотрите по этой ссылке.
Библиотека p5.play является расширением библиотеки p5.js. Это JavaScript-библиотека (и сообщество), нацеленная на то, чтобы сделать программирование более доступным для художников, дизайнеров, преподавателей и просто новичков. Если вы не знакомы с p5.js, то вам необходимо начать отсюда.
Библиотека p5.play создавалась с прицелом на доступность и простоту, но не производительность, а также с прицелом на то, чтобы она была понятна программистам среднего уровня (и чтобы они могли при желании поучаствовать в ее модификации). Ее физический движок не основан на box2D, она не использует события и не поддерживает 3D. Поэтому если вам нужен более надежный (и сложный) игровой веб-фреймворк, рекомендуем обратиться к phaser.io или easel.js.
GitHub-репозиторий p5.play по-прежнему работает в режиме беты. Если вы хотите сообщить о багах или внести свой вклад в библиотеку p5.play, то добро пожаловать!
Старт проекту дал Паоло Педерчини (сайт, Твиттер).
Справочник по классам и методам библиотеки p5.play
Класс Animation
Объект Animation содержит серию изображений (объектов p5.Image), которые можно показать друг за другом.
Все файлы должны иметь разрешение «*.png». Файл задается в формате «data/file0001.png», где «data» – это папка в корневой папке скетча, а «file0001.png» – файл, находящийся в этой папке.
В объекте Sprite может храниться несколько анимаций с разными идентификаторами – более подробно читайте в описании методов Sprite.addAnimation() и Sprite.changeAnimation() – но при помощи Animation можно создать и использовать отдельную, ни от чего не зависящую анимацию.
Анимацию можно создать, либо задав серию графических файлов (в любом количестве), либо задав первый и последний кадры анимации (в этом случае графические файлы должны быть правильно пронумерованы), после чего p5.play попытается определить правильную последовательность отображения графических файлов.
К примеру, если задать файлы «data/file0001.png» и «data/file0005.png», то автоматически будут также загружены файлы «data/file0003.png» и «data/file0004.png».
Конструктор
Animation(fileName1, fileName2, fileNameN)
- filename1 – первый графический файл в серии графических файлов. Тип данных – String
- filename2 – последний (если вы задаете анимацию при помощи ее первого и последнего кадров) или второй (если вы задаете анимацию с помощью всех ее кадров) графический файл в серии графических файлов. Тип данных – String
- filenameN – третий, четвертый, пятый и так далее графические файлы, идущие после первых двух кадров анимации. Задаются в опциональных третьем, четвертом, пятом и так далее параметрах. Тип данных – String
В примере ниже показаны оба способа использования конструктора. Для создания объекта «sequenceAnimation» используется способ с первым и последним кадрами, а для создания «glitch» – способ со всеми кадрами.
var sequenceAnimation;
var glitch;
function preload() {
sequenceAnimation = loadAnimation("data/walking0001.png", "data/walking0005.png");
glitch = loadAnimation("data/dog.png", "data/horse.png", "data/cat.png", "data/snake.png");
}
function setup() {
createCanvas(800, 600);
}
function draw() {
background(0);
animation(sequenceAnimation, 100, 100);
animation(glitch, 200, 100);
}
Методы
- changeFrame(frame) – переключается на другой кадр. В параметре «frame» (тип данных – number) задается номер кадра, на который нужно переключиться (отсчет кадров начинается с «0»).
- clone() – объекты задаются при помощи указателей, поэтому, чтобы получить из одной анимации несколько разных спрайтов, эту анимацию нужно клонировать, для чего и нужен этот метод. Возвращает объект Animation
- draw(x, y, r=0) – рисует анимацию на заданных координатах, заданных в параметрах «x» и «y» (тип данных – number). В опциональном параметре «r=0» (тип данных – number) задается вращение. Кадры обновляются автоматически.
- getFrame() – возвращает номер текущего кадра (отсчет кадров начинается с «0»). Тип возвращаемого значения – number
- getFrameImage() – возвращает текущий кадр в виде объекта p5.Image
- getHeight() – возвращает высоту текущего кадра в пикселях. Если изображения не загружено, возвращает «1». Тип возвращаемого значения – number
- getImageAt(frame) – возвращает кадр, который имеет номер, заданный в параметре «frame» (тип данных – number). Тип возвращаемого значения – p5.Image
- getLastFrame() – возвращает номер последнего кадра (отсчет начинается с «0»). Тип возвращаемого значения – number
- getWidth() – возвращает ширину текущего кадра в пикселях. Если изображения не загружено, возвращает «1». Тип возвращаемого значения – number
- goToFrame(toFrame) – проигрывает анимацию вперед или назад в сторону заданного кадра (отсчет кадров начинается с «0»). Тип данных для параметра «toFrame» – number
- nextFrame() – переходит к следующему кадру и останавливается
- play() – проигрывает анимацию
- previousFrame() – переходит к предыдущему кадру и останавливается
- rewind() – отматывает анимацию к первому кадру
- stop() – останавливает анимацию
Свойства
- frameChanged – стоит «true», если во время последнего цикла draw() кадр изменился. Тип данных – boolean
- frameDelay – меняет частоту кадров. К примеру, если задать здесь «4», то частотой кадров для анимации станет частота кадров скетча, поделенная на 4 раза (т.е., к примеру, 60 к/с превратятся в 15 к/с). Значение по умолчанию – «4». Тип данных – number
- images – здесь хранятся кадры (объекты p5.Image) анимации. Тип данных – массив
- looping – если задать здесь «false», то, достигнув последнего кадра, анимация остановится. Значение по умолчанию – «true». Тип данных – boolean
- playing – если здесь стоит «true», то это значит, что анимация в данный момент проигрывается. Значение по умолчанию – «true». Тип данных – boolean
- visible – задает видимость анимации. Значение по умолчанию – «true». Тип данных – boolean
Класс Camera
Этот класс позволяет использовать камеру, с помощью которой можно перемещать и зуммировать поле обзора и тем самым показывать то, что нарисовано за пределами холста. У камеры есть позиция, коэффициент зума и координаты мыши, соответствующие полю обзора. Камера автоматически создается в первом цикле draw().
В p5.js камера «заворачивает» весь цикл рисования в новую матрицу преобразования, но это можно отключить в любой момент цикла draw() – к примеру, чтобы нарисовать элементы интерфейса в абсолютной системе координат.
Конструктор
Camera(x, y, zoom)
- x – начальная X-координата позиции камеры. Тип данных – number
- y – начальная Y-координата позиции камеры. Тип данных – number
- zoom – коэффициент зума. Тип данных – number
Методы
- off() – выключает камеру. Холст будет рисоваться в нормальном режиме, игнорируя позицию и зум камеры, пока не будет вызван метод Camera.on()
- on() – включает камеру. Холст будет рисоваться в зависимости от позиции и зума камеры, пока не будет вызван метод Camera.off()
Свойства
- active – если камера включена, здесь будет «true». Это свойство только для чтения. Для включения и выключения камеры используйте методы Camera.on() и Camera.off(). Тип данных – boolean
- mouseX – координата X курсора мыши при использовании камеры. Перемещение и масштабирование холста не поменяют ни позиции спрайтов, ни значения в свойствах mouseX и mouseY. Используйте это свойство, чтобы прочесть позицию мыши при перемещении или изменении зума камеры. Тип данных – number
- mouseY – координата Y курсора мыши при использовании камеры. Перемещение и масштабирование холста не поменяют ни позиции спрайтов, ни значения в свойствах mouseX и mouseY. Используйте это свойство, чтобы прочесть позицию мыши при перемещении или изменении зума камеры. Тип данных – number
- position – позиция камеры. Задает глобальное смещение скетча. Тип данных – объект p5.Vector
- zoom – зум камеры. Задает глобальный коэффициент зума скетча. Если задать здесь «1», то скетч будет иметь нормальное масштабирование, если задать «2» – все увеличится в два раза, а если «0.5» – все уменьшится в два раза
Класс Group
Группы в библиотеке p5.js – это коллекции спрайтов, ведущих себя одинаковым образом. К примеру, все спрайты группы могут находиться на фоне или пытаться «убить» игрока. Группы – это «расширенные» массивы и потому наследуют все их свойства (например, group.length).
Поскольку в группах хранятся только указатели на спрайты, один спрайт может быть в нескольких группах, а удаление группы никак не затронет сами спрайты.
Впрочем, Sprite.remove() удалит спрайт из всех групп, в которых он находится.
Конструктор
Group()
Методы
- add(s) – добавляет спрайт в группу. В параметре «s» (тип данных – объект Sprite) задается спрайт, который нужно добавить
- bounce(target, callback) – проверяет, не пересекается ли группа с другой группой или спрайтом, и если пересекается, спрайты отскочат, влияя на траекторию друг друга в зависимости от значений в свойствах «velocity», «mass» и «restitution». Если bounce() вернет «true», то это значит, что пересечение есть. Проверка пересечения осуществляется при помощи так называемого «коллайдера» – подробнее о нем читайте в описании метода setCollider() для класса Sprite – но если «коллайдер» не задан, им будет автоматически сделана ограничительная рамка изображения/анимации. В параметре «target» задается группа или спрайт, пересечение с которыми нужно рассчитать. В опциональном параметре «callback» задается функция обратного вызова для действий, которые будут происходить после определения пересечения. Она будет вызываться при обнаружении пересечения с каждым спрайтом группы. Первым параметром для этой функции обратного вызова будет служить элемент текущей группы, а вторым – другой спрайт, пересечение с которым нужно рассчитать
- clear() – удаляет все указатели на спрайты к группе. Сами спрайты не удаляет
- collide(target, callback) – проверяет, не пересекается ли группа с другой группой или спрайтом, и если пересекается, то для спрайта, инициировавшего столкновение, другой спрайт, с которым он столкнулся, станет препятствием, через которое он не сможет пройти. Если collide() вернет «true», то это значит, что пересечение есть. Проверка пересечения осуществляется при помощи так называемого «коллайдера» – подробнее о нем читайте в описании метода setCollider() для класса Sprite – но если «коллайдер» не задан, им автоматически будет сделана ограничительная рамка изображения/анимации. В параметре «target» задается группа или спрайт, пересечение с которыми нужно рассчитать. В опциональном параметре «callback» задается функция обратного вызова для действий, которые будут происходить после обнаружения пересечения. Она будет вызываться при обнаружении пересечения с каждым спрайтом группы. Первым параметром для этой функции обратного вызова будет служить элемент текущей группы, а вторым – другой спрайт, пересечение с которым рассчитывается этим методом.
- contains(sprite) – проверяет, содержится ли в группе спрайт, заданный в параметре «sprite». Возвращает либо индекс найденного спрайта, либо «-1», если искомый спрайт не будет найден
- displace(target, callback) – проверяет, не пересекается ли группа с другой группой или спрайтом, и если пересекается, то спрайт, инициировавший столкновение, начнет сдвигать спрайт, с которым он столкнулся, в направлении своего движения. Если displace() вернет «true», то это значит, что пересечение есть. Проверка пересечения осуществляется при помощи так называемого «коллайдера» – подробнее о нем читайте в описании метода setCollider() для класса Sprite – но если «коллайдер» не задан, им автоматически будет сделана ограничительная рамка изображения/анимации. В параметре «target» задается группа или спрайт, пересечение с которыми нужно рассчитать. В опциональном параметре «callback» задается функция обратного вызова для действий, которые будут происходить после обнаружения пересечения. Она будет вызываться при обнаружении пересечения с каждым спрайтом группы. Первым параметром для этой функции обратного вызова будет служить элемент текущей группы, а вторым – другой спрайт, пересечение с которым нужно рассчитать
- draw() – рисует все спрайты в группе
- get(i) – считывает элемент группы, имеющий индекс, который задан в параметре «i» (тип данных – number)
- indexOf() – делает то же самое, что и Group.contains()
- maxDepth() – возвращает максимальную «глубину» (о том, что это, читайте в описании свойства «depth» для класса Sprite) в группе, т.е. «глубину» спрайта, нарисованного на самом верху холста. Тип возвращаемого значения – «number»
- minDepth() – возвращает минимальную «глубину» (о том, что это, читайте в описании свойства «depth» для класса Sprite) в группе, т.е. «глубину» спрайта, нарисованного в самом низу холста. Тип возвращаемого значения – «number»
- overlap(target, callback) – проверяет, не пересекается ли группа с другой группой или спрайтом. Если overlap() вернет «true», то это значит, что пересечение есть. Проверка пересечения осуществляется при помощи так называемого «коллайдера» – подробнее о нем читайте в описании метода setCollider() для класса Sprite – но если «коллайдер» не задан, им автоматически будет сделана ограничительная рамка изображения/анимации. В параметре «target» задается группа или спрайт, пересечение с которыми нужно рассчитать. В опциональном параметре «callback» задается функция обратного вызова для действий, которые будут происходить после обнаружения пересечения. Она будет вызываться при обнаружении пересечения с каждым спрайтом группы. Первым параметром для этой функции будет служить элемент текущей группы, а вторым – другой спрайт, пересечение с которым нужно рассчитать
- remove(item) – удаляет из группы спрайт, заданный в параметре «item» (тип данных – объект Sprite). Сам спрайт при этом не удаляется, а только указатель на него. Этот метод возвращает «true», если спрайт был найден и удален
- removeSprites() – удаляет со сцены все спрайты группы
- size() – возвращает то же значение, что хранится в «group.length»
- toArray() – возвращает копию группы в виде стандартного массива
Класс Sprite
Этот класс – главный строительный кирпичик библиотеки p5.play. В нем можно хранить изображения и анимации, обладающие набором свойств вроде позиции и видимости. Кроме того, спрайт может иметь так называемый «коллайдер» – невидимую прямоугольную или круглую область, с помощью которой определяются столкновения и пересечения с курсором мышки и другими спрайтами.
Создание спрайта осуществляется с помощью метода createSprite().
Методы
- addAnimation(label, animation) – добавляет в спрайт анимацию. Она должна быть предзагружена в блоке preload() при помощи метода loadAnimation(). Анимациям нужны идентификаторы, чтобы мы могли переключаться между ними. Анимации хранятся в спрайте, но не показываются до тех пор, пока не будет вызван метод Sprite.changeAnimation(label). В параметре «label» (тип данных – String) задается идентификатор анимации, а в параметре «animation» (тип данных – объект Animation) – сама предзагруженная анимация. Этот метод можно вызвать двумя другими способами: в обоих первым параметром остается «label», но в первом способе – sprite.addAnimation(label, firstFrame, lastFrame) – во втором и третьем параметрах ставятся первый и последний кадр анимации, а во втором способе – sprite.addAnimation(label, frame1, frame2, frame3...) – во втором, третьем, четвертом и так далее параметрах ставятся все кадры анимации.
- addImage(label, img) – добавляет изображение в спрайт. Это изображение будет рассматриваться библиотекой как однокадровая анимация и должно быть предзагружено в блоке preload() при помощи функции loadImage() из библиотеки p5.js. Анимациям необходимы идентификаторы, чтобы между ними можно было переключаться. Изображение хранится в спрайте, но не будет показано, пока в коде не будет вызван метод Sprite.changeAnimation(label). В опциональном параметре «label» (тип данных – String) задается идентификатор изображения, а в параметре «img» (тип данных – объект p5.Image) – само изображение. Если в методе addImage() будет задан только параметр «img», то ему не будет присвоено никакого идентификатора.
- addSpeed(speed, angle) – «подталкивает» спрайт в направлении, заданном в параметре «angle» (тип данных – number), и с силой, заданной в параметре «speed» (тип данных – number). Если спрайт уже движется с некоторой скоростью, то новая скорость суммируется с прежней.
- addToGroup(group) – добавляет спрайт в группу, заданную в параметре «group».
- attractionPoint(magnitude, pointX, pointY) – «подталкивает» спрайт в сторону точки с координатами, заданными в параметрах «pointX» и «pointY» (тип данных – number). Сила «подталкивания» задается в параметре «magnitude» (тип данных – number). Если спрайт уже движется с некоторой скоростью, то новая скорость суммируется с прежней.
- bounce(target, callback) – проверяет, пересекается ли спрайт с другим спрайтом или группой, и если пересекается, то спрайты отскочат, влияя на траектории друг друга в зависимости от значений в свойствах «velocity», «mass» и «restitution». При обнаружении пересечения возвращает «true». Проверка пересечения осуществляется при помощи «коллайдера» – более подробнее о нем читайте в описании метода setCollider() ниже – но если «коллайдер» не задан, им автоматически будет сделана ограничительная рамка изображения/анимации. В параметре «target» задается группа или спрайт, пересечение с которыми нужно рассчитать. В опциональном параметре «callback» задается функция обратного вызова для действий, которые будут происходить после обнаружения пересечения. Если в «target» задана группа, эта функция обратного вызова будет вызываться при пересечении с каждым спрайтом этой группы. Первым параметром для этой функции будет служить текущий спрайт, а вторым – другой спрайт, пересечение с которым нужно рассчитать.
- changeAnimation(label) – переключает показываемую анимацию. Идентификатор анимации, на которую нужно переключиться, задается в параметре «label» (тип данных – String). Более подробно об управлении анимациями читайте в описании класса Animation и его методов
- changeImage(label) – переключает показываемое изображение/анимацию. Идентификатор изображения/анимации задается в параметре «label» (тип данных – String). Этот метод эквивалентен методу changeAnimation().
- collide(target, callback) – проверяет, пересекается ли спрайт с другим спрайтом или группой, и если пересекается, то для спрайта, инициировавшего столкновение, другой спрайт, с которым он столкнулся, станет препятствием, через которое он не сможет пройти. При обнаружении пересечения возвращает «true». Проверка пересечения осуществляется при помощи «коллайдера» – более подробно о нем читайте в описании метода setCollider() ниже – но если «коллайдера» задано не будет, им автоматически будет сделана ограничительная рамка изображения/анимации. В параметре «target» задается спрайт или группа, пересечение с которыми нужно рассчитать. В опциональном параметре «callback» задается функция обратного вызова для запуска действий, которые будут происходить после обнаружения пересечения. Если в параметре «target» задана группа, то эта функция будет вызываться при столкновении с каждым спрайтом этой группы. В первом параметре функции обратного вызова задается текущий спрайт, а во втором – спрайт, пересечение/столкновение с которым нужно рассчитать.