Рубрики
Без рубрики

Phaser 3 и плитку: строительство платформера

Автор оригинала: Marcus Sanatan.

Вступление

Phaser 3 позволяет быстро создавать игры в нашем браузере с помощью JavaScript. Некоторые из наших любимых 2D-игр являются платформеры – подумайте о играх, таких как Mario, Sonic, Super Meat Boy или Cup.

Плиткой Это редактор 2D-карты, который используется для создания игровых миров. Мы исследуем, как создать уровень платформера с помощью плиткой, интегрировать его с помощью Phaser и анимировать SPRITE, чтобы создать богатый двухмерный платформенный опыт.

В этой статье мы будем создавать базовую платформерную игру, где наш игрок может двигаться дальше в нашем мире. Если игрок попадает в всплеск, то мы сбрасываем позицию плеера. Виноватная демография этой игры можно найти здесь Отказ

Этот учебник написан для знакомых с Phaser 3. Если вы не хотите, ознакомьтесь с рамками с одним из наших предыдущих статей на Phaser.

Начиная

Чтобы лучше следовать с этим руководством, скачать и расстегивать проект Stackabuse-platformer.zip в ваше рабочее пространство. Папка должна включать следующие активы:

  • index.html : Загружает Phaser 3.17 и наш game.js файл
  • game.js : Содержит логику нашей игры
  • Активы/Изображения :

    • background.png.png
    • Kenney_Player.png.
    • kenney_player_atlas.json.
    • SPIKE.PNG.PNG
  • Активы/Tilemaps : Пустая папка, будет использоваться для сохранения плитных файлов
  • Активы/Тилкиты :

    • platformpack_tileshet.png.

Примечание : Если вы предпочитаете, вы также можете следовать, просмотрев код для проекта на нашем Github Repo Отказ

Не забудьте запустить сервер в папке проекта, с вашим IDE или даже с Python: python3 -m http.server Отказ Это требуется для Phaser, чтобы иметь возможность загружать эти активы через http. Опять же, для получения дополнительной информации см. Наша предыдущая статья по теме (связанной выше).

Все игровые активы были созданы и поделились Кенни Отказ Файл ATLAS был создан с помощью Atlas Phaser Packer Отказ

Редактор кафельной карты

Tiled – это бесплатное программное обеспечение с открытым исходным кодом для создания уровней игр. Это доступно на всех основных операционных системах на рабочем столе, поэтому посетите Сайт и загрузить его, чтобы продолжить.

Создание TileMap

Откройте плитку и нажмите «Новая карта». В приглашении измените формат слоя плитки на «Base64 (несжатый)», ширина до 14 плиток и высотой до 7 и размером плитки до 64 пикселей каждый.

Новая карта

Сохраните файл как «Level1.tmx» в «Активы/Tilemaps».

Создание TiLeset

На правой панели щелкните «Новый Tiletet …». Во всплывающем окне назвать TiLeset “Kenny_simple_platformer”. Убедитесь, что «встроен в карту» вариант выбран Отказ Без этого варианта Phaser может испытывать проблемы, загружающую вашу карту правильно. В свойстве «Source» выберите «platformpack_tilesheet.png» из каталога «Активы/TiLesets».

Ширина изображения Tileshient составляет 896 пикселей, а высота составляет 448 пикселей. Он содержит 98 изображений в общей сложности равного размера, все они вписываются в 7 строк и 14 столбцов. С помощью основных математики мы можем вывести, что каждая плитка 64PX в ширине и высоте. Убедитесь, что ширина и высота TILESET – 64PX:

Новый TiLeset

Проектирование нашего уровня

Карты в плитке состоят из слоев. Каждый слой сохраняет некоторую конструкцию игрового мира. Слои, которые находятся на вершине, имеют их плитки, показанные над слоями, которые ниже. Мы получаем глубину, используя их. Эта основная игра будет иметь только два слоя:

  • Платформа: содержит мир, который игрок взаимодействует с
  • Spikes: содержит опасные шипы, которые могут повредить игроку.

Слой платформы

Прежде чем добавить нашу плитки на карту, давайте сначала переименуем слой. Названия слоев будут ссылаться в нашем фазерном коде, поэтому давайте изменим «плиточный слой 1» на «платформы»:

Изменить имя слоя

Чтобы создать уровень, просто выберите плитку от TiLeset и нажмите, где вы хотите разместить его на карте. Давайте создадим/добавим все наши платформы:

Добавить платформы

Шипы в объекте слой

На панели слоев справа от экрана нажмите кнопку «Новый слой» и выберите «Объективный слой». Назовите слой «шипы».

Добавьте слой Spike.

На верхней панели инструментов выберите опцию «Вставить объект»:

Вставить объект

Теперь мы можем добавить плитки Spike из Tiletet:

Добавить шипы

Мы создали наш уровень игры! Теперь нам нужно интегрировать его с Phaser.

Загрузка кафельной карты

Фазер не может прочитать .tmx файл, который плиткой создан. Во-первых, давайте экспортируем нашу карту в JSON. Нажмите «Файл -> Export AS», выберите JSON как формат и назовите его «Level1.json» в Tilemaps папка. Как и во всех проектах Phaser, наши активы должны быть загружены в нашу Прелога Функция:

function preload() {
  this.load.image('background', 'assets/images/background.png');
  this.load.image('spike', 'assets/images/spike.png');
  // At last image must be loaded with its JSON
  this.load.atlas('player', 'assets/images/kenney_player.png','assets/images/kenney_player_atlas.json');
  this.load.image('tiles', 'assets/tilesets/platformPack_tilesheet.png');
  // Load the export Tiled JSON
  this.load.tilemapTiledJSON('map', 'assets/tilemaps/level1.json');
}

Примечание : Вам может быть интересно, почему мы должны загружать изображение Spike отдельно, если он включен в TileMap. К сожалению, этот кусочек дублирования требуется для отображения объектов правильно.

В нашем создать Функция, давайте сначала добавим фон и масштабируйте его для нашей резолюции:

const backgroundImage = this.add.image(0, 0,'background').setOrigin(0, 0);
backgroundImage.setScale(2, 0.8);

Тогда давайте добавим нашу карту:

const map = this.make.tilemap({ key: 'map' });

Ключ соответствует названию, указанному в Прелога Функция, когда мы загрузили плитку JSON. Мы также должны добавить изображение TILESET на наш фазер карта объект:

const tileset = map.addTilesetImage('kenney_simple_platformer', 'tiles');

Первый аргумент ADDTILESETIMAGE это название TiLeset, которое мы использовали в плитке. Второй аргумент – это ключ изображения, который мы загрузили в Прелога функция.

Теперь мы можем добавить наш слой платформы:

const platforms = map.createStaticLayer('Platforms', tileset, 0, 200);

И должен увидеть это:

Платформы добавлены

По умолчанию Phaser не управляет столкновениями для наших плитных слоев. Если мы добавили наш плеер сейчас, он полностью упадет через плиту платформы. Давайте расскажем Phaser, что слой может столкнуться с другими объектами:

platforms.setCollisionByExclusion(-1, true);

Каждая плитка на нашей карте была предоставлена индекс, вытекал, чтобы ссылаться на то, что там должно быть показано. Индекс нашей платформы может быть больше 0. setcollisionbyexclusion Сообщает Phaser, чтобы включить столкновения для каждой плитки, чья индекс не -1, следовательно, все плитки.

Текстура атласа

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

Давайте посмотрим на наш файл изображения: «Kenney_Player.png»:

Кенней Игрок

Наши ATLAS содержит 8 кадров: кадры от 0 до 3 находятся сверху и кадры от 4 до 7 ниже. Сам по себе это не так полезно для фазера, поэтому он пришел с файлом json: “Kenney_player_atlas.json”.

Файл имеет Рамы Массив, который содержит информацию о каждой отдельной картинке, которая составляет ATLAS.

Чтобы использовать ATLAS, вам нужно будет знать Имя файла Свойство кадров, которые вы используете.

Добавление игрока

С нашим миром настроен мы можем добавить игрока и иметь его взаимодействие с нашими платформами. В нашем создать Функция Давайте добавим следующее:

this.player = this.physics.add.sprite(50, 300, 'player');
this.player.setBounce(0.1);
this.player.setCollideWorldBounds(true);
this.physics.add.collider(this.player, platforms);

По умолчанию Phaser использует первый кадр ATLAS, если мы хотели начать на другом кадре, мы могли бы добавить Следующий Аргумент для Сприт Метод с Имя файла Собственность Atlas Image E.G. ROBO_PLAYER_3 Отказ

Собственность Bounce просто добавляет немного бодрости, когда наш игрок прыгает и приземляется. И мы поставили игрока столкнуться с нашим игровым миром и платформами. Теперь мы должны увидеть наш игрок, стоя на наших платформах:

Игрок добавил

Фиолетовая коробка существует вокруг нашего игрока, потому что Отладка Режим включает для наших физических двигателей. Режим отладки показывает границы, которые определяют, как сталкиваются наши спрайты.

Добавление анимации

Напомним, что наша текстура ATLAS имела 8 кадров для движения игрока. Phaser позволяет нам создавать анимацию на основе кадров изображения ATLAS. Давайте создадим анимацию для прогулки, используя последние два кадра первого ряда ATLAS через нашу создать Функция:

this.anims.create({
  key: 'walk',
  frames: this.anims.generateFrameNames('player', {
    prefix: 'robo_player_',
    start: 2,
    end: 3,
  }),
  frameRate: 10,
  repeat: -1
});

ключ Свойство – это строка, которую мы используем для воспроизведения анимации позже. Рамы Собственность – это массив кадров в нашем файле ATLAS ‘JSON, который содержит анимацию. Анимация начинается с первого кадра в массиве и заканчивается на последнем. Мы используем функцию помощника GenerateFramenames Чтобы создать список имен кадров для нас, очень полезную функцию для больших файлов ATLAS.

Framerate По умолчанию до 24 кадров в секунду, что может быть слишком быстрым для нашего игрока, чтобы мы установили его на 10. Когда мы устанавливаем повторять до -1 Мы говорим Phaser, чтобы запустить эту анимацию бесконечно.

Давайте добавим анимацию для нашего холостого спрайта, первого кадра ATLAS:

this.anims.create({
  key: 'idle',
  frames: [{ key: 'player', frame: 'robo_player_0' }],
  frameRate: 10,
});

Наша холостого анимации – это просто один кадр. Давайте добавим анимацию, когда наш игрок прыгает, что также просто один кадр:

this.anims.create({
  key: 'jump',
  frames: [{ key: 'player', frame: 'robo_player_1' }],
  frameRate: 10,
});

С нашими анимациями добавлена, мы должны включить клавиши курсора, чтобы мы могли переместить наш игрок:

this.cursors = this.input.keyboard.createCursorKeys();

Анимирование нашего игрока

Если наш игрок движется влево или вправо, то мы хотим ходить Отказ Если мы нажмеем пробел или вверх, мы хотим прыгать Отказ В противном случае мы останемся в наших холостой должность. Давайте реализуем это в нашем Обновить Функция:

// Control the player with left or right keys
if (this.cursors.left.isDown) {
  this.player.setVelocityX(-200);
  if (this.player.body.onFloor()) {
    this.player.play('walk', true);
  }
} else if (this.cursors.right.isDown) {
  this.player.setVelocityX(200);
  if (this.player.body.onFloor()) {
    this.player.play('walk', true);
  }
} else {
  // If no keys are pressed, the player keeps still
  this.player.setVelocityX(0);
  // Only show the idle animation if the player is footed
  // If this is not included, the player would look idle while jumping
  if (this.player.body.onFloor()) {
    this.player.play('idle', true);
  }
}

// Player can jump while walking any direction by pressing the space bar
// or the 'UP' arrow
if ((this.cursors.space.isDown || this.cursors.up.isDown) && this.player.body.onFloor()) {
  this.player.setVelocityY(-350);
  this.player.play('jump', true);
}

Анимирование спрайта так же просто, как установить анимацию на правда Отказ Если бы вы были наблюданы, вы заметите, что наши ATLAS имеют право только с обращенными движениями. Если мы двигаемся влево, будь то ходьба или прыжки, мы хотим перевернуть спрайт на оси X. Если мы перейдем вправо, мы хотим перевернуть его обратно.

Мы можем достичь этой цели со следующим битом кода:

if (this.player.body.velocity.x > 0) {
  this.player.setFlipX(false);
} else if (this.player.body.velocity.x < 0) {
  // otherwise, make them face the other side
  this.player.setFlipX(true);
}

Теперь наш игрок движется по всей игре в хорошо анимированном стиле!

Перемещение игрока

Добавление шиповников

Phaser предоставляет нам множество способов получить спрайты с нашего слоя объекта. Шипы хранятся в массиве в нашем объекте кафельной карты. Каждый Spike заставит нашего игрока начать все, если оно попадает на них. Для нас имеет смысл поставить все шипы в группу спрайт и настроить столкновения между игроком и группой. Когда столкновение установлено с группой спрайты, она применяется для всех спрайтов.

В создать Функция Добавьте следующее:

// Create a sprite group for all spikes, set common properties to ensure that
// sprites in the group don't move via gravity or by player collisions
this.spikes = this.physics.add.group({
  allowGravity: false,
  immovable: true
});

// Let's get the spike objects, these are NOT sprites
const spikeObjects = map.getObjectLayer('Spikes')['objects'];

// Now we create spikes in our sprite group for each object in our map
spikeObjects.forEach(spikeObject => {
  // Add new spikes to our sprite group, change the start y position to meet the platform
  const spike = this.spikes.create(spikeObject.x, spikeObject.y + 200 - spikeObject.height, 'spike').setOrigin(0, 0);
});

Мы должны получить это:

Шипы добавлены

Граница столкновения Spike Spike намного выше, чем сами шипы. Если оставить без изменений, что может создать плохое опыт игры. Игроки будут сбрасывать свою позицию, не ударяя спрайт! Давайте отрегулируем тела шипов, чтобы быть меньше по размеру, особенно высота. Заменить foreach с этим:

spikeObjects.forEach(spikeObject => {
  const spike = this.spikes.create(spikeObject.x, spikeObject.y + 200 - spikeObject.height, 'spike').setOrigin(0, 0);
  spike.body.setSize(spike.width, spike.height - 20).setOffset(0, 20);
});

Чтобы правильно удерживать ограничительную коробку, охватывающую шипы, мы добавляем смещение, которое соответствует снижению высоты. Теперь у нас есть более подходящие спрайты Spike:

Шипы добавлены

Столкновение с игроком

Если наш игрок сталкивается со списком, их положение сбрасывается. В платформенных играх распространена игр для игроков, чтобы иметь анимацию «проиграть». Давайте добавим мигающую анимацию, когда наш игрок сбрасывается. Во-первых, в создать Давайте добавим столкновение:

this.physics.add.collider(this.player, this.spikes, playerHit, null, this);

Логика для сброса игрока будет в PlayerHit функция. Каждый раз, когда игрок сталкивается с спрайтом из группы SPIKE SPRITE, эта функция будет называться. В конце файла добавьте следующее:

function playerHit(player, spike) {
  player.setVelocity(0, 0);
  player.setX(50);
  player.setY(300);
  player.play('idle', true);
  player.setAlpha(0);
  let tw = this.tweens.add({
    targets: player,
    alpha: 1,
    duration: 100,
    ease: 'Linear',
    repeat: 5,
  });
}

Несколько вещей происходит здесь. Давайте возьмем каждую строку инструкции по линии:

  • Установите скорость игрока до 0. Это гораздо более предсказуемо (и безопаснее), чтобы остановить движение игрока на перезапуске
  • Установите координаты X и Y в первую позицию игрока
  • Используйте анимацию холостого хода, как будто именно, когда игрок начал
  • Альфа Свойство контролирует непрозрачность спрайта. Это значение от 0 до 1, где 0 полностью прозрачен, а 1 полностью непрозрачна
  • Создайте Tween – «Анимация» свойства объекта игры. Tween применяется к объекту игрока, который столкнулся с шипом. Он устанавливает альфа-свойство на 1 (то есть делает наш игрок полностью видимым). Этот твин длится 100 мс, а непрозрачность увеличивается линейно, как отмечено легкость имущество. Это также повторяется 5 раз, следовательно, почему он выглядит как мигание.

Теперь наша игра выглядит так:

Полная игра

Примечание : Обязательно удалите Отладка: правда Недвижимость от конфигурации игры, прежде чем поделиться с друзьями, никогда не оставляйте Debug Mode в производстве!

Заключение

С помощью плиткой мы можем спроектировать как маленькие и экспансивные 2D игровые миры. Лучшая практика для создания слоев на глубину в нашем игровом мире. Затем мы взяли мир, который мы построили в плитке, и добавили его в нашу игру в фазер.

Мы добавили слой платформы в качестве статического слоя, что делает его неподвижным, когда игрок сталкивается. Затем мы создали группу SPRITE для шипов и создали функцию, чтобы обрабатывать столкновения между каждым шипом и проигрывателем.

В дополнение к созданию жизненного игрового мира, мы узнали, как оживить наш персонаж, используя ATLAS – большое изображение, которое содержит несколько небольших изображений, сопровождаемых файлом JSON, детализируя изображение в каждом кадре. Мы также использовали Tween, чтобы изменить свойство нашего спрайта в течение определенного периода времени.

С этими методами решать сделать следующий лучший платформер с Phaser!

Вы можете просмотреть аннотированный исходный код для игры здесь Отказ