Установить соотношение масштаба игры

Я пытаюсь подогнать игру под экран, но не могу масштабировать саму сцену. С такими библиотеками, как EaselJS от CreateJS, я могу просто stage.scaleX = stage.scaleY = r.

В Phaser я хочу масштабировать не только игру, но и вместе HTML div (для пользовательского интерфейса), который находится вне Phaser. Как видите, нарисованный прямоугольник не масштабируется в соответствии с текущим размером экрана, независимо от того, какие свойства я изменяю (game.scale.scaleMode, game.scale.displayScale и т. д.). Могу ли я что-нибудь сделать?

const ProjectSettings = {
    backgroundColor: 0x333333,
    resolution: [100, 100],
};

const SceneContainers = {
    sceneContent: null,
    sceneCanvas: null,
    phaserGame: null,
    sceneUIDiv: null,

    init() {
        SceneContainers.sceneContent = document.getElementById('content');
        SceneContainers.phaserGame = new Phaser.Game({
            width: ProjectSettings.resolution[0],
            height: ProjectSettings.resolution[1],
            type: Phaser.AUTO,
            parent: SceneContainers.sceneContent,
            backgroundColor: ProjectSettings.backgroundColor,
            scene: [Preloader],
        });
        SceneContainers.sceneCanvas = SceneContainers.phaserGame.canvas;
        SceneContainers.sceneCanvas.classList.add('scene-canvas');

        SceneContainers.sceneUIDiv = document.createElement('div');
        SceneContainers.sceneUIDiv.id = 'scene-ui';
        SceneContainers.sceneContent.appendChild(SceneContainers.sceneUIDiv);
    },
};

const SceneScaler = {
    init() {
        SceneContainers.phaserGame.scale.scaleMode = Phaser.Scale.ScaleModes.RESIZE;
        SceneScaler.fitToScreen();
        window.addEventListener('resize', e => {
            SceneScaler.fitToScreen();
        });
    },

    fitToScreen() {
        const [contentW, contentH] = ProjectSettings.resolution;
        const [windowW, windowH] = [innerWidth, innerHeight];
        const ratio = contentW / contentH;
        const windowRatio = windowW / windowH;
        let scale = windowW / contentW;
        if (windowRatio > ratio) {
            scale = windowH / contentH;
        }

        //SceneContainers.sceneCanvas.width = contentW * scale;
        //SceneContainers.sceneCanvas.height = contentH * scale;
        SceneContainers.phaserGame.scale.resize(contentW * scale, contentH * scale);
        SceneContainers.sceneUIDiv.style.transform = `scale(${scale})`;
        SceneContainers.sceneContent.style.width = `${contentW * scale}px`;
        SceneContainers.sceneContent.style.height = `${contentH * scale}px`;
        SceneContainers.sceneUIDiv.style.width = `${contentW}px`;
        SceneContainers.sceneUIDiv.style.height = `${contentH}px`;
        SceneContainers.sceneContent.style.left =
        SceneContainers.sceneCanvas.style.left =
        SceneContainers.sceneUIDiv.style.left = `${windowW / 2 - (contentW * scale) / 2}px`;
        SceneContainers.sceneContent.style.top =
        SceneContainers.sceneCanvas.style.top =
        SceneContainers.sceneUIDiv.style.top = `${windowH / 2 - (contentH * scale) / 2}px`;
        //SceneContainers.phaserGame.scale.displayScale = new Phaser.Math.Vector2(scale, scale);
    },
};

class Scene extends Phaser.Scene {
    constructor(id) {
        super(id);
    }

    init() {
        this.events.on('shutdown', () => {
            SceneContainers.sceneUIDiv.innerHTML = '';
        });
    }
}

class Preloader extends Scene {
    constructor() {
        super('preloader');
    }

    preload() {
    }

    create() {
        this.add.rectangle(50, 50, 50, 50, 0xff6666);
    }
}

class EntryPoint {
    constructor() {
        this.init();
    }

    init() {
        SceneContainers.init();
        SceneScaler.init();
    }
}

new EntryPoint;
html, body {
    padding: 0;
    margin: 0;
    width: 100%;
    height: 100%;
}

html, body {
    background: #333333;
}

#content {
    position: absolute;
    display: inline-block;
}

.scene-canvas {
    position: absolute;
}

#scene-ui {
    display: inline-block;
    position: absolute;
    transform-origin: left top;
}
<script src = "https://github.com/photonstorm/phaser/releases/download/v3.55.2/phaser.min.js"></script>
<div id = "content"></div>

Кроме того, по какой-то причине мой фрагмент дает undefined для canvas.classList, поэтому я признателен, если кто-то может это исправить. Эта ошибка classList не происходит с моим проектом.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
15
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы ищете только автоматическое масштабирование, вы можете использовать конфиг, параметр scale.mode и установить его в Phaser.Scale.FIT, тогда все должно масштабироваться.

Вот очень упрощенная демонстрация:
Если вы измените размер окна (когда вы откроете снипплет в полном размере и измените высоту), вы должны увидеть «масштабирование».

var Preloader = {
    create() {
        this.add.rectangle(50, 50, 50, 50, 0xff6666);
    }
};

new Phaser.Game({
    width:300,
    height:300,
    scale: {
        mode: Phaser.Scale.FIT,
    },
    type: Phaser.AUTO,
    scene: [Preloader],
});
<script src = "//cdn.jsdelivr.net/npm/[email protected]/dist/phaser.min.js"></script>

Другие вопросы по теме