foundryvtt-reve-de-dragon/module/tmr/pixi-tmr.js
Vincent Vandemeulebrouck 84ea3a6ea9 Fix: TMR qui ne s'affichent pas
Après un certain temps (changements de scènes?), les TMR ne
s'affichaient plus correctement.

Tentative de forcer le chargement des textures manquantes lors
de l'ouverture de la fenêtre de TMR.
2024-03-10 00:47:50 +01:00

231 lines
7.2 KiB
JavaScript

import { Misc } from "../misc.js";
import { TMRConstants, tmrTokenZIndex } from "../tmr-constants.js";
import { TMRUtility } from "../tmr-utility.js";
import { EffetsDraconiques } from "./effets-draconiques.js";
export class PixiTMR {
static textures = []
static getImgFromCode(code) {
return PixiTMR.textures[code]
}
static register(name, img) {
PixiTMR.textures[name] = img;
}
static async init() {
await Promise.all(
Object.values(PixiTMR.textures)
.filter(img => img != undefined && !PIXI.utils.TextureCache[img])
.map(async img => PIXI.Sprite.from(await PIXI.Assets.load(img))))
}
constructor(tmrDialog, displaySize) {
this.tmrDialog = tmrDialog;
this.callbacksOnAnimate = [];
this.sizes = new TMRConstants({ size: displaySize })
console.info(`Creation d'Application PIXI pour les TMR de ${tmrDialog.actor.name}`)
this.pixiApp = new PIXI.Application(PixiTMR.computeTMRSize(this.sizes));
this.pixiApp.eventMode = 'static';
this.pixiApp.stage.sortableChildren = true;
this.tooltipStyle = new PIXI.TextStyle({
fontFamily: 'CaslonAntique',
fontSize: 16,
fill: '#FFFFFF',
stroke: '#000000',
strokeThickness: 4
});
this.tooltip = new PIXI.Text('', this.tooltipStyle);
this.tooltip.zIndex = 1000
this.pixiApp.stage.addChild(this.tooltip);
}
close() {
console.info(`Destruction d'Application PIXI pour les TMR de ${this.tmrDialog.actor.name}`)
this.pixiApp.destroy();
this.pixiApp = undefined
}
static computeTMRSize(sizeConstants) {
return { width: sizeConstants.cellw * 13 + sizeConstants.marginx, height: sizeConstants.cellh / 2 + sizeConstants.cellh * 15 + sizeConstants.marginy }
}
resizeTMR(displaySize) {
this.sizes = new TMRConstants({ size: displaySize })
const appSize = PixiTMR.computeTMRSize(this.sizes)
this.pixiApp.renderer.resize(appSize.width, appSize.height)
this.tooltipStyle.fontSize = Math.max(this.sizes.size / 3, 16)
}
get view() {
return this.pixiApp.view
}
setup() {
this.carteTMR = EffetsDraconiques.carteTmr.createSprite(this);
this.pixiApp.stage.addChild(this.carteTMR);
this.carteTMR.isOver = false;
this.carteTMR.eventMode = 'static';
this.carteTMR
.on('pointermove', event => this.onPointerMove(event))
.on('pointerdown', event => this.onClickBackground(event))
.on('pointerover', event => this.onShowTooltip(event))
.on('pointerout', event => this.onHideTooltip(event));
}
async loadAnimations() {
for (let onAnimate of this.callbacksOnAnimate) {
onAnimate();
}
this.pixiApp.ticker.start();
}
animate(animation = pixiApp => { }) {
this.callbacksOnAnimate.push(() => animation(this.pixiApp));
}
addMarkTMR(coordTMR) {
const rect = this.getCaseRectangle(TMRUtility.coordTMRToOddq(coordTMR))
const markTMR = new PIXI.Graphics();
markTMR.beginFill(0xffff00, 0.3);
// set the line style to have a width of 5 and set the color to red
markTMR.lineStyle(5, 0xff0000);
// draw a rectangle
markTMR.drawRect(rect.x, rect.y, rect.w, rect.h);
this.pixiApp.stage.addChild(markTMR);
return markTMR
}
removeGraphic(graphic) {
this.pixiApp.stage.removeChild(graphic);
}
sprite(code, options = {}) {
let img = PixiTMR.getImgFromCode(code)
let texture = PIXI.utils.TextureCache[img]
if (!texture) {
// TODO: charger la texture
console.error("Texture manquante", code, PIXI.utils.TextureCache)
return;
}
let sprite = new PIXI.Sprite(texture);
sprite.taille = options.taille ?? (() => this.sizes.half)
sprite.width = sprite.taille()
sprite.height = sprite.taille()
sprite.anchor.set(0.5)
if (options.tint) {
sprite.tint = options.tint
}
sprite.zIndex = options.zIndex ?? tmrTokenZIndex.casehumide + 1
sprite.alpha = options.alpha ?? 1
sprite.decallage = options.decallage ?? this.sizes.center
this.pixiApp.stage.addChild(sprite)
return sprite
}
circle(code, options = {}) {
let sprite = new PIXI.Graphics()
sprite.taille = options.taille ?? (() => this.sizes.half)
sprite.decallage = options.decallage ?? this.sizes.topLeft
sprite.beginFill(options.tint, options.opacity)
sprite.drawCircle(0, 0, sprite.taille())
sprite.endFill()
this.pixiApp.stage.addChild(sprite)
return sprite
}
square(code, options = {}) {
let sprite = new PIXI.Graphics();
sprite.taille = options.taille ?? (() => this.sizes.half)
sprite.decallage = options.decallage ?? this.sizes.topLeft
sprite.beginFill(options.tint, options.opacity)
const size = sprite.taille();
sprite.drawRect(0, 0, size, size)
sprite.endFill()
this.pixiApp.stage.addChild(sprite)
return sprite
}
onClickBackground(event) {
if (!this.viewOnly) {
this.tmrDialog.onClickTMR(event)
}
}
onPointerMove(event) {
if (this.carteTMR.isOver) {
this.setTooltipPosition(event);
this.tooltip.text = this.computeTooltip(event);
}
}
onShowTooltip(event) {
if (!this.carteTMR.isOver) {
this.setTooltipPosition(event);
this.pixiApp.stage.addChild(this.tooltip);
this.tooltip.text = this.computeTooltip(event);
}
this.carteTMR.isOver = true;
}
onHideTooltip(event) {
if (this.carteTMR.isOver) {
this.pixiApp.stage.removeChild(this.tooltip);
}
this.carteTMR.isOver = false;
}
computeTooltip(event) {
const oddq = this.sizes.computeEventOddq(event);
const coordTMR = TMRUtility.oddqToCoordTMR(oddq);
const tmr = TMRUtility.getTMR(coordTMR)
if (tmr) {
const tmrTooltip = `${coordTMR}: ${TMRUtility.getTMRLabel(coordTMR)}`;
const tokenTooltips = this.tmrDialog.allTokens
.filter(token => token.coordTMR() == coordTMR)
.map(token => token.tooltip);
return [tmrTooltip, ...tokenTooltips].reduce(Misc.joining('\n'))
}
}
computeEventOddq(event) {
return this.sizes.computeEventOddq(event)
}
setTooltipPosition(event) {
const oddq = this.sizes.computeEventOddq(event);
this.tooltip.x = oddq.x + (oddq.col > 7 ? -2.5 * this.sizes.full : this.sizes.quarter);
this.tooltip.y = oddq.y + (oddq.row > 10 ? -this.sizes.size : 0);
}
positionToken(token) {
if (token.sprite) {
const sprite = token.sprite;
const oddq = TMRUtility.coordTMRToOddq(token.coordTMR());
const decallagePairImpair = (oddq.col % 2 == 0) ? this.sizes.col1_y : this.sizes.col2_y;
const dx = sprite.decallage?.x ?? 0
const dy = sprite.decallage?.y ?? 0
sprite.x = this.sizes.gridx + (oddq.col * this.sizes.cellw) + dx;
sprite.y = this.sizes.gridy + (oddq.row * this.sizes.cellh) + dy + decallagePairImpair;
}
}
removeToken(token) {
if (token.sprite) {
this.pixiApp.stage.removeChild(token.sprite)
}
}
getCaseRectangle(oddq) {
const decallagePairImpair = (oddq.col % 2 == 0) ? this.sizes.col1_y : this.sizes.col2_y;
const x = this.sizes.gridx + (oddq.col * this.sizes.cellw) - (this.sizes.cellw / 2);
const y = this.sizes.gridy + (oddq.row * this.sizes.cellh) - (this.sizes.cellh / 2) + decallagePairImpair;
return { x, y, w: this.sizes.cellw, h: this.sizes.cellh };
}
}