Быстрый старт (обычная версия)
Phaser — это очень хороший игровой фреймворк HTML5, предназначенный для разработки игр HTML5 на ПК и мобильных устройствах.Это редкий артефакт.
Эта статья быстро познакомит вас с разработкой игр (мобильный терминал), подходящей для людей, которые хотят понять разработку игр или хотят инвестировать в разработку игр.Нет никаких сомнений в том, что Phaser — это игровая среда, которую стоит изучить.
обращать внимание
Хотя Phaser — очень хороший игровой фреймворк HTML5, у него есть и свои недостатки.Теперь, пожалуйста, обратите внимание на следующие две вещи, с которыми Phaser не справляется или с которыми очень трудно справиться:
1. 3D. Если вы хотите научиться делать крутую 3D-анимацию, вы можете научитьсяThree.js
2. Видео (мобильное). Если вам нужно встроить видео на страницы для мобильных устройств, используйте собственный тег видео HTML5. Если вам нужно лучшее расширение для видео, вы можете обратиться кVideo.js
Далее вы можете сначала открыть то, о чем мы говорим в этой статье.кейс(Сервак шлак, это может занять много времени, хахаха), прочитав этот кейс, вы можете сказать, что это такое, я могу сделать это с анимацией Jquery, ха-ха, я тоже говорил что-то похожее на великого бога раньше Тогда люди ясно сказали мне, что сравнение анимации Phaser с анимацией Jquery является оскорблением для Phaser.
Ну вот и все, лично я считаю, что слишком сложный кейс запутает людей, и это идет вразрез с целью нашего быстрого старта.Я считаю, что прочитав эту статью, вы сможете открыть главу о разработке игр. , свободно опишите мир, который вам нравится.
скажи это прямо
Прежде всего, чтобы правильно запустить наш кейс, вам нужен локальный сервер. Вам может быть интересно, почему мы не можем просто поставитьindex.html
Как насчет того, чтобы перетащить его в браузер и запустить?
Потому что это связано с протоколом, используемым для доступа к файлу. Когда вы запрашиваете что-либо в Интернете, вам нужно использовать HTTP, и сервер может гарантировать, что вы можете получить доступ только к тем файлам, которые вам нужны. Но когда вы перетаскиваете html-файл прямо в браузер и запускаете его напрямую, он загружается через локальную файловую систему (file://), поскольку локальная файловая система не имеет концепции домена, безопасности на уровне сервера, просто сырая файловая система.
Вы действительно хотите, чтобы JavaScript мог загружать файлы из любой точки файловой системы? Ответ, конечно, нет. Конечно, ваш компьютер тоже не согласится.
И Phaser необходимо загружать ресурсы: изображения, аудиофайлы, данные JSON или другие файлы Javascript. Для этого его нужно запустить под сервером.
Если вы не знаете, как настроить локальный сервер для запуска html-файлов, и это не является предметом нашей статьи, я могу предложить очень простой способ, вы можете попробовать следующее:
1. Откройте командную строку, введите следующую команду и нажмите Enter:npm install puer -g
(Если у вас нет npm, установите его самостоятельно.) 2. После завершения установки пуэра вызовите командную строку в корневой папке того кейса, который необходимо установить на локальном сервере, и введите следующее команду и нажмите Enter:puer -p 9999
следующим образом:
3. Если Puer работает успешно, будет выглядеть следующим образом и автоматически открыть браузер:
По адресу г.http://localhost:9999/вверх, нажмитеindex.html
Вы можете запустить Фазер
начать первый шаг
Сначала создайте нашу структуру каталогов следующим образом:
Картинки в папке img можно скачать сАдрес кода делаСкопируйте его, а потом найдете, эй, а как же на GitHub есть лишнее изображение sprites.png и файл sprites.xml, о котором речь пойдет позже, сейчас нам нужно только подготовить то, что нам нужно на данном этапе, в файле js/libsjquery.min.js
а такжеphaser.min.js
Пожалуйста, подготовьте свой собственный илиАдрес кода делаСкопируйте сверху, а затем нам нужно убедиться, что другие файлы пусты, чтобы мы могли быстро заполнить содержимое позже.
второй шаг
Во-первых, конечно, к нашемуindex.html
Заполните содержимое быстро, содержание выглядит следующим образом:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Phaser快速入门(普通版)</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
</head>
<style>
html,
body {
width: 100%;
height: 100%;
font-family: "Helvetica Neue", Helvetica, STHeiTi, sans-serif;
overflow: hidden;
background: #fff;
margin: 0;
padding: 0;
}
.main {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.main img {
width: 100%;
height: 100%;
}
</style>
<body>
<!--H5页面所有动画的canvas载体-->
<div id="game-container"></div>
<!--预加载背景,防止预加载的资源加载太久以致屏幕长时间空白-->
<div class="main">
<img src="img/bg.png" alt="">
</div>
</body>
<script src="js/libs/jquery.min.js"></script>
<script src="js/states/utils.js"></script>
<script src="js/libs/phaser.min.js"></script>
<script src="js/states/boot.js"></script>
<script src="js/states/preload.js"></script>
<script src="js/states/state1.js"></script>
<script src="js/states/state2.js"></script>
<script src="js/app.js"></script>
</html>
Ок, содержимое заполнено.В этом файле в первую очередь все анимации в нашем случае разнесены по idgame-container
на элементе , то классmain
Элемент представляет собой предзагруженный фон, если вам после прочтения комментариев не очень понятно его предназначение, то можете не углубляться в него, и это станет ясно позже.
Тогда вы также обнаружите, что мы импортировалиjquery.min.js
, у вас могут возникнуть такие вопросы, для чего это? Нужно ли мне по-прежнему импортировать Jquery при использовании Phaser? Ответ определенно нет, импортируйте Jquery, чтобы потом что-то доказать. utils.js инкапсулирует некоторые операции, которые мы часто используем позже (эффект полноэкранного режима, масштабирование изображения).
Далее мы сосредоточимся на механике того, как работает наш кейс.Давайте взглянем на наши 5 основных файлов:
<script src="js/states/boot.js"></script>
<script src="js/states/preload.js"></script>
<script src="js/states/state1.js"></script>
<script src="js/states/state2.js"></script>
<script src="js/app.js"></script>
Порядок оформления этих пяти документов таков:
app.js
-> boot.js
-> preload.js
-> state1.js
-> state2.js
существуетapp.js
внутри будет выполнятьboot.js
,preload.js
,state1.js
,state2.js
эти 4 сценария, поэтомуapp.js
Нужно импортироватьboot.js
,preload.js
,state1.js
,state2.js
Импортируйте после этих 4 файлов. Затем разберите эти 5 файлов один за другим.
app.js
Этот файл является первым файлом, который выполняет наш Phaser.Он в основном настраивает некоторые аспекты разработки игры, включая установку пути к нашим ресурсам, монтирование элементов, добавление сцен, запуск сцен и т. д.
Конкретный код выглядит следующим образом:
(function() {
'use strict'
// 设置资源目录(项目根目录)
var baseURI ='../..'
//将图片目录放在内存中,方便全局调用
localStorage.baseURI = baseURI
//设置$('#game-container')的高度等于屏幕的高度(这里用原生js代码书写)
document.getElementById('game-container').style.height = document.body.clientHeight + 'px'
//获取屏幕的缩放比
var Ratio = window.devicePixelRatio
//获取屏幕的宽和高
var w = document.documentElement.clientWidth || document.body.clientWidth
var h = document.documentElement.clientHeight || document.body.clientHeight
//因为我们在index.html设置了禁止缩放的meta头
//<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
//所以当我们将屏幕的宽和高直接传入Phaser.Game对象时,浏览器会自动将canvas按屏幕的缩放比缩放,也就是当你的屏幕缩放比是2时,canvas宽高你设置成屏幕的宽高时实际看到的却只有一半,因此相应我们需要将画布放大Ratio倍
var ww = Ratio * w
var hh = Ratio * h
//前两个参数是Phaser要创建的canvas元素的宽高,第三个参数是游戏渲染的引擎,这里让Phaser自己识别设置即可,第四个参数是游戏挂载在哪个元素上
var game = new Phaser.Game(ww, hh, Phaser.AUTO, 'game-container')
//添加场景
game.state.add('Boot', Boot)
game.state.add('Preload', Preload)
game.state.add('State1', State1)
game.state.add('State2', State2)
//启动场景
game.state.start('Boot')
})(window)
Каждая строка кода выше была прокомментирована соответствующим образом. Если у вас есть время, вы можете посмотреть и понять это ясно. Теперь нам просто нужно знатьapp.js
Просто настроить и запустить нашу первую сцену (boot.js
) Сделаю.
Прежде чем говорить о нашей сцене, давайте сначала разберемся, что такое сцена. Сцена является основной частью нашей разработки игры Phaser. Все игровые анимации, которые мы видим, реализованы в сцене. Сцена может быть пользовательским объектом js или функцией A. , если есть любой из трех методов предварительной загрузки, создания и обновления, является допустимой сценой (всего 5 методов, два других — методы init и render).
Метод init: код инициализации некоторых сцен может быть записан в этом методе и выполнен первым.
метод предварительной загрузки: используется для загрузки ресурсов, если нет метода инициализации, он будет выполнен первым.
create method: Инициализируйте и создайте сцену, она будет выполнена после того, как будут загружены все ресурсы, загруженные в методе предварительной загрузки.
метод обновления: функция обновления, которая будет выполняться каждый кадр игры, обычно раз в 1/60 секунды.
метод рендеринга: каждый цикл рендеринга будет вызывать игру, используемую для выполнения некоторой пользовательской работы по рендерингу.
boot.js
Эта сцена не показывается пользователю, только чтобы загрузить следующую сцену (т.е. предварительно загрузить сценуpreload.js
) необходимые ресурсы, поэтому ресурсы не могут быть загружены слишком много, если их слишком много, экран будет черным в течение длительного времени (черный экран на самом деле является процессом загрузки ресурсов в этой сцене, потому что это первая сцена, и нет предыдущей сцены, которая помогла бы вам загрузить его. Ресурсы используются для построения интерфейса, поэтому нет интерфейса, который можно было бы отобразить для удобства пользователя), и мы также занимаемся этой проблемой.index.html
использовать $('.main')
Решите, сначала покажите$('.main')
Интерфейс, отображаемый этим элементом (фон интерфейса должен быть таким же, как фон предварительно загруженной сцены), чтобы сцена загружалась слишком долго, чтобы обеспечить хорошее взаимодействие с пользователем, и когда сцена загружается$('.main')
Это также может обеспечить хорошее соединение с предварительно загруженной сценой.
Конкретный код выглядит следующим образом:
var Boot = function(game) {
var baseURI = localStorage.baseURI
this.init = function() {
//game.device.desktop判断是WAP端还是PC端,true为PC端,false为WAP端
if (!game.device.desktop) {
//设置游戏背景色
game.stage.backgroundColor = '#282C34';
//鼠标指针对象,由于WAP端没有鼠标,因此设置为1(即为null)
game.input.maxPointers = 1;
//缩放控制,这里将画布(canvas)拉伸至填满父容器(即#game-container),不保持比例
game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
//启用时,显示画布(canvas)将在父容器中水平对齐
game.scale.pageAlignHorizontally = true;
//启用时,显示画布(canvas)将在父容器中垂直对齐
game.scale.pageAlignVertically = true;
//强制游戏只能以一个方向运行,这里设置游戏仅能在纵向模式运行(true),无法再横向模式运行(false)
game.scale.forceOrientation(false, true);
//当forceOrientation设置只能纵向模式运行,把手机横向摆放就会调用enterIncorrectOrientation这个方法
game.scale.enterIncorrectOrientation.add(enterIncorrectOrientation, this);
//当forceOrientation设置只能纵向模式运行,把手机横向摆放就会调用enterIncorrectOrientation这个方法,重新将手机纵向摆放就会调用leaveIncorrectOrientation这个方法
game.scale.leaveIncorrectOrientation.add(leaveIncorrectOrientation, this);
}else{
game.scale.pageAlignHorizontally = true
game.scale.pageAlignVertically = true
//防止浏览器失去焦点后动画暂停,如果考虑到计算机性能可以设置为false
game.stage.disableVisibilityChange = true;
}
}
this.preload = function() {
//设置图片支持跨域请求
game.load.crossOrigin = true
//加载预加载界面所需的资源,可以看到图片跟$('.main')界面一致,第一个参数是创建sprite对象时所需要的资源标识,第二个参数是资源所在路径
game.load.image('start_bg', baseURI + '/img/bg.png')
}
this.create = function() {
//跳转到下一个场景
game.state.start('Preload');
}
function enterIncorrectOrientation() {
alert('请将手机纵向摆放');
}
function leaveIncorrectOrientation() {
alert('已经将手机纵向摆放');
}
}
Каждая строчка кода выше прокомментирована соответствующими комментариями.Если есть время, то можете посмотреть и разобраться понятно.Теперь нам нужно только знатьboot.js
Просто чтобы настроить все наши сцены и загрузить нашу вторую сцену (предварительная загрузка сценыpreload.js
) необходимые ресурсы.
preload.js
Эта сцена является предварительно загруженной сценой, которая будет загружать ресурсы всех последующих сцен.Поскольку ресурсов загружено много, в этой сцене нам нужно по-дружески показать процесс загрузки наших ресурсов.Предыдущая сцена уже помогла нам загрузитьstart_bg
Ресурсы и собственный текстовый объект Phaser (показывающий ход загрузки).
существуетpreload.js
Обратите особое внимание на то, что нам нужно загрузить изображение кадра (для достижения эффекта анимации)
//加载帧图片,第一个参数是创建sprite对象时所需要的资源标识,第二个参数是图片所在路径,第三个参数是标识图片xml文件
game.load.atlasXML('sprites', baseURI + '/img/sprites.png',baseURI + '/img/sprites.xml')
Для загрузки изображения рамы нам нужно общий образ со всеми действиями и файлом конфигурации XML. Таким образом, вопрос в том, почему нам нужны два файла? Почему бы нам просто сделать изображение кадра в движущуюся картинку, а затем отображать его? Эта проблема на самом деле очень проста. Прежде всего, движущаяся картина намного больше Статическое изображение (XML Файл слишком мал, чтобы игнорировать), и мы не можем контролировать скорость переключения анимации в коде.
Ну а теперь по нашей задумке, если у нас есть две картинки, которые нужно анимировать в Phaser, например такие:
Тогда как мы объединим их в общую картину и XML-файл конфигурации, который нам нужен? В настоящее время нам нужно программное обеспечение, которое поможет нам справиться с этим.Здесь я представлю Shoebox:
После завершения загрузки и установки мы открываем Shoebox и вместе перемещаем кадры картинок, которые необходимо синтезировать, на лист спрайтов, и отпускаем, как показано на рисунке:
Нажмите Сохранить, изображение кадра и xml-файл будут сгенерированы:
Файл xml в основном записывает информацию о расположении и названии каждого изображения действия, содержащегося в нашей картинке кадра.Конечно, это не является предметом нашего внимания.
Конкретный код выглядит следующим образом:
var Preload = function(game) {
var baseURI = localStorage.baseURI
var tool = new utils()
var w = null
var h = null
var start_bg = null
var loading = null
this.init = function() {
//获取画布的宽高,即Ratio倍屏幕宽高
w = game.width
h = game.height
//动画组,方便统一处理多个对象的动画
group=game.add.group()
//将$('.main')元素隐藏
$('.main').hide()
//由于start_bg跟$('.mian')界面一致,用户是看不出$('.mian')隐藏start_bg显示这个过程的
//创建sprite对象,第一个参数是画布x坐标(距离画布左边缘多远),第二个参数是画布y坐标(距离画布上边缘多远),第三个参数是构建对象的资源
start_bg = game.add.sprite(0, 0, 'start_bg')
//将start_bg宽高设置全屏
tool.setFull(start_bg)
//创建文本对象,前面两个参数跟sprite等同,第三个参数是文本内容,第四个参数是文本样式
loading=game.add.text(w*.5, h*.5, '0%',
{
fontSize:60,
fill:'#ffffff'
})
//锚点位置(相对自身),第一个参数是相对自身左移多少(.5是左移自身宽度的50%),第二个参数是相对自身上移多少(.5是上移自身高度的50%)
loading.anchor.set(.5, .5)
//loading最后的位置是相对画布居中
//loading的补间动画,from(从怎样的状态转变到默认状态),to(从默认状态转变到怎样的状态),这里用的是from
//第一个参数:一个js对象,包含着需要进行动画的属性,{ alpha: 0 }表示透明度为0
//第二个参数:动画的持续时间
//第三个参数:动画过程函数,默认为匀速动画Phaser.Easing.Linear.None
//第四个参数:是否自动开始
//第五个参数:动画开始前的延迟时间,单位是毫秒
//第六个参数:动画重复的次数,如果需要动画永远循环,则把该值设为 Number.MAX_VALUE
//第七个参数:是否自动反转
game.add.tween(loading).from({ alpha: 0 }, 500, null, true, 0, 0, false)
}
this.preload = function() {
game.load.crossOrigin = true
//加载帧图片,第一个参数是创建sprite对象时所需要的资源标识,第二个参数是图片所在路径,第三个参数是标识图片xml文件
game.load.atlasXML('sprites', baseURI + '/img/sprites.png',baseURI + '/img/sprites.xml')
game.load.image('next', baseURI + '/img/next.png')
game.load.image('img2_1', baseURI + '/img/2_1.jpg')
game.load.image('img2_2', baseURI + '/img/2_2.jpg')
//这个方法是文件加载过程,返回的progeress是完成的进度,0~100
game.load.onFileComplete.add(function(progeress) {
loading.setText(progeress + '%')
})
//所有文件都完成加载时会调用这个方法,我们可以在调用这个方法的时候跳转到下一个场景,效果等同于在create方法执行game.state.start('State1')
game.load.onLoadComplete.add(function() {
game.state.start('State1')
})
}
this.create = function() {
//game.state.start('State1') }
this.update = function() {}
}
Мы должны обратить особое внимание на приведенный выше код$('.main').hide(), который мы также импортировали ранееjquery.min.js
Нужно доказать, что вы можете написать любой код Jquery в Phaser.
Если два вышеуказанных сценария (boot.js
а такжеpreload.js
) вы полностью усвоили и поняли слова, то следующие два сценария (state1.js
а такжеstate2.js
) Я думаю, вы можете прочитать это очень быстро.
state1.js
Эта сцена в основном применяется к анимации Phaser, событиям и использованию групп анимации. Внимательные друзья здесь могут видеть, что мы написали код, первоначально написанный в методе создания, для инициализации и построения сцены в методе предварительной загрузки.Насколько мой опыт касается, пока сцена не требует предварительной загрузки ресурсов, метод предварительной загрузки и метод create не требует предварительной загрузки, разницы в полезности нет.
Конкретный код выглядит следующим образом:
var State1 = function(game) {
var baseURI = localStorage.baseURI
var tool = new utils()
var w = null
var h = null
var next=null
var sprites=null
var group=null
this.preload = function() {
w = game.width
h = game.height
//动画组,方便统一处理多个对象的动画
group=game.add.group()
//第四个参数是没有加入动画时静态展示第几帧图片
sprites=game.add.sprite(w*.5,h*.6,'sprites',0)
tool.setSize(sprites,'width',w*.5)
sprites.anchor.set(.5,1)
//给sprite对象添加一个新动画,第一个参数是动画名称
sprites.animations.add('run')
//播放动画,第一个参数是动画名称,第二个参数是播放的速率,第三个参数是是否循环
sprites.animations.play('run',4,true)
//将start_bg加入动画组
group.add(sprites)
next=game.add.sprite(w*.5,h*.8,'next')
tool.setSize(next,'width',w*.3)
next.anchor.set(.5,.5)
game.add.tween(next).to({ width:next.width+20,height:next.height+20 }, 500, Phaser.Easing.Linear.In, true, 0, -1, true)
group.add(next)
//默认情况下,游戏对象不会处理任何事件,所以我们需要让它可以处理事件
next.inputEnabled = true
//当对next对象点击然后手指放开的时候触发
next.events.onInputUp.add(function() {
//onComplete方法是补间动画完成后的回调,我们可以在跳转到下一个场景的时候做一些用户体验比较良好的当前场景的退场动画(这里的退场动画类似淡出效果)
game.add.tween(group).to({ alpha: 0 }, 500, Phaser.Easing.Linear.In, true, 0, 0, false).onComplete.add(function() {
game.state.start('State2')
})
})
}
}
state2.js
Эта сцена просто продолжает предыдущую сценуnext
Щелчок кнопки прыгает.
var State2 = function(game) {
var w = null
var h = null
var img2_1=null
var img2_2=null
this.preload = function() {
w = game.width
h = game.height
img2_1=game.add.sprite(0,h*.5,'img2_1')
img2_1.width=w
img2_1.height=h*.5
img2_1.anchor.set(0,1)
game.add.tween(img2_1).to({ y:h }, 2000, Phaser.Easing.Linear.In, true, 500, -1, true)
img2_2=game.add.sprite(0,h*.5,'img2_2')
img2_2.width=w
img2_2.height=h*.5
game.add.tween(img2_2).to({ y:0 }, 2000, Phaser.Easing.Linear.In, true, 500, -1, true)
}
this.create = function() {}
}
хорошо,state2.js
Я не буду идти в слишком много подробностей. После этого, я верю, что вы уже знаете, какой эффект анимации это сцена.
Куриный суп, приготовленный за день
Что ж, давайте закончим на этом, у Фазера слишком много интересных мест, которые ждут вас, чтобы открыть для себя, если вы хотите узнать больше, вы можете пойти прямоОфициальный сайт, есть много интересных маленьких примеров.
Особая благодарность косоглазому коту Ли Шицану за то, что сводил меня с ума, и за техническую поддержку этой статьи.
Здесь я поздравляю всех со счастливым двойным 12 и продвижением в карьере!