Phaser游戏初级教程(二)
var platforms; function create() { //We're going to be using physics, so enable the Arcade Physics system game.physics.startSystem(Phaser.Physics.ARCADE); //A simple background for our game game.add.sprite(0, 0, 'sky'); //The platforms group contains the ground and the 2 ledges we can jump on platforms = game.add.group(); //We will enable physics for any object that is created in this group platforms.enableBody = true; //Here we create the ground. var ground = platforms.create(0, game.world.height - 64, 'ground'); //Scale it to fit the width of the game (the original sprite is 400x32 in size) ground.scale.setTo(2, 2); //This stops it from falling away when you jump on it ground.body.immovable = true; //Now let's create two ledges var ledge = platforms.create(400, 400, 'ground'); ledge.body.immovable = true; ledge = platforms.create(-150, 250, 'ground'); ledge.body.immovable = true; }
platforms = game.add.group();
准备一个玩家(NPC)
创建一个新的本地变量player然后添加以下的代码到create函数。
// The player and its settings player = game.add.sprite(32, game.world.height - 150, 'dude'); // We need to enable physics on the player game.physics.arcade.enable(player); // Player physics properties. Give the little guy a slight bounce. player.body.bounce.y = 0.2; player.body.gravity.y = 300; player.body.collideWorldBounds = true; // Our two animations, walking left and right. player.animations.add('left', [0, 1, 2, 3], 10, true); player.animations.add('right', [5, 6, 7, 8], 10, true);
这个创建一个新的子图形称作player,放置在x轴32像素,从游戏底部向上150像素的地方。我们指定它使用之前加载的dude资产。如果你回到preload函数看看你会看到dude被加载为精灵图,而非图片。这是因为它包含动画帧。整个精灵图看起来像这样:
从上图可以看到总共有9帧,4帧往左跑,1帧面向窗口,剩下的4帧往右跑。注意:Phaser是支持翻转精灵来节省动画帧的,但在本教程中我们没有用到。我们定义了两种动画分别命名为“right”“left”,“left”动画使用0,1,2和3帧,并以每秒10帧运行,参数“true”则表示动画循环,这是标准的运行周期,在相反的方向也是如此,随着动画的设置,我们还要创建一些物理属性
实体和速度:物理世界
Phaser支持多种不同的物理引擎,有Arcade Physics,Ninja Physics和P2.JS Full-Body Physics,在本教程中我们使用Arcade Physics,它使用简单,也是轻量级的,非常适合用于移动端浏览器。你会注意到我们的代码首先开启了物理引擎系统,然后将需要添加到物理世界中的每个sprite和Group添加进去。
一但一个sprite获得了新的特性(ArcadePhysics.Body),它就可以作为物理引擎的body对象来操作,body对象具有很多可以使用的属性,就像给sprite添加一个重力属性,简单如下:
player.body.gravity.y = 300;
此属性可以任意取值,但从逻辑上讲,这个值越大,就会感到越重,下落的也就越快。如果添加以上代码你将会看到NPC一直下落,完全忽略了我们之间创建的地面ground
这显然不是我们想要的,是什么导致的呢。
原因是我们没有在地面和角色间检测碰撞。我们已经告诉Phaser我们的地面和壁架是固定不动的。如果我们不这么做,当角色碰撞到它们,角色会停止下落一会儿,然后所有东西都会塌下。这是因为如果不指明不动,地面子图形是一个可动的物理物体(也称为动态物体),当角色撞击它,撞击力将作用于地面,这两个实体互换速度然后地面也就开始下落。
所以为了启用角色的碰撞和利用物理属性,我们需要在update函数里引入碰撞检测:
function update() { // Collide the player and the stars with the platforms game.physics.arcade.collide(player, platforms); }
update函数在核心游戏循环的每帧都会调用。Physics.collide是一个充满魔力的函数。它在两个物体间检测碰撞然后将碰撞的物体分开。所以我们在角色和平台组间使用这个函数。它足够聪明能为组的所有成员启用碰撞检测,所以角色将能和地面和所有的壁架碰撞。结果就是平台变得坚固:
下一章,我们就让NPC动起来!