微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 Phaser 3 为任何屏幕尺寸创建响应式游戏?

如何解决如何使用 Phaser 3 为任何屏幕尺寸创建响应式游戏?

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

Resize screen

这个例子是用 Construct 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函数中调用父场景的updateResize函数。

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,height: SIZE_HEIGHT_SCREEN
}

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

小米完整的解决方案在这里:

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

说明:

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。