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);
|
this.platformsLayer = this.levelMap.createLayer('platforms', terrainTiles);
|
||||||
|
|
||||||
// Add camera zoom functionality
|
// 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.addControls();
|
||||||
|
|
||||||
this.waveManager = new WaveManager(this, 1, 1);
|
this.waveManager = new WaveManager(this, 1, 1);
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ export class TowerManager {
|
||||||
this.lastFired = {}; // Track last fire time for each tower
|
this.lastFired = {}; // Track last fire time for each tower
|
||||||
this.following = {};
|
this.following = {};
|
||||||
this.selectedTower = null;
|
this.selectedTower = null;
|
||||||
|
this.upgradeCost = null;
|
||||||
|
|
||||||
this.createAnims();
|
this.createAnims();
|
||||||
|
|
||||||
|
|
@ -38,6 +39,7 @@ export class TowerManager {
|
||||||
tower.setInteractive();
|
tower.setInteractive();
|
||||||
tower.on('pointerdown', () => {
|
tower.on('pointerdown', () => {
|
||||||
if (!this.selectedTower) {
|
if (!this.selectedTower) {
|
||||||
|
console.log('CLICK');
|
||||||
this.upgradeMenu(tower);
|
this.upgradeMenu(tower);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -52,64 +54,126 @@ export class TowerManager {
|
||||||
|
|
||||||
upgradeMenu(tower) {
|
upgradeMenu(tower) {
|
||||||
this.selectedTower = tower;
|
this.selectedTower = tower;
|
||||||
const camera = this.scene.cameras.main;
|
const currentLevel = `level${tower.props.level}`;
|
||||||
const towerLocX = tower.x - camera.scrollX;
|
const nextLevel = currentLevel === 'level3' ? 'level3' : `level${tower.props.level + 1}`;
|
||||||
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)
|
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)
|
.setOrigin(0.5)
|
||||||
.setDepth(5);
|
.setDepth(5);
|
||||||
// Add a line from center to edge of range circle
|
this.upgradeDetails.add(rangeCircle);
|
||||||
this.centerToEdgeLine = this.scene.add.line(tower.x, tower.y, 0, 0, TOWERS_CONFIG[tower.props.type].level1.range, 0, 0x00ff00)
|
|
||||||
|
const centerToEdgeLine = this.scene.add.line(tower.x, tower.y, 0, 0, TOWERS_CONFIG[tower.props.type][currentLevel].range, 0, 0x00ff00)
|
||||||
.setOrigin(0)
|
.setOrigin(0)
|
||||||
.setDepth(6);
|
.setDepth(6);
|
||||||
|
this.upgradeDetails.add(centerToEdgeLine);
|
||||||
|
|
||||||
this.scene.tweens.add({
|
this.scene.tweens.add({
|
||||||
targets: this.centerToEdgeLine,
|
targets: centerToEdgeLine,
|
||||||
angle: 360,
|
angle: 360,
|
||||||
duration: 8000,
|
duration: 8000,
|
||||||
repeat: -1
|
repeat: -1
|
||||||
});
|
});
|
||||||
console.log('here');
|
|
||||||
|
|
||||||
// TODO: update this asap.
|
const intUpgrade = this.scene.add.image(tower.x + 100, tower.y, 'intUpgrade')
|
||||||
const nextLevel = `level${tower.props.level+1}`;
|
.setDepth(12)
|
||||||
if (this.scene.UIScene.interfaceManager.gold >= TOWERS_CONFIG[tower.props.type][nextLevel].cost){
|
.setTint(0xAAAAAA)
|
||||||
this.upgradeTower(tower)
|
.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) {
|
isPointerOverTower(pointer) {
|
||||||
// Check if pointer is over any tower
|
|
||||||
let isOverTower = false;
|
let isOverTower = false;
|
||||||
this.scene.towers.children.iterate((tower) => {
|
if (this.upgradeDetails.getBounds().contains(pointer.x, pointer.y)) {
|
||||||
if (tower.getBounds().contains(pointer.x, pointer.y)) {
|
isOverTower = true;
|
||||||
isOverTower = true;
|
}
|
||||||
return false; // Break iteration
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return isOverTower;
|
return isOverTower;
|
||||||
}
|
}
|
||||||
|
|
||||||
closeUpgradeMenu() {
|
closeUpgradeMenu() {
|
||||||
if (this.rangeCircle) {
|
if (this.upgradeDetails) {
|
||||||
this.rangeCircle.destroy();
|
this.upgradeDetails.destroy();
|
||||||
this.rangeCircle = null;
|
this.upgradeDetails = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.centerToEdgeLine) {
|
|
||||||
this.centerToEdgeLine.destroy();
|
|
||||||
this.centerToEdgeLine = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.selectedTower = null;
|
this.selectedTower = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
upgradeTower(tower) {
|
upgradeTower(tower) {
|
||||||
|
this.closeUpgradeMenu();
|
||||||
if (tower.props.level === 3) return;
|
if (tower.props.level === 3) return;
|
||||||
tower.props.level++;
|
tower.props.level++;
|
||||||
const newLevel = `level${tower.props.level}`
|
const newLevel = `level${tower.props.level}`
|
||||||
tower.setTexture('towers', TOWERS_CONFIG[tower.props.type][newLevel].sprite);
|
tower.setTexture('towers', TOWERS_CONFIG[tower.props.type][newLevel].sprite);
|
||||||
}
|
this.scene.UIScene.removeGold(TOWERS_CONFIG[tower.props.type][newLevel].cost);
|
||||||
|
}
|
||||||
|
|
||||||
update(time, delta) {
|
update(time, delta) {
|
||||||
// Iterate through all towers
|
// 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) {
|
attackTarget(tower, enemy) {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ export class UIScene extends Phaser.Scene {
|
||||||
this.load.image('redArrow', 'assets/redArrow.png');
|
this.load.image('redArrow', 'assets/redArrow.png');
|
||||||
this.load.image('intTop', 'assets/intTop.png');
|
this.load.image('intTop', 'assets/intTop.png');
|
||||||
this.load.image('gold', 'assets/gold.png');
|
this.load.image('gold', 'assets/gold.png');
|
||||||
|
this.load.image('intUpgrade', 'assets/intUpgrade.png');
|
||||||
this.load.spritesheet('nextWave', 'assets/nextWave.png', {
|
this.load.spritesheet('nextWave', 'assets/nextWave.png', {
|
||||||
frameHeight: 150,
|
frameHeight: 150,
|
||||||
frameWidth: 150
|
frameWidth: 150
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue