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

How to create a responsive game for any screen size with Phaser 3?(如何用Phaser 3创建任何屏幕大小的响应性游戏?)
本文介绍了如何用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

这篇关于如何用Phaser 3创建任何屏幕大小的响应性游戏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

本文给大家介绍Javascript js中实现和PHP一样的时间戳格式化函数的方法,具有一定的参考借鉴价值,需要的朋友可以参考下,我们知道在php中有一个date()函数,可以方便的把时间戳格式化为时间字符串。可是在js中,我们要想实现这种效果,要写好
需求是模板字符串中不允许出现script 标签、不允许有javascript: 和 .js 文件引用,主要方法如下: clearScriptTag (str) { const reg = /script[^]*([\S\s]*?)\/script/gim; // 清除标签内 相关 xss 安全代码 const reg1 = /javascript:/gim; const reg2 = / *.js/gim; if (reg.test(str)) { str
javascript中Replace全部替换字符用法实例代码,替换1次和多次,主要是正则表达式 var r= "1\n2\n3\n";//将字母\n替换成分号alert(r.replace("\n",";"));//结果:1;2\n3\n 只替换了第一个var r= "1\n2\n3\n";//将字母\n替换成分号alert(r.replace(/\n/g, ";"));//结果:1;2;3; replac
js输出当前日期和时间的实例代码,具体实例代码如下,有兴趣的朋友可以尝试运行下。 !doctype htmlhtml lang="en" head meta charset="UTF-8" title获取当前时间/title /head body script type="text/javascript" /** *获取当前时间 *format=1精确到天 *format=2精确到秒 */ function
p5.js WebGL 3d graphics covered by 2d background when rotated(P5.js旋转时被2D背景覆盖的WebGL 3D图形)
Static vector field with classic arrows at every point on p5.js(P5.js上每个点都有经典箭头的静态向量场)