Phaser.js 3.x 开发h5小游戏——初始化游戏

2,474 阅读4分钟

上节回顾

在上一节搭建环境文章中,搭建好了游戏开发的本地环境,打开命令行执行 npm start 浏览器就会自动启动了。使用的开发工具是visual code。笔者文章就是记录的一个简单的 飞刀游戏开发过程,由于时间问题,仅仅实现了游戏的基本逻辑,和基本场景。后面有时间在优化

Phaser基本概念介绍

Phaser 游戏开发中,主要由场景(scene), 精灵(sprite)去构成,物理世界(physics),精灵可以是图片精灵,文本精灵,瓦片地图等等。场景就相当于web开发中的一个完整的页面,精灵就类似于页面的各个dom元素。物理世界就是计算机模拟现实世界的一些物理现象(本次游戏中没有用到物理世界这个概念),如加速度,重力,摩擦力等等。

初始化游戏——Game配置

游戏的初始化代码是写在入口文件 game.js 中,所有代码的开发、游戏的资源存放都是在如图所示的src文夹中进行的

。入口game.js首先要引入Phaser 基类Game,另外还需要Scale 类,Scale主要是做一下场景尺寸的适配。首先实例化Game 类,参数是是一个 Ojbect对象。代码如下:

import { Game, Scale } from 'phaser';

window.game = new Game({
    type: Phaser.AUTO,
    scale: {
        width: 720,
        height: 1280,
        autoCenter: Scale.CENTER_BOTH,
        mode: Scale.FIT,
    },
    parent: "container"
});

实例化一个Game类,并赋值给window 对象中的 game属性,方便在其他场景中访问这个实例。看一下传入的参数。type属性定义Phaser的渲染方式,有三个值:

  • Phaser.AUTO 根据浏览器自动选择渲染方式,如果支持webgl 就使用webgl
  • Phaser.CANVAS 使用canvas渲染
  • Phaser.WEBGL 使用webgl渲染

scale属性定义了Phaser的画布宽高,缩放。它的值也是一个对象,对象的width,height属性 定义画布宽高,autoCenter 属性定义了 canvas 元素相对于其父元素对其方式,有如下值:

  • Scale.NO_CENTER 水平方向以及垂直方向都不局中
  • Scale.CENTER_BOTH 水平方向以及垂直方向都局中
  • Scale.CENTER_HORIZONTALLY 水平方向局中
  • Scale.CENTER_VERTICALLY 垂直方向居中

mode属性定义缩放模式,有如下值:

  • Scale.NONE 不缩放,canvas保持width,height定义的宽高。
  • Scale.WIDTH_CONTROLS_HEIGHT 宽度不变,高度自适应,也就是高度会根据宽度进行缩放
  • Scale.HEIGHT_CONTROLS_WIDTH 高度不变,宽度自适应,也就是宽度会根据高度进行缩放
  • Scale.FIT 宽高根据ratio等比自动缩放,不同屏幕下,可能会出现黑边
  • Scale.RESIZE 充满整个父元素,图像会拉伸变形
  • Scale.ENVELOP 根据比例,canvas宽或高充满父元素,因此图像的有一个边可能会超出父元素 parent属性定义canvas的父元素,传入父元素id,如果没有指定,默认是body元素。

到这里其实Phaser初始化已经完成了,执行 npm start 执行的,浏览器控制台

出现这句话就表示初始化成功了,由于现在没有场景和精灵,因此只会显示720*1280 黑漆漆的一片

初始化游戏——场景(scene)

Phaser中场景也是一个对象或者一个类,一个游戏必然有多个场景, Phaser 3.0 以后都是通过实例Game类并传入 scene参数,它传入的是个数组,数组的每个元素都是一个场景类。每个场景类都有如下几个方法(依次执行):

  • init 场景初始化之后的回调,可以用来执行游戏初始化的数据
  • preload 场景预加载,可以用来加载各个资源加载
  • create 场景创建,可以用来创建各种精灵,将精灵添加到场景中以及注册事件
  • update 执行帧,游戏的每一帧都在调用。猜测应该是对requestAnimationFrame封装。

初始化游戏——创建一个场景

在src目录下的scenes 目录创建loadScene.js 作为加载场景,显示游戏加载的进度条。代码如下:

import { Scene } from 'phaser';
export class LoadScene extends Scene {
    constructor() {
        super("LoadScene")
    }
    init() {}
    preload() {}
    update() {}
}

代码中定义了一个loadScene类继承自场景(Scene)类,以及定义了三个方法。定义好场景之后,我要将场景注册给Game类,这样Phaser 才知道有哪些场景,修改game.js代码:

import { Game, Scale } from 'phaser';
import { LoadScene } from './scenes/loadScene';
window.game = new Game({
    type: Phaser.AUTO,
    scale: {
        width: 720,
        height: 1280,
        autoCenter: Scale.CENTER_BOTH,
        mode: Scale.ENVELOP,
    },
    parent: "container",
    scene: [LoadScene],
});

引入创建的loadScene,给game实例传入scene参数,它的值是一个数组,将数组的第一个元素赋值为LoadScene。如果传入多个场景的话,Phaser会默认加载第一个。接着就可以进行具体业务逻辑的实现了。

到此,游戏初始化就结束了,下一节开始游戏加载场景的具体实现。