如何用Phaser 3创建任何屏幕大小的响应性游戏?

我一直在寻找一种解决方案,使我的游戏能够完全响应使用Phaser 3的任何屏幕分辨率,例如:

此示例是使用构造2创建的,顺便说一句,实现此效果非常简单。

有人知道使用Phaser 3实现此目的的最佳方法是什么吗?


解决方案

通过研究,我找到了问题的解决方案:

关键是使用父场景来控制所有其他子场景,该场景将与设备的屏幕大小相同。它还会在屏幕大小更改时调整子场景的大小,但始终保持纵横比不变。

HandlerScene.js

export default class Handler extends Phaser.Scene {

// Vars
sceneRunning = null

constructor() {
    super('handler')
}

create() {
    this.cameras.main.setBackgroundColor('#FFF')
    this.launchScene('preload')
}

launchScene(scene, data) {
    this.scene.launch(scene, data)
    this.gameScene = this.scene.get(scene)
}

updateResize(scene) {
    scene.scale.on('resize', this.resize, scene)

    const scaleWidth = scene.scale.gameSize.width
    const scaleHeight = scene.scale.gameSize.height

    scene.parent = new Phaser.Structs.Size(scaleWidth, scaleHeight)
    scene.sizer = new Phaser.Structs.Size(scene.width, scene.height, Phaser.Structs.Size.FIT, scene.parent)

    scene.parent.setSize(scaleWidth, scaleHeight)
    scene.sizer.setSize(scaleWidth, scaleHeight)

    this.updateCamera(scene)
}

resize(gameSize) {
    // 'this' means to the current scene that is running
    if (!this.sceneStopped) {
        const width = gameSize.width
        const height = gameSize.height

        this.parent.setSize(width, height)
        this.sizer.setSize(width, height)

        const camera = this.cameras.main
        const scaleX = this.sizer.width / this.game.screenBaseSize.width
        const scaleY = this.sizer.height / this.game.screenBaseSize.height

        camera.setZoom(Math.max(scaleX, scaleY))
        camera.centerOn(this.game.screenBaseSize.width / 2, this.game.screenBaseSize.height / 2)
    }
}

updateCamera(scene) {
    const camera = scene.cameras.main
    const scaleX = scene.sizer.width / this.game.screenBaseSize.width
    const scaleY = scene.sizer.height / this.game.screenBaseSize.height

    camera.setZoom(Math.max(scaleX, scaleY))
    camera.centerOn(this.game.screenBaseSize.width / 2, this.game.screenBaseSize.height / 2)
}

}

通过这种方式,我们可以在父场景中并行启动其他场景。

PreloadScene.js

export default class Preload extends Phaser.Scene {

handlerScene = null
sceneStopped = false

constructor() {
    super({ key: 'preload' })
}

preload() {
    // Images
    this.load.image('logo', 'assets/images/logo.png')   

    this.width = this.game.screenBaseSize.width
    this.height = this.game.screenBaseSize.height

    this.handlerScene = this.scene.get('handler')
    this.handlerScene.sceneRunning = 'preload'
    this.sceneStopped = false

    ...
}

create() {
    const { width, height } = this
    // CONFIG SCENE         
    this.handlerScene.updateResize(this)
    // CONFIG SCENE  

    // GAME OBJECTS  
    this.add.image(width / 2, height / 2, 'logo').setOrigin(.5)
    // GAME OBJECTS
}

}

在子场景中,必须从每个场景的Create函数调用父场景的updateReize函数。

ConfigGame.js

import Handler from './scenes/handler.js'
import Preload from './scenes/preload.js'

// Aspect Ratio 16:9 - Portrait
const MAX_SIZE_WIDTH_SCREEN = 1920
const MAX_SIZE_HEIGHT_SCREEN = 1080
const MIN_SIZE_WIDTH_SCREEN = 270
const MIN_SIZE_HEIGHT_SCREEN = 480
const SIZE_WIDTH_SCREEN = 540
const SIZE_HEIGHT_SCREEN = 960

const config = {
    type: Phaser.AUTO,
    scale: {
        mode: Phaser.Scale.RESIZE,
        parent: 'game',
        width: SIZE_WIDTH_SCREEN,
        height: SIZE_HEIGHT_SCREEN,
        min: {
            width: MIN_SIZE_WIDTH_SCREEN,
            height: MIN_SIZE_HEIGHT_SCREEN
        },
        max: {
            width: MAX_SIZE_WIDTH_SCREEN,
            height: MAX_SIZE_HEIGHT_SCREEN
        }
    },
    dom: {
        createContainer: true
    },
    scene: [Handler, Preload]

}

const game = new Phaser.Game(config)

// Global

game.screenBaseSize = {
    maxWidth: MAX_SIZE_WIDTH_SCREEN,
    maxHeight: MAX_SIZE_HEIGHT_SCREEN,
    minWidth: MIN_SIZE_WIDTH_SCREEN,
    minHeight: MIN_SIZE_HEIGHT_SCREEN,
    width: SIZE_WIDTH_SCREEN,
    height: SIZE_HEIGHT_SCREEN
}

模式:Phaser.Scale.RESIZE非常重要,也是屏幕大小的最大值和最小值。

Mi Complete Solution在此:

https://github.com/shimozurdo/mobile-game-base-phaser3

探索:

https://labs.phaser.io/edit.html?src=src/scalemanager/mobile%20game%20example.js

相关文章