feat: Implement tower selection and upgrade system with pan control

- Added allowPan flag to level scene to control camera panning
- Implemented interface manager to disable/enable panning when interfaces open/close
- Enhanced tower manager with:
  * Tower selection functionality
  * Visual range circle and rotating line indicator
  * Global click handler to close upgrade menu when clicking outside towers
  * Depth management for tower sprites
  * Pointer overlap detection for UI interactions

This enables proper tower selection, visual feedback during upgrades, and prevents camera panning while interacting with the UI.
This commit is contained in:
Brian Fertig 2025-09-03 15:54:27 -06:00
parent b554839537
commit 0dc8fba5db
3 changed files with 63 additions and 4 deletions

View File

@ -4,6 +4,8 @@ import { TowerManager } from '../support/towerManager.js';
export class Level extends Phaser.Scene {
constructor() {
super({ key: 'Level' });
this.allowPan = true;
}
init(data) {
@ -81,7 +83,7 @@ export class Level extends Phaser.Scene {
// Add camera panning functionality
this.input.on('pointerdown', (pointer) => {
if (pointer.button === 0) { // Left mouse button
if (pointer.button === 0 && this.allowPan === true) { // Left mouse button
this.isPanning = true;
this.panStartX = pointer.x;
this.panStartY = pointer.y;

View File

@ -205,6 +205,7 @@ export class InterfaceManager {
openInterface() {
this.interfaceOpen = true;
this.scene.levelScene.allowPan = false;
this.upLeft.setAlpha(0).setRotation(Math.PI);
this.upRight.setAlpha(0).setRotation(Math.PI);
this.interfaceText.setAlpha(0).setText('Click to Close');
@ -225,6 +226,7 @@ export class InterfaceManager {
closeInterface() {
this.interfaceOpen = false;
this.scene.levelScene.allowPan = true;
this.upLeft.setAlpha(0).setRotation(0);
this.upRight.setAlpha(0).setRotation(0);
this.interfaceText.setAlpha(0).setText('Click to Open');

View File

@ -7,16 +7,24 @@ export class TowerManager {
this.scene = scene;
this.lastFired = {}; // Track last fire time for each tower
this.following = {};
this.selectedTower = null;
this.createAnims();
// Add global click handler to close upgrade menu
this.scene.input.on('pointerdown', (pointer) => {
if (this.selectedTower && !this.isPointerOverTower(pointer)) {
this.closeUpgradeMenu();
}
});
}
createTower(type, x, y) {
const posX = this.scene.gridToLocation(x);
const posY = this.scene.gridToLocation(y);
const towerBase = this.scene.add.sprite(posX, posY, 'towers', 7);
const tower = this.scene.add.sprite(posX, posY, 'towers', TOWERS_CONFIG[type].spriteStart);
const towerBase = this.scene.add.sprite(posX, posY, 'towers', 7).setDepth(10);
const tower = this.scene.add.sprite(posX, posY, 'towers', TOWERS_CONFIG[type].spriteStart).setDepth(11);
tower.props = {
'type': type,
'level': 1
@ -29,7 +37,9 @@ export class TowerManager {
this.scene.towers.add(tower);
tower.setInteractive();
tower.on('pointerdown', () => {
if (!this.selectedTower) {
this.upgradeMenu(tower);
}
});
// Draw range circle
@ -41,6 +51,25 @@ export class TowerManager {
}
upgradeMenu(tower) {
this.selectedTower = tower;
const camera = this.scene.cameras.main;
const towerLocX = tower.x - camera.scrollX;
const towerLocY = tower.y - camera.scrollY;
this.rangeCircle = this.scene.add.circle(tower.x, tower.y, TOWERS_CONFIG[tower.props.type].level1.range, 0xc009900, 0.2)
.setOrigin(0.5)
.setDepth(5);
// Add a line from center to edge of range circle
this.centerToEdgeLine = this.scene.add.line(tower.x, tower.y, 0, 0, TOWERS_CONFIG[tower.props.type].level1.range, 0, 0x00ff00)
.setOrigin(0)
.setDepth(6);
this.scene.tweens.add({
targets: this.centerToEdgeLine,
angle: 360,
duration: 8000,
repeat: -1
});
console.log('here');
// TODO: update this asap.
const nextLevel = `level${tower.props.level+1}`;
if (this.scene.UIScene.interfaceManager.gold >= TOWERS_CONFIG[tower.props.type][nextLevel].cost){
@ -48,6 +77,32 @@ export class TowerManager {
}
}
isPointerOverTower(pointer) {
// Check if pointer is over any tower
let isOverTower = false;
this.scene.towers.children.iterate((tower) => {
if (tower.getBounds().contains(pointer.x, pointer.y)) {
isOverTower = true;
return false; // Break iteration
}
});
return isOverTower;
}
closeUpgradeMenu() {
if (this.rangeCircle) {
this.rangeCircle.destroy();
this.rangeCircle = null;
}
if (this.centerToEdgeLine) {
this.centerToEdgeLine.destroy();
this.centerToEdgeLine = null;
}
this.selectedTower = null;
}
upgradeTower(tower) {
if (tower.props.level === 3) return;