Phaser.js 3.x 开发h5小游戏——加载场景实现

3,893 阅读4分钟

上节回顾

上一节记录了Phaser开发游戏的初始化流程,以及一些常用的配置参数,并且创建了加载场景,这一节将描述一下如何加载场景资源以及如何实现一个加载进度条。

加载场景——加载资源

在上一节游戏初始化,新建了一个LoadScene的场景类,此场景主要用来加载游戏的资源文件,我的游戏中主要是图片资源。假如是复杂的游戏,里面会有很多资源,比如音频资源,图集动画,字体文件等等。Phaser 提供了很多加载资源的函数。如果是图片资源的话呢,调用场景类的load.image函数就行了。所有的资源加载可以放在场景类的preload方法体里边。先看一下LoadScene 的代码结构:

import { Scene } from 'phaser';
import { preloadSceneAssets } from '../config/assetsConfig'
export class LoadScene extends Scene {
    constructor() {
        super("LoadScene")
    }
    //初始化状态
    init() {
        
    }
    //绘制加载进度条
    drawProgress() {
        
    }
    //
    preload() {
        
    }
    //帧函数
    update() {
        
    }
}

为了便于资源的管理,单独创建了一个assetConfig.js,代码如下:

export const preloadSceneAssets = {
    'bk-sheet0': require('../assets/bk-sheet0.png'),
    'download': require('../assets/download.png'),
    "knife_rotate-sheet0": require('../assets/knife_rotate-sheet0.png'),
    "sprite4-sheet0": require('../assets/sprite4-sheet0.png'),
    "buttonfullscreen-sheet0": require('../assets/buttonfullscreen-sheet0.png'),
    "buttonfullscreen-sheet1": require('../assets/buttonfullscreen-sheet1.png'),
    "sprite6-sheet0": require('../assets/sprite6-sheet0.png'),
    "sprite7-sheet0": require('../assets/sprite7-sheet0.png'),
    "sprite8-sheet0": require('../assets/sprite8-sheet0.png'),
    "sprite9-sheet0": require('../assets/sprite9-sheet0.png'),
    "volum-sheet0": require('../assets/volum-sheet0.png'),
    "volum-sheet1": require('../assets/volum-sheet1.png')
}

文件用来配置资源路径,并且在LoadScene场景中引入,接着在preload方法中实现资源加载,代码如下:

preload(){
    this.load.image('bk-sheet0', preloadSceneAssets['bk-sheet0'])
    this.load.image('download', preloadSceneAssets['download'])
    this.load.image('sprite4-sheet0',preloadSceneAssets['sprite4-sheet0'])
    this.load.image('knife_rotate-sheet0',preloadSceneAssets['knife_rotate-sheet0'])
    this.load.image('buttonfullscreen-sheet0',preloadSceneAssets['buttonfullscreen-sheet0'])
    this.load.image('buttonfullscreen-sheet1',preloadSceneAssets['buttonfullscreen-sheet1'])
    this.load.image('sprite6-sheet0',preloadSceneAssets['sprite6-sheet0'])
    this.load.image('sprite7-sheet0',preloadSceneAssets['sprite7-sheet0'])
    this.load.image('sprite8-sheet0',preloadSceneAssets['sprite8-sheet0'])
    this.load.image('sprite9-sheet0',preloadSceneAssets['sprite9-sheet0'])
    this.load.image('volum-sheet0', preloadSceneAssets['volum-sheet0'])
    this.load.image('volum-sheet1', preloadSceneAssets['volum-sheet1'])
}

this.load.image 有两个参数,第一个参数是资源的keyPhaser在绘制精灵的时候,就需要指定key,一次区别绘制的是什么精灵;第二个参数是资源的路径。

加载场景——监听加载进度

Phaser提供了资源加载的监听函数this.load.on, 有两个参数,第一个参数是字符串(函数名),第二个参数是回调函数,监听加载进度的代码如下:

this.load.on('progress', value => {
    //value 是个0-1的浮点数,也就是加载的百分比
});

加载场景——进度条的实现

知道加载进度条之后,我们就能实现进度条的绘制了。要实现进度条,需要初始化这些数据:

  • 进度条对象 progressBar
  • 进度条的总长度 progressWidth
  • 当前加载的长度 nowWidth
  • 进度条变化增量 loadingSpeed
  • 进度条长度 loadingWidth

数据的初始化在 init方法中完成:

init() {
    this.progressWidth = parseInt(game.config.width * 0.8);
    this.nowWidth = 0;
    this.loadingSpeed = 6;
    this.loadingWidth = 0;
    this.progressBar = this.add.graphics();
}

this.add.graphicsPhaser中的图形绘制方法,可以绘制矩形,三角形,圆形等等。绘制一个矩形的进度条,调用的是 this.add.graphics执行之后返回的.fillRect方法,它有四个参数:x,y,width,height,分别代表x坐标,y坐标,宽度,高度。状态的初始化完成之后,接着就是绘制进度条的实现,修改LoadSecen类的drawprogressBarBar函数如下

drawprogressBarBar() {
    //清除上一次绘制的图像;
    this.progressBar.clear() 
    //设置图像样式(颜色值,透明度)
    this.progressBar.fillStyle(0xffffff, 1);
    //绘制矩形进度条
    this.progressBar.fillRect(game.config.width * 0.2 / 2, game.config.height / 2 - 5, this.loadingWidth, 10);
}

最后,就是如何实现让进度条宽度从0%到100%的变化了。原理很简单,实现一个递增的值,将该值作为进度条宽度,如果递增的总和不大于当前已经加载的进度值,就继续递增。获取当前加载的进度值,就是监听加载的回调中进行赋值,修改 this.load.on('progress', value => { });

this.load.on('progressBar', value => {
    this.nowWidth = this.progressBarWidth * value
});

进度条的不停变化,可以再场景类的 帧函数update中进行实现,代码如下:

update() {
    if (this.loadingWidth < this.nowWidth) {
        this.loadingWidth += this.loadingSpeed;
        this.drawprogressBarBar()
        return;
    }
    this.loadingSpeed = 0;
    this.progressBar.destroy()
    this.scene.stop()
}

帧函数回循化执行他里面的方法,直到场景渲染停止。到此,加载场景的实现就已经完成了,运行项目,就能看到进度条的加载动画了。下一节将是游戏的首页的布局的实现。最后,把整个代码贴一遍:

  • LoadScene代码
import { Scene } from 'phaser';
import { preloadSceneAssets } from '../config/assetsConfig'
export class LoadScene extends Scene {
    constructor() {
        super("LoadScene")
    }
    init() {
        this.progressBarWidth = parseInt(game.config.width * 0.8);
        this.nowWidth = 0;
        this.loadingSpeed = 6;
        this.loadingWidth = 0;
        this.progressBar = this.add.graphics();
    }

    drawprogressBarBar() {
        this.progressBar.clear();
        this.progressBar.fillStyle(0xffffff, 1);
        this.progressBar.fillRect(game.config.width * 0.2 / 2, game.config.height / 2 - 5, this.loadingWidth, 10);
    }
    preload() {
        this.load.image('bk-sheet0', preloadSceneAssets['bk-sheet0'])
        this.load.image('download', preloadSceneAssets['download'])
        this.load.image('sprite4-sheet0', preloadSceneAssets['sprite4-sheet0'])
        this.load.image('knife_rotate-sheet0', preloadSceneAssets['knife_rotate-sheet0'])
        this.load.image('buttonfullscreen-sheet0', preloadSceneAssets['buttonfullscreen-sheet0'])
        this.load.image('buttonfullscreen-sheet1', preloadSceneAssets['buttonfullscreen-sheet1'])
        this.load.image('sprite6-sheet0', preloadSceneAssets['sprite6-sheet0'])
        this.load.image('sprite7-sheet0', preloadSceneAssets['sprite7-sheet0'])
        this.load.image('sprite8-sheet0', preloadSceneAssets['sprite8-sheet0'])
        this.load.image('sprite9-sheet0', preloadSceneAssets['sprite9-sheet0'])
        this.load.image('volum-sheet0', preloadSceneAssets['volum-sheet0'])
        this.load.image('volum-sheet1', preloadSceneAssets['volum-sheet1'])
        this.load.on('progressBar', value => {
            this.nowWidth = this.progressBarWidth * value
        });

    }
    update() {
        if (this.loadingWidth < this.nowWidth) {
            this.loadingWidth += this.loadingSpeed;
            this.drawprogressBarBar()
            return;
        }
        this.loadingSpeed = 0;
        this.progressBar.destroy()
        this.scene.stop()
        this.scene.start('StartScene')
    }
}

游戏图片资源,提取码: wyi9