feat(towers): Implement interactive upgrade system with visual range indicators and cost validation
- Replace static camera bounds with dynamic level dimensions - Add comprehensive tower upgrade menu with animated range circle - Implement gold cost validation and visual feedback for upgrades - Create interactive upgrade/cancel buttons with tween animations - Add upgrade cost tracking and enable/disable functionality - Update UI scene to include new upgrade icon asset
This commit is contained in:
parent
0dc8fba5db
commit
2c37e407cd
Binary file not shown.
|
After Width: | Height: | Size: 212 KiB |
|
|
@ -37,7 +37,7 @@ export class Level extends Phaser.Scene {
|
|||
this.platformsLayer = this.levelMap.createLayer('platforms', terrainTiles);
|
||||
|
||||
// Add camera zoom functionality
|
||||
this.cameras.main.setBounds(0, 0, 2000, 2000);
|
||||
this.cameras.main.setBounds(0, 0, this.mainLayer.width, this.mainLayer.height);
|
||||
this.addControls();
|
||||
|
||||
this.waveManager = new WaveManager(this, 1, 1);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ export class TowerManager {
|
|||
this.lastFired = {}; // Track last fire time for each tower
|
||||
this.following = {};
|
||||
this.selectedTower = null;
|
||||
this.upgradeCost = null;
|
||||
|
||||
this.createAnims();
|
||||
|
||||
|
|
@ -38,6 +39,7 @@ export class TowerManager {
|
|||
tower.setInteractive();
|
||||
tower.on('pointerdown', () => {
|
||||
if (!this.selectedTower) {
|
||||
console.log('CLICK');
|
||||
this.upgradeMenu(tower);
|
||||
}
|
||||
});
|
||||
|
|
@ -52,64 +54,126 @@ 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)
|
||||
const currentLevel = `level${tower.props.level}`;
|
||||
const nextLevel = currentLevel === 'level3' ? 'level3' : `level${tower.props.level + 1}`;
|
||||
|
||||
this.upgradeDetails = this.scene.add.container();
|
||||
|
||||
const rangeCircle = this.scene.add.circle(tower.x, tower.y, TOWERS_CONFIG[tower.props.type][currentLevel].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)
|
||||
this.upgradeDetails.add(rangeCircle);
|
||||
|
||||
const centerToEdgeLine = this.scene.add.line(tower.x, tower.y, 0, 0, TOWERS_CONFIG[tower.props.type][currentLevel].range, 0, 0x00ff00)
|
||||
.setOrigin(0)
|
||||
.setDepth(6);
|
||||
this.upgradeDetails.add(centerToEdgeLine);
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: this.centerToEdgeLine,
|
||||
targets: 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){
|
||||
this.upgradeTower(tower)
|
||||
const intUpgrade = this.scene.add.image(tower.x + 100, tower.y, 'intUpgrade')
|
||||
.setDepth(12)
|
||||
.setTint(0xAAAAAA)
|
||||
.setOrigin(0, 0.5)
|
||||
.setScale(0)
|
||||
.setAlpha(0);
|
||||
this.upgradeDetails.add(intUpgrade);
|
||||
|
||||
this.upgradeCost = TOWERS_CONFIG[tower.props.type][nextLevel].cost;
|
||||
|
||||
this.upgradeText = this.scene.add.text(tower.x +175, tower.y - 50, `Upgrade: ${this.upgradeCost}`, {
|
||||
fontFamily: 'neuropol, arial',
|
||||
fontSize: '32px',
|
||||
fill: '#ffd900ff',
|
||||
stroke: '#c48f00ff',
|
||||
strokeThickness: 2,
|
||||
shadow: {
|
||||
offsetX: 5,
|
||||
offsetY: 5,
|
||||
color: '#000000',
|
||||
blur: 5,
|
||||
stroke: false,
|
||||
fill: true
|
||||
}
|
||||
}).setDepth(13).setAlpha(0).setInteractive();
|
||||
this.upgradeDetails.add(this.upgradeText);
|
||||
|
||||
if (currentLevel === 'level3') upgradeText.setText('Max Upgrade').disableInteractive();
|
||||
|
||||
const upgradeCancelText = this.scene.add.text(tower.x +175, tower.y + 25, `Cancel`, {
|
||||
fontFamily: 'neuropol, arial',
|
||||
fontSize: '32px',
|
||||
fill: '#ff0000ff',
|
||||
stroke: '#c40000ff',
|
||||
strokeThickness: 2,
|
||||
shadow: {
|
||||
offsetX: 5,
|
||||
offsetY: 5,
|
||||
color: '#000000',
|
||||
blur: 5,
|
||||
stroke: false,
|
||||
fill: true
|
||||
}
|
||||
}).setDepth(13).setAlpha(0).setInteractive();
|
||||
this.upgradeDetails.add(upgradeCancelText);
|
||||
|
||||
upgradeCancelText.on('pointerdown', () => {
|
||||
this.closeUpgradeMenu();
|
||||
});
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets:[intUpgrade, this.upgradeText, upgradeCancelText],
|
||||
scale: 1,
|
||||
alpha: 1,
|
||||
duration: 500
|
||||
});
|
||||
|
||||
this.upgradeText.on('pointerdown', () => {
|
||||
this.upgradeTower(tower);
|
||||
});
|
||||
|
||||
if (this.scene.UIScene.interfaceManager.gold < TOWERS_CONFIG[tower.props.type][nextLevel].cost) {
|
||||
this.disableUpgrade(this.upgradeText);
|
||||
}
|
||||
}
|
||||
|
||||
enableUpgrade(text) {
|
||||
text.setInteractive().setTint(0xFFFFFF);
|
||||
}
|
||||
|
||||
disableUpgrade(text) {
|
||||
text.disableInteractive().setTint(0xAAAAAA);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
});
|
||||
if (this.upgradeDetails.getBounds().contains(pointer.x, pointer.y)) {
|
||||
isOverTower = true;
|
||||
}
|
||||
return isOverTower;
|
||||
}
|
||||
|
||||
closeUpgradeMenu() {
|
||||
if (this.rangeCircle) {
|
||||
this.rangeCircle.destroy();
|
||||
this.rangeCircle = null;
|
||||
}
|
||||
|
||||
if (this.centerToEdgeLine) {
|
||||
this.centerToEdgeLine.destroy();
|
||||
this.centerToEdgeLine = null;
|
||||
}
|
||||
|
||||
if (this.upgradeDetails) {
|
||||
this.upgradeDetails.destroy();
|
||||
this.upgradeDetails = null;
|
||||
}
|
||||
this.selectedTower = null;
|
||||
}
|
||||
|
||||
upgradeTower(tower) {
|
||||
|
||||
this.closeUpgradeMenu();
|
||||
if (tower.props.level === 3) return;
|
||||
tower.props.level++;
|
||||
const newLevel = `level${tower.props.level}`
|
||||
tower.setTexture('towers', TOWERS_CONFIG[tower.props.type][newLevel].sprite);
|
||||
}
|
||||
this.scene.UIScene.removeGold(TOWERS_CONFIG[tower.props.type][newLevel].cost);
|
||||
}
|
||||
|
||||
update(time, delta) {
|
||||
// Iterate through all towers
|
||||
|
|
@ -175,6 +239,10 @@ export class TowerManager {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (this.upgradeDetails && this.upgradeCost <= this.scene.UIScene.interfaceManager.gold) {
|
||||
this.enableUpgrade(this.upgradeText);
|
||||
}
|
||||
}
|
||||
|
||||
attackTarget(tower, enemy) {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ export class UIScene extends Phaser.Scene {
|
|||
this.load.image('redArrow', 'assets/redArrow.png');
|
||||
this.load.image('intTop', 'assets/intTop.png');
|
||||
this.load.image('gold', 'assets/gold.png');
|
||||
this.load.image('intUpgrade', 'assets/intUpgrade.png');
|
||||
this.load.spritesheet('nextWave', 'assets/nextWave.png', {
|
||||
frameHeight: 150,
|
||||
frameWidth: 150
|
||||
|
|
|
|||
Loading…
Reference in New Issue