javascript - 根据内容更改模态高度

标签 javascript phaser-framework

我正在尝试为我的 Phaser 3 项目创建模态场景。这是我当前在 modal.js 中的代码:

class modal extends Phaser.Scene {

    // constructor
    constructor() {
        super("Modal");
    }

    preload() {
        this.load.image("header", "Assets/popUpTop.png");
        this.load.image("x", "Assets/x.png");
    }

    init(data) {
        this.modalName = data.modalName;
    }

    create() {
        // create a white rounded rectangle as modal background
        var bgGrafics = this.make.graphics();
        bgGrafics.fillStyle(0xffffff, 1);
        bgGrafics.fillRoundedRect(0, 0, gameConfig.width / 3, gameConfig.height / 1.7, 51);
        bgGrafics.generateTexture("modalBg", gameConfig.width / 3, gameConfig.height / 1.7);
        this.modalBg = this.add.sprite(gameConfig.width / 2, gameConfig.height / 2, "modalBg");
        
        this.modalBg.setScale(1.05);
        
        this.headerBg = this.add.image(0, 0, "header");
        this.headerBg.setScale((this.modalBg.width * 1.05 / this.headerBg.width), (1 + (0.05 * this.modalBg.height / this.headerBg.height)));
        
        this.closeBtn = new RoundedButton(this, 0, 0, 43, "x", 1.3, () => {this.close()}); // RoundedButton is a custom class that extends Phaser.GameObjects.Container
        this.add.existing(this.closeBtn);

        // help modal
        if(this.modalName === 'help') {
        // add content of help modal 
        }
        // profile modal
        else if(this.modalName === 'profile') {
        // add content of profile modal 
        }
        // confirm spin modal
        else if(this.modalName === 'spin') {
        // add content of confirm modal 
        }
        
        Phaser.Display.Align.In.TopRight(this.closeBtn, this.modalBg);
        Phaser.Display.Align.In.TopCenter( this.headerBg, this.modalBg );
    }

    close() {
        this.scene.stop('Modal');
        this.scene.run('PlayGame');
    }
}

如您在我的代码中所见,我尝试根据 modelName 向模态添加不同的内容,但我找不到根据内容更改模态高度的方法。 我该怎么做?

最佳答案

一个解决方案是,使用 gameObject Phaser.GameObjects.TextStyle 中的函数 setWordWrapWidth ( link to the documentation ) 来限制 width,然后设置 text 游戏对象的内容,最后获取并使用 text 游戏对象的 height 属性。

有了 text 游戏对象的 widthheight (从 Phaser 计算),您可以简单地渲染graphics 对象,具有正确的大小(我还会添加一些填充)。如果您想要/需要生成纹理,则每次都必须将其删除,因为大小可能已更改。

这是一个简短的演示:
(我正在生成纹理,因为它在原始代码中,但我会简单地使用 graphics 游戏对象。)

document.body.style = 'margin:0;';

const TEXT_SHORT = 'Hello World.'.repeat(8);
const TEXT_LONG = TEXT_SHORT.repeat(2);

class Main extends Phaser.Scene {

    constructor() {
        super("Main");
    }

    create() {
        let buttonShortText = this.add.rectangle(10, 10, 80, 40, 0xcdcdcd)
            .setOrigin(0)
            .setInteractive()
            .on('pointerdown', () => this.scene.start('Modal', {
                name: 'SHORT',
                text: TEXT_SHORT,
                padding: 10,
                maxWidth: 200
            }));

        // x,y Position are not relevant since they will be change on align
        let helperLabel = this.add.text(0, 0, 'SHORT').setColor('#000000');

        Phaser.Display.Align.In.Center(helperLabel, buttonShortText);

        let buttonLongText = this.add.rectangle(100, 10, 80, 40, 0xcdcdcd)
            .setOrigin(0)
            .setInteractive()
            .on('pointerdown', () => this.scene.start('Modal', {
                name: 'SHORT',
                text: TEXT_LONG,
                padding: 20,
                maxWidth: 400
            }));

        // x,y Position are not relevant since they will be change on align
        let helperLabel2 = this.add.text(0, 0, 'LONG').setColor('#000000');

        Phaser.Display.Align.In.Center(helperLabel2, buttonLongText);
    }
}

class Modal extends Phaser.Scene {

    constructor() {
        super("Modal");
    }

    init(data) {
        this._name = data.name;
        this._text = data.text + '\n\nClick to Close';
        this._maxWidth = data.maxWidth;
        this._padding = data.padding;
    }

    create() {
        this.add.rectangle(0, 0, config.width, config.height, 0xcdcdcd, .5)
            .setOrigin(0)
            .setInteractive()
            .on('pointerdown', () => this.scene.start('Main'));

        // x,y Position are not relevant since they will be change on align
        this.content = this.add.text(0, 0, this._text).setColor('#000000');
        this.content.setWordWrapWidth(this._maxWidth - (2 * this._padding));
        this.content.setDepth(10);

        let bgHeight = this.content.height + (2 * this._padding);

        let graphics = this.make.graphics({ add: false });

        graphics.fillStyle(0xffffff);
        graphics.fillRect(0, 0, this._maxWidth, bgHeight, 0xffffff);

        // Remove the texture is it was generated and has a different size.
        if (this.textures.exists('bgModal')) {
            this.textures.remove('bgModal');
        }

        graphics.generateTexture('bgModal', this._maxWidth, bgHeight);

        this.bgImage = this.add.image(config.width / 2, config.height / 2, 'bgModal');

        // Center Text onto the Background
        Phaser.Display.Align.In.Center(this.content, this.bgImage);
    }
}

var config = {
    type: Phaser.CANVAS,
    width: 536,
    height: 183,
    scene: [Main, Modal]
};

new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>

关于javascript - 根据内容更改模态高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74171052/

相关文章:

javascript - 向 Phaser 3 游戏添加场景不起作用

javascript - node.js 实现背后的基本思想?

javascript - addEventListener 与 getElementsByClassName

javascript - jQuery 微调器使用问题

javascript - jQuery版本升级-jQuery库版本之间的差异

javascript - 将电子表格中的每个值返回到 Web 应用程序表

javascript - 如何避免使用 Cordova 的 Phaser 游戏内存占用过高?

phaser-framework - Phaser P2 body.collideWorldBounds 停止 body 碰撞

javascript - 使用 tileset 将 map 更改为另一个 map

phaser-framework - Phaser3 场景转换