diff --git a/src/classes/GuiObject.ts b/src/classes/GuiObject.ts index edec09e..5e62348 100644 --- a/src/classes/GuiObject.ts +++ b/src/classes/GuiObject.ts @@ -10,6 +10,8 @@ export default abstract class GuiObject { protected enabled: boolean = true; + public bb: PIXI.Rectangle = new PIXI.Rectangle(); + public destroy() { this._events.removeAllListeners(); if (this._container.parent) this._container.parent.removeChild(this._container); @@ -36,6 +38,30 @@ export default abstract class GuiObject { this.enabled = enabled; } + public copyContainerToBB() { + this.bb.x = this.container.x; + this.bb.y = this.container.y; + this.bb.width = this.container.width; + this.bb.height = this.container.height; + return this.bb; + } + + public copyBBToContainer() { + this.container.x = this.bb.x; + this.container.y = this.bb.y; + this.container.width = this.bb.width; + this.container.height = this.bb.height; + return this.container; + } + + public copyPropertiesToObj(obj: PIXI.Container) { + obj.x = this.bb.x; + obj.y = this.bb.y; + obj.width = this.bb.width; + obj.height = this.bb.height; + return obj; + } + constructor(interactive?: boolean) { Engine.GameMaster._CreateGuiObject(this); if (!interactive) return; diff --git a/src/classes/game/Tower.ts b/src/classes/game/Tower.ts index 3e3615d..d81d5a8 100644 --- a/src/classes/game/Tower.ts +++ b/src/classes/game/Tower.ts @@ -8,7 +8,7 @@ import Projectile, { calculateAngleToPoint } from './Projectile'; import Creep from './Creep'; import Gem from './Gem'; -function distance(x1, y1, x2, y2) { +export function distance(x1, y1, x2, y2) { return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); } @@ -70,6 +70,7 @@ export class Tower extends GameObject { this.slottedGems[i + 1] = null; } } + Engine.GameScene.sidebar.gemTab.selectingGemTowerObject = this; this.slottedGems = this.slottedGems.filter((gem) => gem != null); Engine.NotificationManager.Notify( `Lv. ${gem.level} ${gem.definition.name} unslotted and placed back in your inventory.`, diff --git a/src/classes/gui/GemTab.ts b/src/classes/gui/GemTab.ts index 38777c6..f7da1d5 100644 --- a/src/classes/gui/GemTab.ts +++ b/src/classes/gui/GemTab.ts @@ -5,7 +5,7 @@ import { Engine } from '../Bastion'; import { StatsEvents } from '../Events'; import Gem from '../game/Gem'; import { VisualGemSlot } from './TowerPanel'; -import { Tower } from '../game/Tower'; +import { distance, Tower } from '../game/Tower'; export default class GemTab extends GuiObject { private bounds: PIXI.Rectangle; @@ -14,6 +14,8 @@ export default class GemTab extends GuiObject { public isSelectingGem: boolean = false; public selectingGemSlotIndex: number = -1; public selectingGemTowerObject: Tower = null; + public isDragAndDroppingGem: boolean = false; + private dragAndDroppingGem: VisualGemSlot = null; constructor(bounds: PIXI.Rectangle) { super(false); @@ -32,6 +34,9 @@ export default class GemTab extends GuiObject { this.gemTabSprite.width = this.bounds.width; this.gemTabSprite.height = this.bounds.height; this.container.addChild(this.gemTabSprite); + Engine.app.canvas.addEventListener('pointermove', () => { + this.pointerMoveEvent(); + }); Engine.GameScene.events.on(StatsEvents.GemGivenEvent, () => { this.RebuildInventoryVisual(); @@ -70,12 +75,16 @@ export default class GemTab extends GuiObject { } } } + public pointerMoveEvent() { + if (!this.isDragAndDroppingGem || !Engine.GameScene.towerPanel.isShown || !this.dragAndDroppingGem) return; + this.dragAndDroppingGem.container.x = Engine.MouseX - 32; + this.dragAndDroppingGem.container.y = Engine.MouseY - 32; + } public RebuildInventoryVisual() { this.vGems.forEach((vGem) => vGem.destroy()); this.vGems = []; Engine.GameScene.MissionStats.getInventory().forEach((gem, index) => { let vGem = new VisualGemSlot(0, this.container, gem); - let vGemYCoord = 10; let vGemXCoord = (index % 4) * 70 + 10; let vGemYIdx = index; @@ -87,22 +96,56 @@ export default class GemTab extends GuiObject { vGem.container.x = vGemXCoord; vGem.container.y = vGemYCoord; vGem.container.onpointermove = () => { - if (gem == null) return; + if (gem == null || this.isDragAndDroppingGem) return; Engine.GameScene.tooltip.SetContentGem(gem); Engine.GameScene.tooltip.Show(Engine.MouseX, Engine.MouseY); }; vGem.container.onpointerleave = () => { Engine.GameScene.tooltip.Hide(); }; - vGem.onClick = () => { + vGem.container.onpointerdown = () => { Engine.GameScene.tooltip.Hide(); if (this.isSelectingGem) { + // already clicked on vGem slot in towerpanel this.isSelectingGem = false; let takenGem = Engine.GameScene.MissionStats.takeGem(gem); this.selectingGemTowerObject.SlotGem(takenGem, this.selectingGemSlotIndex); this.RebuildInventoryVisual(); + } else { + if (!Engine.GameScene.towerPanel.isShown) return; + // initialise drag and drop + this.isDragAndDroppingGem = true; + this.dragAndDroppingGem = vGem; + vGem.container.removeFromParent(); + Engine.GameScene.stage.addChild(vGem.container); + this.pointerMoveEvent(); } }; + vGem.container.onpointerup = () => { + if (this.isSelectingGem) return; + let overlapping = null; + Engine.GameScene.towerPanel.vGems.forEach((internVG) => { + if (overlapping || !this.dragAndDroppingGem) return; + let ddbb = this.dragAndDroppingGem.copyContainerToBB(); + let vb = internVG.copyContainerToBB(); + let x = Engine.GameScene.towerPanel.container.x + vb.x; + let y = Engine.GameScene.towerPanel.container.y + vb.y; + + let vgbb = new PIXI.Rectangle(x, y, vb.width, vb.height); + console.log(ddbb, vgbb, ddbb.getBounds().intersects(vgbb)); + if (ddbb.getBounds().intersects(vgbb)) { + if (internVG && internVG.gem == null) overlapping = internVG; + } + }); + if (overlapping) { + let takenGem = Engine.GameScene.MissionStats.takeGem(gem); + Engine.GameScene.towerPanel.showingTower.SlotGem(takenGem, overlapping.i); + } + // clean up + this.isDragAndDroppingGem = false; + this.dragAndDroppingGem = null; + this.RebuildInventoryVisual(); + }; this.vGems.push(vGem); }); } diff --git a/src/classes/gui/TowerPanel.ts b/src/classes/gui/TowerPanel.ts index b77e10b..5493cdb 100644 --- a/src/classes/gui/TowerPanel.ts +++ b/src/classes/gui/TowerPanel.ts @@ -13,6 +13,7 @@ export class VisualGemSlot extends GuiObject { private background: PIXI.Sprite; private frame: PIXI.Sprite; public i: number = 0; + public gem: Gem = null; constructor(index: number, parent: PIXI.Container, gem: Gem | null) { super(true); let gtexture; @@ -26,6 +27,7 @@ export class VisualGemSlot extends GuiObject { gtexture = GameAssets.PlusIconTexture; } else { gtexture = gem.texture; + this.gem = gem; } this.iconSprite = new PIXI.Sprite({ texture: gtexture, @@ -54,21 +56,19 @@ export class VisualGemSlot extends GuiObject { this.container.addChild(this.background); this.container.addChild(this.iconSprite); this.container.addChild(this.frame); - if (Engine.latestCommit == 'DEVELOPMENT') { - let txt = gem ? gem.id : ''; - let dbgText = new PIXI.Text({ - text: txt, - zIndex: 11, - style: { - fill: 'white', - stroke: { - color: 0x000000, - width: 5, - }, + let txt = gem ? gem.id : ''; + let dbgText = new PIXI.Text({ + text: txt, + zIndex: 11, + style: { + fill: 'white', + stroke: { + color: 0x000000, + width: 5, }, - }); - this.container.addChild(dbgText); - } + }, + }); + this.container.addChild(dbgText); parent.addChild(this.container); } @@ -86,6 +86,7 @@ export default class TowerPanel extends GuiObject { private towerPanel: PIXI.NineSliceSprite; private closeBtn: Button; public vGems: VisualGemSlot[] = []; + public showingTower: Tower = null; public isShown: boolean = false; public titleText: PIXI.Text; @@ -104,7 +105,6 @@ export default class TowerPanel extends GuiObject { this.closeBtn = new Button(new PIXI.Rectangle(-20, -20, 60, 60), '', ButtonTexture.Button01, true); this.closeBtn.container.removeFromParent(); // Added custom button logic to still keep all the regular events for the button, just have an icon instead of text. - // TODO: maybe make this better? add like a seperate class for icon buttons or smth this.closeBtn.CustomButtonLogic = () => { this.closeBtn.buttonIcon = new PIXI.Sprite({ texture: GameAssets.XIconTexture, @@ -172,10 +172,11 @@ export default class TowerPanel extends GuiObject { } } public Show(tower: Tower) { - let mouseX = Engine.MouseX; this.isShown = true; this.SetContent(tower); this.MakeSlots(tower); + this.showingTower = tower; + Engine.GameScene.sidebar.gemTab.selectingGemTowerObject = tower; if (tower.container.x < 900) { this.ShowRight(); } else {