原文地址:Phaser教程1
Phaser是一个html5游戏框架,可以帮助开发者快速地制作功能强大、跨浏览器的html5游戏。它唯一的浏览器要求是对canvas标签的支持。
首先创建一个新的html文档,并在页面中引入phaser.js文件
<script src="phaser.min.js"></script>
接下来需要写这样一段代码:
var game = new Phaser.Game(800, 600, Phaser.AUTO, '', {preload: preload, create: create, update: update});
function preload() {
}
function create() {
}
function update() {
}
创建一个Phaser.Game
对象的实例,并命名为game
。
把它命名为game
是一个常见的做法。参看Game API
在preload
函数中调用game.load
函数。Phaser启动时会自动查询这个函数并加载其中定义的内容。
function preload() {
game.load.image('sky', 'assets/sky.png');
game.load.image('ground', 'assets/platform.png');
game.load.image('star', 'assets/star.png');
game.load.spritesheet('dude', 'assets/dude.png', 32, 48);
}
在create函数中添加如下代码添加小元素
function create() {
game.add.sprite(0, 0, 'star');
}
打开浏览器,会看到黑色的游戏屏幕和左上角的小星星。
图片的展示顺序和创建顺序相同。如果想给小星星放置一个背景,就要将背景创建在小星星前面。
通过game.add.sprite
创建了一个Phaser.Sprite
对象,并添加精灵图到game world
,创建的所有的对象都在game world
中。
game world
没有固定的大小,它以(0,0)为中心,无限地向四面八方扩展。为了方便,(0,0)放置在game world
的左上角,但是通过内置的Camera,可以根据需要移动它。
game world
的类可以通过game.world
访问,其中有许多方便的方法和属性。也有一些简单的属性如game.world.height
。
通过添加背景和平台创建场景:
var platforms;
function create() {
//添加游戏背景
game.add.sprite(0, 0, 'sky');
//平台组。包括地面和两个可以跳上去的壁架
platforms = game.add.group();
//启用平台组内所有对象的物理属性
platforms.enableBody = true;
//创建地面
var ground = platforms.create(0, game.world.height - 64, 'ground');
//将地面缩放以适合游戏画布的宽度
ground.scale.setTo(2, 2);
//阻止地面移动(发生碰撞时)
ground.body.immovable = true;
//创建壁架
var ledge = platforms.create(400, 400, 'ground');
ledge.body.immovable = true;
ledge = platforms.create(-150, 250, 'ground');
ledge.body.immovable = true;
}
组有强大的功能,就像这个名字一样,可以把一些类似的对象组合在一起,并且把它们作为一个单一的单元控制。在这个游戏中将创建两个组,其中一个就是上面代码中所创建的platforms
就像创建精灵元素一样,使用game.add
创建组对象,将其分配给platforms
局部变量,之后就可以添加对象。首先是地面,位于游戏画布的最下面,地面被缩放来适应游戏画布的宽度。最后我们将它的immovable
属性设置为true
,否则,当玩家与它碰撞时它就会移动。之后创建了两个较小的壁架,玩家在上面的跳跃效果与地面相同。
创建一个新变量player
,在create
函数中输入下面这些代码。
//创建玩家
player = game.add.sprite(32, game.world.height - 150, 'dude');
//使其物理属性可用
game.physics.arcade.enable(player);
//设置玩家的一些物理属性
player.body.bounce.y = 0.2;//反弹
player.body.gravity.y = 300; //重力
player.body.collideWorldBounds = true;
//两个动画,向左与向右
player.animations.add('left', [0, 1, 2, 3], 10, true);
player.animations.add('right', [5, 6, 7, 8], 10, true);
创建了一个叫做player
的精灵元素,定位在游戏画布底部150像素,距离游戏画布左边32像素的地方。使用之前加在的'dude'
。'dude'
是作为精灵图表加载的,因为它包含着许多帧。通过图片可以看出共有9帧,4个朝左边跑的,1个正面的,4个朝右边跑的。Phaser
支持翻转精灵图,这样可以少加载几帧。本教程没有使用。
定义了两个动画分别叫做left
和right
。left
动画使用0,1,2,3帧,并且每秒10帧。true
参数表示动画循环。这是一个标准的跑动周期,右边也是如此。通过设置动画,我们创建了一些新的物理属性。
Phaser
支持很多种不同的物理系统,有Arcade Physics
,Ninja Physics
和P2.JS Full-Body Physics
。本教程使用Arcade Physics
系统,这个系统简单轻便,适合手机浏览器。在代码中必须运行物理系统,然后使用物理系统的每个精灵或者每个组,必须启用它们。一旦启用,精灵会或得一个新的body
属性,是ArcadePhysics.Body
的实例,这意味着精灵将会在Phaser's Arcade Physics
引擎中作为一个物理体。这个body
本身有很多好玩的属性。为了模拟重力对精灵的影响,只需要这样简单的一句代码:
player.body.gravity.y = 300;
上面代码给了重力一个任意值。从逻辑上来说,值越大,物理感觉越重,速度越快。如果将其添加到代码中运行,就会看到玩家不停的下降,完全忽略之前创建的地面,原因是我们还没有测试地面和玩家之间的碰撞。地面和壁架都已经设置为不可移动的,如果没有这么做,当玩家和它们相撞时,玩家会停下来一会然后一切都会崩溃。这是因为除非另有说明,地面精灵是一个移动的物体(也称为动体)当玩家击中它的时候,碰撞力施加到地面上,因此,这两个如理交换它们的速度,地面也开始下降。所以为了让玩家碰撞并利用物理属性,我们需要在update
函数中引入碰撞检查。
var hitPlatform = game.physics.arcade.collide(player, platforms);
update
函数由核心游戏循环每帧调用。Physics.collide
函数需要两个对象碰撞并分离。在这个例子中我们给它的两个对象是玩家和平台组,它会很智能地检测玩家与所有组成员之间的碰撞。
Phaser
有一个内置的键盘管理器,它的好处之一可以帮助我们实现玩家的移动。
cursors = game.input.keyboard.createCursorKeys();
//在函数外面定义变量cursor,并将这行代码写在create函数中
这将使cursors
对象具有四个属性,up
,down
,left
,right
,这些都是Phaser.Key
对象的实例。现在我们要做的就是将下面这些代码放到我们的更新循环中,也就是update
函数中。
//重置玩家的速度
player.body.velocity.x = 0;
if (cursors.left.isDown)
{
// 向左移动
player.body.velocity.x = -150;
player.animations.play('left');
}
else if (cursors.right.isDown)
{
// 向右移动
player.body.velocity.x = 150;
player.animations.play('right');
}
else
{
// 静止站立
player.animations.stop();
player.frame = 4;
}
// 当玩家在地面上时,按下键盘上向上键,玩家跳
if (cursors.up.isDown && player.body.touching.down && hitPlatform)
{
player.body.velocity.y = -350;
}
上面的代码中,第一件事是重置精灵的水平速度。之后检查是否按住左光标键,如果按住了,给精灵一个负的水平速度并开始left
跑动动画。如果按住的是向右的方向键,就做相反的事。通过重置速度和设置每一帧图片,产生了停止-跑动的移动状态。玩家精灵只有在按住按键的时候才会移动,一旦停止按键,就会立即停止移动。用Phaser
还可以创建更复杂的运动效果,比如带动力和加速度的效果,但是对于这个教程动画效果已经是我们所需要的了。最后一部分键盘检查,如果没有按键被按下,则设置为第4帧。精灵图表中的第4帧是一个正对着你的玩家。
代码的最后部分增加了玩家的跳跃功能。向上的方向键是跳跃键,检测它是否被按下。也要测试玩家是否与地面接触,否则它可能在半空中跳跃。检查变量hitPlatform
只是为了确保玩家是与地面碰撞而不是与其它的东西碰撞。如果两个条件都满足,就给玩家添加一个垂直方向的速度350,因为之前我们添加的重力值,所以玩家会自动的落下。
是时候给我们的小游戏一个目标性了。在场景中撒一些星星,并让玩家收集它们。为了实现这个目标,我们创建了一个新的组Group
起名为stars
并填充它。在create
函数中添加如下代码:
stars = game.add.group();
stars.enableBody = true;
// 创建12个星星
for (var i = 0; i < 12; i++)
{
var star = stars.create(i * 70, 0, 'star');
// 添加重力
star.body.gravity.y = 6;
// 给星星随机的反弹值
star.body.bounce.y = 0.7 + Math.random() * 0.2;
}
创建星星的过程与我们创建平台组的过程相似。使用for
循环创建了12颗星星。它们的x坐标是i * 70
,以为着它们将在70像素的场景中均匀分布。像玩家对象一样,也给星星一个重力值,使它们能够自然下落,并给它们一个反弹值,当它们碰到平台的时候会反弹一点。反弹值是介于0(完全不反弹)和1(全反弹)之间的值。我们设置的反弹值再0.7到0.9之间。如果就这样运行代码,星星会一直向下落。为了阻止它一直下落,我们需要在更新循环中检查它们与平台的碰撞。
game.physics.arcade.collide(stars, platforms);
检查玩家是否与星星重叠。
game.physics.arcade.overlap(player, stars, collectStar, null, this);
如果有重叠,则传递collectStar
函数。
function collectStar (player, star) {
// 从屏幕中移出星星
star.kill();
}
简单地将星星杀掉,也就是在现实中被移出。现在运行游戏,可以看到一个能够跑动、跳跃、收集星星的玩家。
最后一个调整就是添加分数。使用一个Phaser.Text
对象来做到这一点。先创建两个新变量,一个保存实际的分数,一个保存文本对象本身。
var score = 0;
var scoreText;
在create
函数中添加如下代码,创建scoreText
scoreText = game.add.text(16, 16, 'score: 0', { fontSize: '32px', fill: '#000' });
16x16
是文本显示的坐标。score:0
是要显示的默认字符串,后面的对象中包括字体大小和字体颜色,如果不指定字体,将使用浏览器的默认字体,所以在Windows上是宋体的。接下来我们要修改collectStar
函数,这样当玩家拿起一颗星星时,他们的分数会增加,文字会更新来反应这一点:
function collectStar (player, star) {
star.kill();
score += 10;
scoreText.text = 'Score: ' + score;
}
每次收集一颗星星增加10分,分数文字也随着更新。