228 lines
		
	
	
		
			7.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			228 lines
		
	
	
		
			7.0 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) {
 | |
|       return this.tmrDialog.getTokensDetails(coordTMR)
 | |
|     }
 | |
|     return undefined
 | |
|   }
 | |
| 
 | |
|   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 };
 | |
|   }
 | |
| } |