跳转至

Phaser3官网实例学习笔记

说明#

  1. 本文是随时更新的,最终会累积成一个便览手册;可通过搜索或底端的目录快速查找。
  2. 这是我学习Phaser3官网实例的笔记,对快速了解Phaser3能做什么、API概貌也许有帮助。以前做过一篇《Phaser2官网实例学习笔记》
  3. 阅读本文前,您需要对Phaser的场景结构有大致了解。(如果你完全不了解Phaser,宜先学习官网入门教程,以便对框架结构有整体了解。)笔记只摘录了关键语句,加了少量注释;语句不完整、不连续;为便于字面理解,有些类实例名称调整得更接近类名,如Sprite实例名称一般改作sprite
  4. 摘录的代码都是片段。我用的是TypeScript语言,但摘录的代码可能是JavaScript,或在此基础上添加了TypeScript类型标记。JavaScript代码在TypeScript中是有效的,但可能使编辑器、编译工具等报错——这跟设置有关。
  5. 小标题下给出了实例代码的路径,如“src\actions\grid align.js”,http://labs.phaser.io的首页即相当于“src\”;也可以用http://labs.phaser.io/edit.html?src=src\actions\grid align.js直接访问代码对应的在线编辑器界面(有时路径中的空格可能要用%20代替)。
  6. 官网是按字母排列类别的,有时为初学者学习、理解方便会调整顺序。

Actions/动作#

Phaser.Actions包含一组静态方法,可以对一组游戏对象进行批量处理,应用相同的动作。常常结合组的方法Group.getChildren()(取得group的所有对象形成一个数组)一起使用;这样一样,就可以尽量使用组(Group)来代替很消耗资源容器(Container,相当于Phaser2的Group)。

要处理的对象要包含要处理的属性、方法,否则无效。

请参考Phaser.Actions的文档

Grid Align/所有对象对齐网格放置#

src\actions\grid align.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// 生成group,包含4x20个对象
var group = this.add.group({
    key: 'diamonds', // 精灵单的key
    frame: [ 0, 1, 2, 3], // 依次使用的精灵单的帧号
    frameQuantity: 20 // 每帧重复使用次数
});
// group的所有对象逐一对齐网格(多余网格数量的对象不处理)
Phaser.Actions.GridAlign(group.getChildren(), {
    width: 10, // 网格列数
    height: 10, // 网格行数
    cellWidth: 32, // 单网格宽度
    cellHeight: 32, // 单网个高度
    x: 100, // 左上第一个网格中心点x值
    y: 100 // 左上第一个网格中心点y值
});

inc x layers/所有对象用IncX、IncY、IncXY递增坐标值,整体改变位置#

src\actions\inc x layers.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
function update ()
{
    // 所有对象移动
    Phaser.Actions.IncX(groupA.getChildren(), move); 
    Phaser.Actions.IncY(groupA.getChildren(), move);
    // 所有对象旋转
    Phaser.Actions.Rotate(groupA.getChildren(), -0.01);
    // 所有对象沿着圆形轨道移动
    Phaser.Actions.IncX(groupB.getChildren(), -Math.cos(move));
    Phaser.Actions.IncY(groupB.getChildren(), -Math.sin(move));
    // 所有对象旋转
    Phaser.Actions.Rotate(groupB.getChildren(), 0.01);

    move += 0.1;
}

Place On Circle/所有对象沿着圆圈放置/排列#

src\actions\place on circle.js

1
2
3
4
5
6
function create ()
{
    // 沿着圆圈放置,也可以是椭圆、方形、三角形、直线等
    var circle = new Phaser.Geom.Circle(400, 300, 260);
    Phaser.Actions.PlaceOnCircle(group.getChildren(), circle);
}

Random Circle/所有对象随机放置在圆内#

src\actions\random circle.js

1
2
3
4
5
6
function create ()
{
    // 对象随机放置在圆内,也可以是椭圆、方形、三角形、直线等
    var circle = new Phaser.Geom.Circle(400, 300, 130);
    Phaser.Actions.RandomCircle(group.getChildren(), circle);
}

Rotate Around Distance/所有对象(整体)围绕一定距离旋转#

src\actions\rotate around distance.js

1
2
3
4
function update ()
{
    Phaser.Actions.RotateAroundDistance(group.getChildren(), { x: 400, y: 300 }, 0.02, 200);
}

Rotate Around/所有对象(整体)围绕一点旋转#

src\actions\rotate around.js

1
2
3
4
function update ()
{
    Phaser.Actions.RotateAround(group.getChildren(), { x: 400, y: 300 }, 0.01);
}

Set Alpha/所有对象(整体)设置透明度#

src\actions\set alpha.js

1
2
3
4
function create ()
{
    Phaser.Actions.SetAlpha(group.getChildren(), 0, 1 / 50);
}

Set Xy/给所有对象设置坐标值#

src\actions\set xy.js

1
2
3
4
function create ()
{
    Phaser.Actions.SetXY(group.getChildren(), 400, 300);
}

Shift Position/所有对象依次换位#

src\actions\shift position.js

1
2
3
4
5
function update (time, delta)
{
    // 给出第一个(或最后一个)新位置,后面依次换位
    Phaser.Actions.ShiftPosition(group.getChildren(), x, y);
}

Spread/在两个属性值之间铺展所有对象#

src\actions\spread.js

1
2
3
4
5
function create ()
{
    //  在两个属性值('alpha', 0, 1)之间铺展所有对象
    Phaser.Actions.Spread(group.getChildren(), 'alpha', 0, 1);
}

wrap in rectangle/所有对象在一个方形内折返放置#

src\actions\wrap in rectangle.js

1
2
3
4
5
6
7
function update ()
{
    // 移动位置后,超出方框的一侧的对象会折返到对侧重新放置
    var children = group.getChildren();
    Phaser.Actions.IncXY(children, 1, 1);
    Phaser.Actions.WrapInRectangle(group.getChildren(), rect);
}

Animation#

Audio#

Bugs#

Cache#

Camera#

Components#

Demoscene#

Depth Sorting#

Display#

Dwitter#

Events#

Game Config/游戏配置#

使用配置对象进行配置,是Phaser3的风格。以下游戏配置,可参考GameConfig的文档

src\game config\banner colors.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
var config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    // 透明背景
    transparent: true,
    // 绘制纹理对象时,像素位置预先处理成整数
    roundPixels: true,
    scene: {
        preload: preload,
        create: create
    },
    // 设定浏览器开发工具中能看到的游戏标题
    title: 'Shock and Awesome',
    // 设定浏览器开发工具中能看到的游戏版本号
    version: '1.2b'
    //  设定浏览器开发工具中能看到的条幅颜色和(标题等)文字颜色
    // 使用banner: false关闭条幅
    banner: {
        text: '#ffffff',
        background: [
            '#fff200',
            '#38f0e8',
            '#00bff3',
            '#ec008c'
        ],
        // 隐藏Phaser版本等信息
        hidePhaser: true
    },
    // 设定浏览器开发工具中能看到的游戏链接
    url: 'http://xiiiGame.com'

};

var game = new Phaser.Game(config);

Custom Canvas/客户定制画布#

src\game config\custom canvas.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// 客户定制文档元素
var myCustomCanvas = document.createElement('canvas');
myCustomCanvas.id = 'myCustomCanvas';
myCustomCanvas.style = 'border: 8px solid red';
document.body.appendChild(myCustomCanvas);
// var myCustomContext = myCustomCanvas.getContext('2d');

var config = {
    type: Phaser.CANVAS,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    // 使用客户定制的文档元素,用来放置画布
    canvas: document.getElementById('myCustomCanvas'),
    scene: {
        preload: preload,
        create: create
    }
};

var game = new Phaser.Game(config);

Custom Webgl Canvas/客户定制WebGL画布#

src\game config\custom webgl canvas.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 客户定制文档元素
var myCustomCanvas = document.createElement('canvas');
myCustomCanvas.id = 'myCustomCanvas';
myCustomCanvas.style = 'border: 8px solid green';
document.body.appendChild(myCustomCanvas);

//  设置Phaser需要的WebGL语境变量
var contextCreationConfig = {
    alpha: false,
    depth: false,
    antialias: true,
    premultipliedAlpha: true,
    stencil: true,
    preserveDrawingBuffer: false,
    failIfMajorPerformanceCaveat: false,
    powerPreference: 'default'
};
// 也可以是'webgl2'
var myCustomContext = myCustomCanvas.getContext('webgl', contextCreationConfig);

var config = {
    type: Phaser.WEBGL,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    // 使用画布和语境
    canvas: myCustomCanvas,
    context: myCustomContext,
    scene: {
        preload: preload,
        create: create
    }
};

var game = new Phaser.Game(config);

Game Destroy With Multi Scenes/多场景游戏的销毁#

src\game config\game destroy with multi scenes.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
var Background = new Phaser.Class({
    // 继承场景
    Extends: Phaser.Scene,

    initialize: function Background () {
        Phaser.Scene.call(this, { key: 'background', active: true });
    },

    preload: function () {
        // ……
    },

    create: function ()
    {
        // ……
        this.input.on('pointerdown', function () {
            // 销毁游戏
            this.sys.game.destroy(true);
            // 重新生成游戏
            document.addEventListener('mousedown', function newGame () {
                game = new Phaser.Game(config);
                document.removeEventListener('mousedown', newGame);
            });
        }, this);
    },

    update: function (time, delta) {
        // ……
    }
});

var Demo = new Phaser.Class({
    Extends: Phaser.Scene,
    // …………
});

var config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    backgroundColor: '#000000',
    parent: 'phaser-example',
    scene: [ Background, Demo ]
};

var game = new Phaser.Game(config);

Game Rng/游戏的随机数问题#

src\game config\game rng.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var seed = 122548965231;
var config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    // 为随机数生成器设置种子
    seed: [ seed ],
    scene: {
        create: create
    }
};

var game = new Phaser.Game(config);

function create ()
{
    //  如果使用随机种子,那么每次重载所得随机数不变
    var shuffleTest = [ 'A', 'B', 'C', 'D', 'E', 'F', 'G' ];
    text.setText([
        'Between 0 and 50: ' + Phaser.Math.RND.between(0, 50),
        'Between 0 and 1: ' + Phaser.Math.RND.realInRange(0, 1),
        'Normal: ' + Phaser.Math.RND.normal(),
        'UUID: ' + Phaser.Math.RND.uuid(),
        'Angle: ' + Phaser.Math.RND.angle(),
        'Shuffle: ' + Phaser.Math.RND.shuffle(shuffleTest).join(' ')
    ]);
}

Multiple Game Instances/多个游戏实例#

src\game config\multiple game instances.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var config2 = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    scene: {
        preload: preload2,
        create: create2
    }
};

var config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    scene: {
        preload: preload,
        create: create
    }
};

// 两个游戏实例
var game1 = new Phaser.Game(config);
var game2 = new Phaser.Game(config2);

Game Objects/游戏对象#

各种具体游戏对象都是继承GameObject。请参考基础游戏对象/Phaser.GameObjects.GameObject的文档

Sprites/精灵#

Sprite是Phaser最常用的游戏对象之一。

Create From Config/通过配置对象生成精灵#

src\game objects\sprites\create from config.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
function create ()
{
    //  Implicit values
    var config1 = {
        key: 'bunny',
        x: 400,
        y: 300
    };

    //  Implicit values
    var config2 = {
        key: 'bunny',
        x: 400,
        y: 300,
        flipX: true,
        flipY: true
    };

    //  An array means 'pick one element at random'
    var config3 = {
        key: [ 'bunny', 'atari', 'logo' ],
        x: 400,
        y: 300
    };

    //  randInt means pick a random integer between the min and max values given
    var config4 = {
        key: 'atari',
        x: { randInt: [ 0, 800 ] },
        y: 300
    };

    //  randFloat means pick a random float between the min and max values given
    var config5 = {
        key: 'logo',
        x: 400,
        y: 300,
        alpha: { randFloat: [ 0.1, 1 ] }
    };

    //  If the property is a function it will invoke it and use the result as the value
    var config6 = {
        key: 'atari',
        x: 400,
        y: function () {
            return 100 + Math.random() * 500;
        }
    };

    //  An example using randFloat to set the scale of a Sprite
    var config7 = {
        key: 'logo',
        x: 400,
        y: 300,
        scale: { randFloat: [ 0.2, 2 ] }
    };

    //  An example using randFloat to set independent x and y scale values
    var config8 = {
        key: 'logo',
        x: 400,
        y: 300,
        scale: { x: { randFloat: [ 0.2, 2 ] }, y: { randFloat: [ 1.5, 3 ] } }
    };

    this.make.sprite(config8);
}

Bitmaptext/位图文本#

请参考静态文图文本的文档

Static/静态位图文本#

Bitmaptext Blend Mode/位图文本混色模式#

src\game objects\bitmaptext\static\bitmaptext blend mode.js

1
2
3
    var text = this.add.bitmapText(64, 200, 'ice', 'Zero Two', 32);
    // 与下层的图进行ADD混色
    text.setBlendMode(Phaser.BlendModes.ADD);
Bitmaptext-Atlas/用字体图集生成位图文本#

src\game objects\bitmaptext\static\bitmaptext-atlas.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
function preload() 
{
    // 加载图集
    this.load.atlas('fontatlas', 'assets/atlas/bitmap-fonts-debug.png', 'assets/atlas/bitmap-fonts.json');
    //  加载字体图集的XML数据
    this.load.xml('atariXML', 'assets/fonts/bitmap/atari-sunset.xml');
    // 也可以直接加载位图字体
    // this.load.bitmapFont('desyrel', 'assets/fonts/bitmap/desyrel.png', 'assets/fonts/bitmap/desyrel.xml');
}

function create() 
{
    // 生成位图字体和位图文本
    Phaser.GameObjects.BitmapText.ParseFromAtlas(this, 'font3', 'fontatlas', 'atari-sunset', 'atariXML');
    this.add.bitmapText(0, 300, 'font3', 'qwert');
}
以下存目#
  • Bitmaptext Rotation/旋转动画
  • Bitmaptext Scale/缩放动画
  • Bitmaptext-Canvas/字体缩放和比例缩放动画
  • Bitmaptext/位图字体
  • Change Font Size/更改字号
  • Change Font/更改字体
  • Get Text Size Multiline/获取多行文本的尺寸
  • Get Text Size Scaled/获取缩放后文本的尺寸
  • Get Text Size/获取文本尺寸
  • Large-Text/大文本
  • Multi Line Alignment/多行对齐
  • Multi Line/多行文本
  • Padding/边距
  • Text Origin/文本原点
  • Tinted Text/着色文本
  • Width And Height/宽和高

Dynamic/动态位图文本#

请参考动态位图文本的文档

Display Callback Rotation Effect/显示回调,旋转效果#

src\game objects\bitmaptext\dynamic\display callback rotation effect.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
function create()
{
    var text = this.add.dynamicBitmapText(60, 60, 'gothic', 'Hello\nWorld!', 128);
    text.setDisplayCallback(textCallback);
}

function textCallback (data)
{
    data.rotation = 1.570;
    return data;
}
存目#
  • Display Callback Index Effect/显示回调,索引效果
  • Display Callback Scale Effect/显示回调,缩放效果
  • Display Callback Wibble Effect/显示回调,抖动效果
  • Text Follow Path/文本跟随路径移动
  • Tinted Text/文本着色
  • Vertical Scroller/垂直滚动

Retro Font/复古字体#

Retro Text 1/复古文本#

src\game objects\bitmaptext\retro font\retro text 1.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
function create() 
{
    var config = {
        image: 'knighthawks',
        width: 31,
        height: 25,
        chars: Phaser.GameObjects.RetroFont.TEXT_SET6,
        charsPerRow: 10,
        spacing: { x: 1, y: 1 }
    };
    // 解析复古字体,加入缓存中
    this.cache.bitmapFont.add('knighthawks', Phaser.GameObjects.RetroFont.Parse(this, config));
    dynamic = this.add.bitmapText(0, 200, 'knighthawks', 'PHASER 3');
}
存目#
  • Retro Text Mega Scroll/复古文本滚动
  • Retro Text Scroll Callback/复古字体滚动回调
  • Retro Text Scroll/复古文本滚动
  • Scrolling Retro Text/复古文本滚动
  • Tinted Retro Text/复古文本着色

Blitter#

Container#

Dom Element#

Graphics#

Group#

Images#

Lights#

Mesh#

Particle Emitter#

Quad#

Render Texture#

Shaders#

Shapes#

Sprites#

Tests#

Text#

Tile Sprite#

Tilemap#

Games#

Geom#

input输入#

game object游戏对象#

src\input\game object\sprite example.js#

精灵,热点在上,热点离开

1
2
3
4
// 开启互动
sprite.setInteractive();
sprite.on('pointerover', function () {});
sprite.on('pointerout', function () {});

src\input\game object\on down event.js#

热点按下,热点抬起

1
2
3
sprite.setInteractive();
sprite.on('pointerdown', function () {});
sprite.on('pointerup', function () {});

src\input\dragging\drag distance threshold.js; drag time threshold.js#

拖拽距离阈值,拖拽时间阈值。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
sprite.setInteractive();
this.input.setDraggable(sprite);
//  热点移动一定距离(阈值,16点)后才被看做拖拽
this.input.dragDistanceThreshold = 16;
//  热点按钮500ms后才被看做拖拽
this.input.dragTimeThreshold = 500;
this.input.on('dragstart', function (pointer, gameObject) {});
// 给场景中所有可能的拖拽对象设置事件回调
this.input.on('drag', function (pointer, gameObject, dragX, dragY) {
    // 跟随拖拽点
    gameObject.x = dragX;
    gameObject.y = dragY;
});
this.input.on('dragend', function (pointer, gameObject) {});

也可以单独给一个对象设置拖拽事件回调函数:

1
2
3
4
sprite.on('drag', function (pointer:Phaser.Input.Pointer, dragX:number, dragY:number) {
    this.x = dragX;
    this.y = dragY;
}

Loader#

Paths#

Physics#

Plugins#

Pools#

Renderer#

Scalemanager#

Scenes#

外部场景/External Scene#

跨场景控制,比如场景用来做菜单、控制面板时。

改变场景顺序/Change Scene Order#

1
2
3
4
5
let config = {
    //...
    scene: [SceneA, SceneB, SceneC ] //预先激活的场景,最后载入的场景在最前景
};
let game = new Phaser.Game(config);

多场景控制器/Scene Controller#

用一个场景做控制面板,控制其他场景的启动、显示顺序、激活与否、可视与否;

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// this指当前场景,this.scene指当前场景的场景管理器:Phaser.Scenes. ScenePlugin
this.scene.launch('SceneA'); //启动场景
this.currentScene = this.scene.get('SceneA'); //取得场景
this.scene.setVisible(false, this.currentScene); //设置不可见
this.scene.setActive(false, this.currentScene);//设置不激活
this.scene.bringToTop(this.currentScene);//把场景移到顶层
this.scene.moveAbove('Controller', this.currentScene);//移动到指定场景上面
this.scene.moveDown(this.currentScene);//向下移动
this.scene.moveUp(this.currentScene);//向上移动
let idx = this.scene.getIndex(this.currentScene);//取得当前位置

Snapshot#

Spine#

Textures#

Time#

Timestep#

Transform#

Tweens#

Utils#