【问题标题】:How to create a responsive game for any screen size with Phaser 3?如何使用Phaser 3创建任何屏幕大小的响应游戏?
【发布时间】:2021-05-17 08:18:02
【问题描述】:

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

这个例子是用 Construct 2 制作的,顺便说一句,这个效果很简单。

有谁知道使用 Phaser 3 实现这一目标的最佳方法是什么?

【问题讨论】:

    标签: javascript game-engine phaser-framework


    【解决方案1】:

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

    关键是使用父场景来控制所有其他子场景,该场景将测量与设备的屏幕尺寸相同。当屏幕尺寸发生变化时,它也会调整子场景的大小,但始终保持纵横比。

    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,
        width: SIZE_WIDTH_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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-31
      • 2020-06-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多