Adding the ability to display "Text" objects from Tiled
I honestly don't believe text objects look good on map, and in real maps, I think text should be written on tiles. However, for a variety of use cases (like in test maps in the /maps/test directory, it can be useful to be able to display some text easily on a map. This PR adds the ability to display this text. Note: the "font" support cannot work correctly, as Tiled is listing fonts from the local system, and those fonts are not available in a browser.
This commit is contained in:
parent
e37ab7d8ad
commit
22cb41dc29
45
front/src/Phaser/Components/TextUtils.ts
Normal file
45
front/src/Phaser/Components/TextUtils.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import {ITiledMapObject} from "../Map/ITiledMap";
|
||||||
|
import Text = Phaser.GameObjects.Text;
|
||||||
|
import {GameScene} from "../Game/GameScene";
|
||||||
|
import TextStyle = Phaser.GameObjects.TextStyle;
|
||||||
|
|
||||||
|
export class TextUtils {
|
||||||
|
public static createTextFromITiledMapObject(scene: GameScene, object: ITiledMapObject): void {
|
||||||
|
if (object.text === undefined) {
|
||||||
|
throw new Error('This object has not textual representation.');
|
||||||
|
}
|
||||||
|
const options: {font?: string} = {};
|
||||||
|
let font = '';
|
||||||
|
if (object.text.italic) {
|
||||||
|
font += 'italic ';
|
||||||
|
}
|
||||||
|
// Note: there is no support for "strikeout" and "underline"
|
||||||
|
let fontSize: number = 16;
|
||||||
|
if (object.text.pixelsize) {
|
||||||
|
font += object.text.pixelsize+'px ';
|
||||||
|
fontSize = object.text.pixelsize;
|
||||||
|
} else {
|
||||||
|
font += '16px ';
|
||||||
|
}
|
||||||
|
if (object.text.fontfamily) {
|
||||||
|
font += '"'+object.text.fontfamily+'"';
|
||||||
|
}
|
||||||
|
if (font !== '') {
|
||||||
|
options.font = font;
|
||||||
|
}
|
||||||
|
const textElem = scene.add.text(object.x, object.y, object.text.text, options);
|
||||||
|
textElem.setFontSize(fontSize);
|
||||||
|
let color = '#000000';
|
||||||
|
if (object.text.color !== undefined) {
|
||||||
|
color = object.text.color;
|
||||||
|
}
|
||||||
|
textElem.setColor(color);
|
||||||
|
if (object.text.wrap) {
|
||||||
|
textElem.setWordWrapWidth(textElem.width);
|
||||||
|
}
|
||||||
|
textElem.setAngle(object.rotation);
|
||||||
|
if (object.text.halign !== undefined) {
|
||||||
|
textElem.setAlign(object.text.halign);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,7 @@ import {
|
|||||||
ITiledMapLayer,
|
ITiledMapLayer,
|
||||||
ITiledMapLayerProperty,
|
ITiledMapLayerProperty,
|
||||||
ITiledMapObject,
|
ITiledMapObject,
|
||||||
|
ITiledText,
|
||||||
ITiledMapTileLayer,
|
ITiledMapTileLayer,
|
||||||
ITiledTileSet
|
ITiledTileSet
|
||||||
} from "../Map/ITiledMap";
|
} from "../Map/ITiledMap";
|
||||||
@ -84,6 +85,7 @@ import DOMElement = Phaser.GameObjects.DOMElement;
|
|||||||
import {Subscription} from "rxjs";
|
import {Subscription} from "rxjs";
|
||||||
import {worldFullMessageStream} from "../../Connexion/WorldFullMessageStream";
|
import {worldFullMessageStream} from "../../Connexion/WorldFullMessageStream";
|
||||||
import { lazyLoadCompanionResource } from "../Companion/CompanionTexturesLoadingManager";
|
import { lazyLoadCompanionResource } from "../Companion/CompanionTexturesLoadingManager";
|
||||||
|
import {TextUtils} from "../Components/TextUtils";
|
||||||
import {LayersIterator} from "../Map/LayersIterator";
|
import {LayersIterator} from "../Map/LayersIterator";
|
||||||
import {touchScreenManager} from "../../Touch/TouchScreenManager";
|
import {touchScreenManager} from "../../Touch/TouchScreenManager";
|
||||||
import {PinchManager} from "../UserInput/PinchManager";
|
import {PinchManager} from "../UserInput/PinchManager";
|
||||||
@ -412,6 +414,13 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
if (layer.type === 'objectgroup' && layer.name === 'floorLayer') {
|
if (layer.type === 'objectgroup' && layer.name === 'floorLayer') {
|
||||||
depth = 10000;
|
depth = 10000;
|
||||||
}
|
}
|
||||||
|
if (layer.type === 'objectgroup') {
|
||||||
|
for (const object of layer.objects) {
|
||||||
|
if (object.text) {
|
||||||
|
TextUtils.createTextFromITiledMapObject(this, object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (depth === -2) {
|
if (depth === -2) {
|
||||||
throw new Error('Your map MUST contain a layer of type "objectgroup" whose name is "floorLayer" that represents the layer characters are drawn at. This layer cannot be contained in a group.');
|
throw new Error('Your map MUST contain a layer of type "objectgroup" whose name is "floorLayer" that represents the layer characters are drawn at. This layer cannot be contained in a group.');
|
||||||
|
@ -136,6 +136,20 @@ export interface ITiledMapObject {
|
|||||||
* Polyline points
|
* Polyline points
|
||||||
*/
|
*/
|
||||||
polyline: {x: number, y: number}[];
|
polyline: {x: number, y: number}[];
|
||||||
|
|
||||||
|
text?: ITiledText
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ITiledText {
|
||||||
|
text: string,
|
||||||
|
wrap?: boolean,
|
||||||
|
fontfamily?: string,
|
||||||
|
pixelsize?: number,
|
||||||
|
color?: string,
|
||||||
|
underline?: boolean,
|
||||||
|
italic?: boolean,
|
||||||
|
strikeout?: boolean,
|
||||||
|
halign?: "center"|"right"|"justify"|"left"
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ITiledTileSet {
|
export interface ITiledTileSet {
|
||||||
|
179
maps/tests/text_object.json
Normal file
179
maps/tests/text_object.json
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
{ "compressionlevel":-1,
|
||||||
|
"height":10,
|
||||||
|
"infinite":false,
|
||||||
|
"layers":[
|
||||||
|
{
|
||||||
|
"data":[1, 1, 1, 1, 1, 1, 23, 23, 23, 23, 1, 1, 1, 1, 1, 1, 23, 23, 23, 23, 1, 1, 1, 1, 1, 1, 23, 23, 23, 23, 1, 1, 1, 1, 1, 1, 23, 23, 23, 23, 1, 1, 1, 1, 1, 1, 23, 23, 23, 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||||
|
"height":10,
|
||||||
|
"id":1,
|
||||||
|
"name":"floor",
|
||||||
|
"opacity":1,
|
||||||
|
"type":"tilelayer",
|
||||||
|
"visible":true,
|
||||||
|
"width":10,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
"height":10,
|
||||||
|
"id":2,
|
||||||
|
"name":"start",
|
||||||
|
"opacity":1,
|
||||||
|
"type":"tilelayer",
|
||||||
|
"visible":true,
|
||||||
|
"width":10,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"draworder":"topdown",
|
||||||
|
"id":3,
|
||||||
|
"name":"floorLayer",
|
||||||
|
"objects":[
|
||||||
|
{
|
||||||
|
"height":154.708861498919,
|
||||||
|
"id":1,
|
||||||
|
"name":"",
|
||||||
|
"rotation":0,
|
||||||
|
"text":
|
||||||
|
{
|
||||||
|
"color":"#ffff00",
|
||||||
|
"fontfamily":"Sans Serif",
|
||||||
|
"text":"A yellow text that wraps automatically.\n\nIt is 16px high.",
|
||||||
|
"wrap":true
|
||||||
|
},
|
||||||
|
"type":"",
|
||||||
|
"visible":true,
|
||||||
|
"width":127.701300455634,
|
||||||
|
"x":192.052147832817,
|
||||||
|
"y":5.45414451778726
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"height":19,
|
||||||
|
"id":3,
|
||||||
|
"name":"",
|
||||||
|
"rotation":0,
|
||||||
|
"text":
|
||||||
|
{
|
||||||
|
"text":"Default text",
|
||||||
|
"wrap":true
|
||||||
|
},
|
||||||
|
"type":"",
|
||||||
|
"visible":true,
|
||||||
|
"width":113.494863163736,
|
||||||
|
"x":1.76065884397454,
|
||||||
|
"y":8.44497342134471
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"height":19,
|
||||||
|
"id":5,
|
||||||
|
"name":"",
|
||||||
|
"rotation":0,
|
||||||
|
"text":
|
||||||
|
{
|
||||||
|
"text":"A very long text with no world wrap so it keeps going"
|
||||||
|
},
|
||||||
|
"type":"",
|
||||||
|
"visible":true,
|
||||||
|
"width":349.4375,
|
||||||
|
"x":1.01295161808517,
|
||||||
|
"y":168.828173374613
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"height":19,
|
||||||
|
"id":6,
|
||||||
|
"name":"",
|
||||||
|
"rotation":45,
|
||||||
|
"text":
|
||||||
|
{
|
||||||
|
"text":"A rotated text"
|
||||||
|
},
|
||||||
|
"type":"",
|
||||||
|
"visible":true,
|
||||||
|
"width":117.607252906128,
|
||||||
|
"x":62.3249441410129,
|
||||||
|
"y":41.3440913604766
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"height":48.1605818096851,
|
||||||
|
"id":7,
|
||||||
|
"name":"",
|
||||||
|
"rotation":0,
|
||||||
|
"text":
|
||||||
|
{
|
||||||
|
"fontfamily":"Sans Serif",
|
||||||
|
"italic":true,
|
||||||
|
"pixelsize":27,
|
||||||
|
"strikeout":true,
|
||||||
|
"text":"Italic 27px",
|
||||||
|
"underline":true
|
||||||
|
},
|
||||||
|
"type":"",
|
||||||
|
"visible":true,
|
||||||
|
"width":337.807030930545,
|
||||||
|
"x":6.6207558122554,
|
||||||
|
"y":209.952070798528
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"height":40,
|
||||||
|
"id":9,
|
||||||
|
"name":"",
|
||||||
|
"rotation":0,
|
||||||
|
"text":
|
||||||
|
{
|
||||||
|
"fontfamily":"Sans Serif",
|
||||||
|
"halign":"center",
|
||||||
|
"pixelsize":15,
|
||||||
|
"text":"This text should appear below the plant and be centered",
|
||||||
|
"wrap":true
|
||||||
|
},
|
||||||
|
"type":"",
|
||||||
|
"visible":true,
|
||||||
|
"width":317.4375,
|
||||||
|
"x":0.78125,
|
||||||
|
"y":269.5
|
||||||
|
}],
|
||||||
|
"opacity":1,
|
||||||
|
"type":"objectgroup",
|
||||||
|
"visible":true,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 79, 80, 0, 0, 0, 0, 0, 0, 0, 89, 90, 91, 0, 0, 0, 0, 0, 0, 0, 100, 101, 102, 0, 0, 0, 0],
|
||||||
|
"height":10,
|
||||||
|
"id":8,
|
||||||
|
"name":"over",
|
||||||
|
"opacity":1,
|
||||||
|
"type":"tilelayer",
|
||||||
|
"visible":true,
|
||||||
|
"width":10,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
}],
|
||||||
|
"nextlayerid":9,
|
||||||
|
"nextobjectid":10,
|
||||||
|
"orientation":"orthogonal",
|
||||||
|
"renderorder":"right-down",
|
||||||
|
"tiledversion":"2021.03.23",
|
||||||
|
"tileheight":32,
|
||||||
|
"tilesets":[
|
||||||
|
{
|
||||||
|
"columns":11,
|
||||||
|
"firstgid":1,
|
||||||
|
"image":"tileset1.png",
|
||||||
|
"imageheight":352,
|
||||||
|
"imagewidth":352,
|
||||||
|
"margin":0,
|
||||||
|
"name":"tileset1",
|
||||||
|
"spacing":0,
|
||||||
|
"tilecount":121,
|
||||||
|
"tileheight":32,
|
||||||
|
"tilewidth":32
|
||||||
|
}],
|
||||||
|
"tilewidth":32,
|
||||||
|
"type":"map",
|
||||||
|
"version":1.5,
|
||||||
|
"width":10
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user