我在之前的教程中说过,所有游戏窗口中能看到的元素,几乎都是有有x,y坐标的,通过对改变坐标值,就可以实现它的移动操作,比如下面这个奔跑的机器人:
function preload() {
game.load.atlasJSONHash('bot', 'assets/sprites/running_bot.png', 'assets/sprites/running_bot.json');
}
var s;
function create() {
s = game.add.sprite(game.world.centerX, game.world.centerY, 'bot');
s.anchor.setTo(0.5, 0.5);
s.animations.add('run');
s.animations.play('run', 10, true);
}
function update() {
if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT))
{
s.x -= 4;
}
else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
s.x += 4;
}
if (game.input.keyboard.isDown(Phaser.Keyboard.UP))
{
s.y -= 4;
}
else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN))
{
s.y += 4;
}
}
function render() {
game.debug.spriteInfo(s, 20, 32);
}
这个例子中,我定义了上下左右四个方向键,使它们分别可以控制机器人的xy坐标增减,当你按下按键时,你会发想机器人的位置也发生了,这样就实现了位移的操作,就是这么简单。
再来说说拖拽,拖拽的操作很简单:按下、移动、松开,相应地也就有了三个状态的事件,查看下面的代码:var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, render: render });
function preload() {
game.load.image('grid', 'assets/tests/debug-grid-1920x1920.png');
game.load.image('atari', 'assets/sprites/atari800xl.png');
game.load.image('sonic', 'assets/sprites/sonic_havok_sanity.png');
}
var result = 'Drag a sprite';
function create() {
//设置背景
game.add.sprite(0, 0, 'grid');
//添加一个对象组,设置对象组可用
var group = game.add.group();
group.inputEnableChildren = true;
var atari = group.create(32, 100, 'atari');
// 使atari对象可以操作
atari.inputEnabled = true;
atari.input.enableDrag();
// atari.input.enableDrag(true, true, true);
atari.events.onDragStart.add(onDragStart, this);
atari.events.onDragStop.add(onDragStop, this);
var sonic = group.create(300, 200, 'sonic');
sonic.inputEnabled = true;
sonic.input.enableDrag();
// sonic.input.enableDrag(true, true, true);
sonic.events.onDragStart.add(onDragStart, this);
sonic.events.onDragStop.add(onDragStop, this);
group.onChildInputDown.add(onDown, this);
}
function onDown(sprite, pointer) {
result = "Down " + sprite.key;
console.log('down', sprite.key);
}
function onDragStart(sprite, pointer) {
result = "Dragging " + sprite.key;
}
function onDragStop(sprite, pointer) {
result = sprite.key + " dropped at x:" + pointer.x + " y: " + pointer.y;
if (pointer.y > 400)
{
console.log('input disabled on', sprite.key);
sprite.input.enabled = false;
sprite.sendToBack();
}
}
function render() {
game.debug.text(result, 10, 20);
game.debug.text('拖动结束时纵坐标大于400,将禁止再次拖动!', 30, 560);
//game.add.text(30, 560, '拖动结束时纵坐标大于400,将禁止再次拖动!', {font: '24px Arial'}); //这句是错误示例,一定要避免这样使用,输出调试信息时,一定要使用game.debug.xxxxinfo()方法。
}
运行了上面的代码之后,再把那两行注释的代码取消注释,再运行下,你会发现其中有着明显地不同,相比较而言,参数为true的拖动效果要稍微好一些,这里,就要介绍一下enableDrag的参数了(具体描述在API都有,链接在这:http://phaser.io/docs/2.6.2/Phaser.InputHandler.html#enableDrag):
enableDrag(lockCenter,bringToTop, pixelPerfect, alphaThreshold, boundsRect, boundsSprite)
六个参数,含义如下:
lockCenter:是否锁定中心,无论你按下的位置是在sprite的哪里,下一个画面sprite中心就会出现在你按下的地方;
bringToTop:是否置顶,就是拖动结束后是否位于最顶层;
pixelPerfect:是否启用像素识别,这样翻译有利于理解,一张png图片只可能是矩形,但是上面的图像不一定占满整个矩形,如果启用像素识别,代码会判断你点击的位置是否在图像上,如果点击的位置在空白区域,则拖动无效;
alphaThreshold:像素识别的精度,取值范围0~255,数值越大精度越高;
boundsRect:定义矩形边界;
boundsSprite:定义一个sprite为边界,你可以试着添加一个和游戏窗口一样大的sprite图片,然后参数设置为它试下。
●注意:注意看render方法中添加的文字提示,如果想自己添加调试信息,就是用game.debug,如果没注意使用了下面的game.add,打开任务管理器,你就会发现你的浏览器内存一直在增加……
最后再来说说补间动画,补间动画的概念大家都知道,其实说白了就是一个状态向另一个状态的变更,Phaserjs也提供了一个tween的构造器,可以修改对象的一个或多个属性,非常适用于对象的透明度、缩放等状态的改变,来看一个简单的例子:var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create });
function preload() {
game.load.image('tile', 'assets/sprites/p2.jpeg');
game.load.spritesheet('monster', 'assets/sprites/pixi_monsters.png', 154, 170);
}
function create() {
// 设置一个边距使game.world比game.camera对象要大,否则无法实现game.camera的晃动效果
var margin = 50;
var x = -margin;
var y = -margin;
var w = game.world.width + margin * 2;
var h = game.world.height + margin * 2;
game.world.setBounds(x, y, w, h);
//确认camera的位置是在0,0这个坐标
game.world.camera.position.set(0);
//添加一个背景图片
game.add.tileSprite(x, y, w, h, 'tile');
//添加一个图像,看起来清楚些
var monster = game.add.sprite(400, 300, 'monster', 0);
monster.anchor.setTo(0.5);
//了解一下Phaser.Easing对象
console.log(Phaser.Easing);
//定义和执行动画
addQuake();
}
function addQuake() {
//定义移动的距离
var rumbleOffset = 50;
//从相机当前的位置开始移动
var properties = {
x: game.camera.x - rumbleOffset
};
//持续时间
var duration = 100;
//重复次数
var repeat = 4;
//动画方式,支持对象和字符串两种方式
//var ease = Phaser.Easing.Linear.None;
var ease = 'Linear';
//设置为true可以自动开始,false则需要手动调用start()方法
var autoStart = false;
//延迟x毫秒后开始
var delay = 1000;
//是否回到起始位置
var yoyo = true;
var quake = game.add.tween(game.camera)
.to(properties, duration, ease, autoStart, delay, 0, yoyo);
//我们定义结束后重新开始动画
quake.onComplete.addOnce(addQuake);
//开始动画
quake.start();
}
这里展示了一个简单的补间动画(参数的含义已经注释了),通过移动相机的位置使视图窗口内的元素发生变换,同时通过onComplete属性在动画结束时重新执行当前动画,使之无限循环。
补间动画中,最重要的两个方法就是to和from了,因为这两个方法定义了状态的变更,它们的参数完全一样,只不过动画的起点不一样。至于其他的属性和方法,都很常规,有兴趣的可以去官网上仔细地看下:http://phaser.io/docs/2.6.2/Phaser.Tween.html,同时在下载的官方示例中,有很多补间动画的例子,不过讲的有些零散,大家还是都找出来运行下,看一下其中的知识点。
我本来是想具体说一下Phaser.Easing对象的,后来想了想,还是自己动手记得比较熟练,所以已经打印在控制台了,同学们可以把感兴趣的都挑出来试一下,说实话,其实跟js的没有太大区别。
好了,这一节我们讲到了一些简单的操作,操作虽然简单,但要熟练使用,还需要多多的练习,这一节就到这里,下一节了解一下物理引擎的简单使用。