Я добавил в сцену два текстовых объекта. Но для последнего я не смог установить прозрачный цвет фона.
Может кто-нибудь мне помочь?
Вот скриншот.
Я хочу, чтобы текстовые объекты имели прозрачный фон.
Я попытался установить backgroundColor
например:
this.scene.add.text(0, 0, "hoge", {
backgroundColor: "rgb(255 255 255 / 0.5)",
});
но это не работает.
Этот текстовый объект выглядит хорошо. Он имеет прозрачный фон.
this.text = (() => {
const text = this.scene.add.text(0, 0, "x: -, y: -", {
padding: {
y: 50 / this.scene.cameras.main.zoom,
},
align: "center",
fixedWidth: containerWidth,
fixedHeight: containerHeight,
fontSize: `${100 / this.scene.cameras.main.zoom}px`,
lineSpacing: 0,
});
return text;
})();
Этот текст выглядит плохо. Он имеет черный фон.
this.text = (() => {
const text = this.scene.add.text(0, 0, [
"a10a",
"VIT: 0",
], {
fixedWidth: containerWidth,
fixedHeight: containerHeight,
fontSize: `${100 / this.scene.cameras.main.zoom}px`,
});
return text;
})();
Я создал минимальный воспроизводимый пример.
Я обнаружил, что опция type: CANVAS
в new PhaserGame
и this.load.image
что-то делает.
Я мог бы сделать фон текста прозрачным, когда закомментировал эти строки.
Но я не хочу этого делать, потому что мне нужно загружать изображения, и если я изменю параметр type: CANVAS
, возникнут другие ошибки.
+ app/
+ _components/
| + game/
| + scenes/
| | + main-scene/
| | + index.ts
| |
| + index.tsx
|
+ globals.css
+ layout.tsx
+ page.tsx
"use client";
import { CANVAS, Game as PhaserGame, Scale } from "phaser";
import { useEffect, useRef } from "react";
import { MainScene } from "./scenes/main-scene";
export function Game() {
const game = useRef<Phaser.Game | null>(null);
useEffect(() => {
if (game.current === null) {
game.current = new PhaserGame({
parent: "game-container",
// If AUTO, it doesn't work on smartphone browser
type: CANVAS,
width: 100,
height: 100,
scale: {
mode: Scale.ScaleModes.FIT,
},
backgroundColor: "#028af8",
scene: [
MainScene,
],
});
}
return () => {
if (game.current) {
game.current.destroy(true);
if (game.current !== null) {
game.current = null;
}
}
}
}, []);
return (
<div id = "game-container"></div>
);
}
export default Game;
import { Scene } from "phaser";
export class MainScene extends Scene {
constructor () {
super("MainScene");
}
preload() {
this.load.image("tiles", "assets/tiles.1.png");
}
create () {
this.add.text(0, 0, "Text 1", {
fontSize: `10px`,
});
this.add.text(0, 20, "Text 2", {
fontSize: `10px`,
});
}
}
(клонируйте stackoverflow/questions/78791454
ветку и запустите npm run dev
для воспроизведения)
Я обнаружил, что это происходит только в браузере Chrome.
@winner_joiner Я добавил раздел «Минимальный воспроизводимый пример» в тело вопроса. Мне все еще нужна твоя помощь. Спасибо.
Прежде всего, я должен сказать: отличный вопрос и потрясающее резюме и анализ.
Я провел небольшое тестирование и заметил, что это может быть связано с реакцией/nextjs и/или проблемой с очисткой canvas
. Поскольку ваш код фазера работает не на React, а на базовой странице React или с набором type: Phaser.WEBGL
. В вашей демонстрации DevTools дважды покажите баннер фазера. Если вы закомментируете деструктор в файле _components/game/index.tsx
, баннер фазера отобразится один раз, и текст будет выглядеть правильно. К сожалению, я недостаточно хорошо знаю React/Next, чтобы сузить проблему. Я добавил тег nextjs
, так как думаю, что настройка следующего кода может решить вашу проблему.
@winner_joiner Спасибо, твой совет мне очень помог. Я написал деструктор, потому что в стиле React обратный вызов useEffect
должен возвращать функцию, которая очищает все элементы, измененные в этом обратном вызове. Как вы упомянули, я также обнаружил, что type: Phaser.WEBGL
все работает хорошо, и обнаружил, что это зависит от среды: только в Chrome на ПК. У меня такое ощущение, что это ошибка в библиотеке фазера...
Я обновил свой первоначальный ответ, добавив два решения для использования обычного текстового GameObject. Надеюсь, это решит вашу проблему, и удачного кодирования. :)
@winner_joiner Спасибо за помощь! Я застрял над этой проблемой несколько дней и почти отказываюсь от фреймворка фазера. Вы помогли мне по-настоящему.
Обновление (26 июля 2024 г.). Два возможных «решения»:
Я покопался еще немного и нашел решение проблемы:
Поскольку проблема связана с некоторой проблемой очистки холста, вы можете просто установить фазер «CanvasPool» в пустой список в деструкторе, прежде чем уничтожать объект game
. Это приведет к созданию новых объектов html-canvas.
// ...
return () => {
if (game.current) {
Phaser.Display.Canvas.CanvasPool.pool = [];
game.current.destroy(true);
if (game.current !== null) {
game.current = null;
}
}
} //...
Похоже, что двойной вызов useEffect
связан с запуском приложения в режиме разработки (StrictMode). Если вы запустите приложение в производственном режиме (npm run build
и npm run start
), фазер не будет запускаться так быстро подряд, поэтому и этой ошибки не возникнет. Никаких других изменений не требуется (эта информация основана на этом ответе на stackoverflow и кратком просмотре документации)
Я протестировал оба варианта с вашим MRE, и оба работают нормально.
Это «обходной путь» на базе Phaser (первоначальный ответ)
вы можете использовать Phaser BitmapFonts . Поскольку Bitmap Text GameObject визуализируется/генерируется другим способом (а не на скрытом внутреннем холсте, как обычный Text GameObject), проблем не возникнет.
Я протестировал ваше демонстрационное приложение с растровым шрифтом, и оно работает (на Win11 Chrome 126+).
По их словам, растровый текст не так гибок, как обычный текст, но имеет лучшую производительность. Существует несколько инструментов преобразования шрифтов, которые могут помочь, если вам нужен какой-то специальный шрифт, но, поскольку я никогда им не пользовался, я не могу его предложить. Также существует множество готовых к использованию растровых шрифтов (, как здесь , или в примерах растровых шрифтов Phaser, ...).
Спасибо за ваш труд и очень подробный ответ!
Добро пожаловать, рад, что смог помочь. Кстати: если у вас когда-нибудь возник вопрос о фазере, вы также можете заглянуть на официальный форум фазера некоторые из фазеров - разработчики там довольно активны и полезны. В большинстве случаев вы можете получить ответ в течение нескольких часов. (Есть также официальный дискорд-сервер фазера, который довольно активен, но я никогда им не пользовался до сих пор)
Этого не должно происходить, можете ли вы привести минимальный воспроизводимый пример ? Потому что, если вы не установите фоновый цвет для текстового GameObject, насколько я знаю, никакого цвета быть не должно. Возможно, это какие-то побочные эффекты с другим кодом