462 lines
16 KiB
JavaScript
462 lines
16 KiB
JavaScript
import { TOWERS_CONFIG } from './towerConfig.js';
|
|
|
|
export class InterfaceManager {
|
|
|
|
constructor(scene) {
|
|
this.scene = scene;
|
|
this.gold = 150;
|
|
this.cores = 20;
|
|
this.interfaceOpen = false;
|
|
this.selectedTower = false;
|
|
this.selectedTowerPos = {
|
|
x: 0,
|
|
y: 0
|
|
}
|
|
|
|
this.paintInterface();
|
|
}
|
|
|
|
paintInterface() {
|
|
this.intTop = this.scene.add.image(1300, -50, 'intTop').setOrigin(0.5).setScrollFactor(0);
|
|
this.intCore = this.scene.add.sprite(1320, 60, 'towers', 9).setScale(.50).setOrigin(0.5).setScrollFactor(0).setAlpha(0);
|
|
|
|
// Add gold text display
|
|
this.goldText = this.scene.add.text(1200, 25, `${this.gold}`, {
|
|
fontFamily: 'neuropol, arial',
|
|
fontSize: '36px',
|
|
fill: '#ffd900ff',
|
|
stroke: '#c48f00ff',
|
|
strokeThickness: 2,
|
|
shadow: {
|
|
offsetX: 5,
|
|
offsetY: 5,
|
|
color: '#000000',
|
|
blur: 5,
|
|
stroke: false,
|
|
fill: true
|
|
}
|
|
}).setScrollFactor(0).setAlpha(0);
|
|
|
|
this.coreText = this.scene.add.text(1350, 25, `${this.cores}`, {
|
|
fontFamily: 'neuropol, arial',
|
|
fontSize: '36px',
|
|
fill: '#00eeffff',
|
|
stroke: '#2a338aff',
|
|
strokeThickness: 2,
|
|
shadow: {
|
|
offsetX: 5,
|
|
offsetY: 5,
|
|
color: '#000000',
|
|
blur: 5,
|
|
stroke: false,
|
|
fill: true
|
|
}
|
|
}).setScrollFactor(0).setAlpha(0);
|
|
|
|
this.scene.tweens.add({
|
|
targets: this.intTop,
|
|
y: 50,
|
|
duration: 500,
|
|
delay: 500,
|
|
ease: 'Back.easeOut',
|
|
onComplete: () => {
|
|
this.scene.tweens.add({
|
|
targets: [this.coreText, this.goldText, this.intCore],
|
|
angle: 360,
|
|
alpha: 1,
|
|
duration: 500,
|
|
onComplete: () => {
|
|
this.scene.tweens.add({
|
|
targets: this.intCore,
|
|
angle: 360,
|
|
duration: 5000,
|
|
repeat: -1
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
this.intMain = this.scene.add.image(800, 1300, 'intMain').setOrigin(0.5).setScrollFactor(0);
|
|
// NOTE ^^ Fully up is at Y 475
|
|
|
|
// Add gold text display
|
|
this.interfaceText = this.scene.add.text(800, 850, `Click to Open`, {
|
|
fontFamily: 'neuropol, arial',
|
|
fontSize: '36px',
|
|
fill: '#ff5353ff',
|
|
stroke: '#581a1aff',
|
|
strokeThickness: 2,
|
|
shadow: {
|
|
offsetX: 5,
|
|
offsetY: 5,
|
|
color: '#000000',
|
|
blur: 5,
|
|
stroke: false,
|
|
fill: true
|
|
}
|
|
}).setOrigin(0.5).setScrollFactor(0).setAlpha(0);
|
|
|
|
this.upLeft = this.scene.add.image(650, 850, 'redArrow').setOrigin(0.5).setScale(0.25).setAlpha(0);
|
|
this.upRight = this.scene.add.image(950, 850, 'redArrow').setOrigin(0.5).setScale(0.25).setAlpha(0);
|
|
|
|
this.scene.tweens.add({
|
|
targets: this.intMain,
|
|
y: 1150,
|
|
duration: 500,
|
|
delay: 500,
|
|
ease: 'Back.easeOut',
|
|
onComplete: () => {
|
|
this.scene.tweens.add({
|
|
targets: [this.interfaceText, this.upLeft, this.upRight],
|
|
alpha: 1,
|
|
duration: 500,
|
|
onComplete: () => {
|
|
this.scene.tweens.add({
|
|
targets: [this.upLeft, this.upRight],
|
|
y: { from: 860, to: 840},
|
|
duration: 2000,
|
|
repeat: -1
|
|
})
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
this.interfaceUp = this.scene.add.rectangle(800, 840, 800, 120, 0x000000, 0).setOrigin(0.5);
|
|
this.interfaceUp.setInteractive();
|
|
this.interfaceUp.on('pointerdown', () => {
|
|
if (!this.interfaceOpen) {
|
|
this.openInterface();
|
|
// Disable further clicks
|
|
this.interfaceUp.disableInteractive();
|
|
} else {
|
|
this.closeInterface();
|
|
this.interfaceUp.disableInteractive();
|
|
}
|
|
});
|
|
|
|
// Next Wave Button
|
|
this.waveStart = this.scene.add.container().setScrollFactor(0);
|
|
const nextWaveBack = this.scene.add.rectangle(1250, 200, 235, 100, 0x000000, 1).setOrigin(0, 0.5).setScrollFactor(0);
|
|
this.buttonBack = this.scene.add.sprite(1250, 200, 'nextWave', 0).setOrigin(0.5).setScrollFactor(0);
|
|
this.buttonBack.on('pointerdown', () => {
|
|
const waveManager = this.scene.levelScene.waveManager
|
|
waveManager.waveActive = true;
|
|
waveManager.nextWave();
|
|
this.hideNextWave();
|
|
})
|
|
const button = this.scene.add.sprite(1250, 200, 'nextWave', 1).setOrigin(0.5).setScrollFactor(0);
|
|
button.preFX.addGlow(0xffd900, 10);
|
|
const nextWaveText = this.scene.add.text(1300, 200, 'Start\nNext Wave', {
|
|
fontFamily: 'neuropol, arial',
|
|
fontSize: '28px',
|
|
fill: '#ffd900ff',
|
|
stroke: '#c48f00ff',
|
|
strokeThickness: 2,
|
|
shadow: {
|
|
offsetX: 5,
|
|
offsetY: 5,
|
|
color: '#000000',
|
|
blur: 5,
|
|
stroke: false,
|
|
fill: true
|
|
}
|
|
}).setOrigin(0, 0.5).setScrollFactor(0);
|
|
|
|
this.scene.tweens.add({
|
|
targets: this.buttonBack,
|
|
angle: -360,
|
|
duration: 20000,
|
|
repeat: -1
|
|
})
|
|
this.scene.tweens.add({
|
|
targets: button.preFX.list[0],
|
|
outerStrength: 0,
|
|
duration: 2000,
|
|
yoyo: true,
|
|
repeat: -1
|
|
});
|
|
|
|
this.waveStart.add(nextWaveBack);
|
|
this.waveStart.add(this.buttonBack);
|
|
this.waveStart.add(button);
|
|
this.waveStart.add(nextWaveText);
|
|
this.waveStart.setAlpha(0);
|
|
}
|
|
|
|
hideNextWave() {
|
|
this.buttonBack.disableInteractive()
|
|
this.scene.tweens.add({
|
|
targets: this.waveStart,
|
|
alpha: 0,
|
|
duration: 500
|
|
});
|
|
}
|
|
|
|
showNextWave() {
|
|
this.buttonBack.setInteractive()
|
|
this.scene.tweens.add({
|
|
targets: this.waveStart,
|
|
alpha: 1,
|
|
duration: 1000
|
|
});
|
|
}
|
|
|
|
openInterface() {
|
|
this.interfaceOpen = true;
|
|
this.upLeft.setAlpha(0).setRotation(Math.PI);
|
|
this.upRight.setAlpha(0).setRotation(Math.PI);
|
|
this.interfaceText.setAlpha(0).setText('Click to Close');
|
|
this.scene.tweens.add({
|
|
targets: this.intMain,
|
|
y: {from: 1150, to: 475},
|
|
duration: 500,
|
|
ease: 'Quant',
|
|
onComplete: () => {
|
|
this.upLeft.setAlpha(1);
|
|
this.upRight.setAlpha(1);
|
|
this.interfaceText.setAlpha(1);
|
|
this.interfaceUp.setInteractive();
|
|
this.showTowers();
|
|
}
|
|
});
|
|
}
|
|
|
|
closeInterface() {
|
|
this.interfaceOpen = false;
|
|
this.upLeft.setAlpha(0).setRotation(0);
|
|
this.upRight.setAlpha(0).setRotation(0);
|
|
this.interfaceText.setAlpha(0).setText('Click to Open');
|
|
this.towerDisplay.destroy();
|
|
this.scene.tweens.add({
|
|
targets: this.intMain,
|
|
y: {from: 475, to: 1150},
|
|
duration: 500,
|
|
ease: 'Quant',
|
|
onComplete: () => {
|
|
this.upLeft.setAlpha(1);
|
|
this.upRight.setAlpha(1);
|
|
this.interfaceText.setAlpha(1);
|
|
this.interfaceUp.setInteractive();
|
|
}
|
|
});
|
|
}
|
|
|
|
showTowers() {
|
|
this.towerDisplay = this.scene.add.container();
|
|
let x = 0;
|
|
let y = 0;
|
|
for (const type in TOWERS_CONFIG) {
|
|
const tower = TOWERS_CONFIG[type];
|
|
this.gridAdd(x, y, tower.name, tower.cost, type);
|
|
x++;
|
|
if (x > 6) {
|
|
y = 2;
|
|
x = 0;
|
|
}
|
|
}
|
|
// this.gridAdd(0, 0, 'Gatlin Gun', 100, 'gun');
|
|
// this.gridAdd(0, 1, 'Flamethrower', 150, 'gun');
|
|
// this.gridAdd(1, 0, 'Laser', 200, 'gun');
|
|
// this.gridAdd(1, 1, 'Cannon', 200, 'cannon');
|
|
}
|
|
|
|
gridAdd(x, y, text, cost, type) {
|
|
const xAdd = 325;
|
|
const yAdd = 375;
|
|
const startX = (x * 225) + xAdd;
|
|
const startY = (y * 225) + yAdd;
|
|
|
|
const slot = this.scene.add.container();
|
|
slot.props = {
|
|
cost: cost
|
|
}
|
|
|
|
const slotBack = this.scene.add.rectangle(startX, startY, 200, 200, 0xAAAAAA, 0.5)
|
|
.setOrigin(0.5)
|
|
.setScrollFactor(0);
|
|
slot.add(slotBack);
|
|
//slotBack.setInteractive();
|
|
slotBack.on('pointerdown', () => {
|
|
this.selectTower(type);
|
|
});
|
|
|
|
// Add gold text display
|
|
const slotText = this.scene.add.text(startX-95, startY+75, `${text}`, {
|
|
fontFamily: 'neuropol, arial',
|
|
fontSize: '25px',
|
|
fill: '#ffffffff',
|
|
stroke: '#5f4719ff',
|
|
strokeThickness: 2,
|
|
shadow: {
|
|
offsetX: 2,
|
|
offsetY: 2,
|
|
color: '#000000',
|
|
blur: 5,
|
|
stroke: false,
|
|
fill: true
|
|
}
|
|
}).setOrigin(0).setScrollFactor(0);
|
|
slot.add(slotText);
|
|
|
|
// Add gold text display
|
|
const slotCost = this.scene.add.text(startX+100, startY-100, `Gold: ${cost}`, {
|
|
fontFamily: 'neuropol, arial',
|
|
fontSize: '25px',
|
|
fill: '#ffd900ff',
|
|
stroke: '#c48f00ff',
|
|
strokeThickness: 2,
|
|
shadow: {
|
|
offsetX: 2,
|
|
offsetY: 2,
|
|
color: '#000000',
|
|
blur: 5,
|
|
stroke: false,
|
|
fill: true
|
|
}
|
|
}).setOrigin(1, 0).setScrollFactor(0);
|
|
slot.add(slotCost);
|
|
|
|
const towerBase = this.scene.add.sprite(startX, startY, 'towers', 7)
|
|
.setOrigin(0.5)
|
|
.setScrollFactor(0);
|
|
slot.add(towerBase);
|
|
|
|
const towerTop = this.scene.add.sprite(startX, startY, 'towers', TOWERS_CONFIG[type].spriteStart)
|
|
.setOrigin(0.5)
|
|
.setScrollFactor(0);
|
|
slot.add(towerTop);
|
|
|
|
this.towerDisplay.add(slot);
|
|
this.updateTowerAvail();
|
|
}
|
|
|
|
updateTowerAvail() {
|
|
if (this.interfaceOpen === true && this.towerDisplay) {
|
|
this.towerDisplay.iterate((slot) => {
|
|
// Not Enough Gold
|
|
if (slot.props.cost > this.gold) {
|
|
slot.iterate((child) => {
|
|
if (child.type === 'Rectangle') {
|
|
child.disableInteractive();
|
|
child.setFillStyle(0x333333);
|
|
} else {
|
|
child.setTint(0x888888);
|
|
}
|
|
});
|
|
}
|
|
// Is Enough Gold
|
|
else {
|
|
slot.iterate((child) => {
|
|
if (child.type === 'Rectangle') {
|
|
child.setInteractive();
|
|
child.setFillStyle(0xAAAAAA);
|
|
} else {
|
|
child.setTint(0xFFFFFF);
|
|
}
|
|
});
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
selectTower(type) {
|
|
this.selectedTower = this.scene.levelScene.add.container();
|
|
|
|
const towerInteractive = this.scene.add.rectangle(0, 0, 200, 200, 0x000000, 0);
|
|
this.selectedTower.add(towerInteractive);
|
|
|
|
const towerBase = this.scene.add.sprite(0, 0, 'towers', 7)
|
|
.setOrigin(0.5)
|
|
.setScrollFactor(0)
|
|
.setTint(0xa32a00);
|
|
this.selectedTower.add(towerBase);
|
|
|
|
const towerTop = this.scene.add.sprite(0, 0, 'towers', TOWERS_CONFIG[type].spriteStart)
|
|
.setOrigin(0.5)
|
|
.setScrollFactor(0)
|
|
.setTint(0xa32a00);
|
|
this.selectedTower.add(towerTop);
|
|
|
|
towerInteractive.on('pointerdown', () => {
|
|
this.placeTower(type);
|
|
});
|
|
towerInteractive.setInteractive();
|
|
|
|
this.closeInterface();
|
|
}
|
|
|
|
placeTower(type) {
|
|
if (this.selectedTower.safe === true) {
|
|
//Bring up Next Wave on first tower:
|
|
if (this.scene.levelScene.towers.countActive() === 0) {
|
|
this.showNextWave();
|
|
}
|
|
|
|
// Snap to current mouse position
|
|
const levelCam = this.scene.levelScene.cameras.main;
|
|
const mouse = this.scene.input.activePointer;
|
|
const worldX = mouse.position.x + levelCam.scrollX;
|
|
const worldY = mouse.position.y + levelCam.scrollY;
|
|
|
|
// Convert world coordinates to tile coordinates
|
|
const tileX = Math.floor(worldX / 200); // Assuming 200px tile width
|
|
const tileY = Math.floor(worldY / 200); // Assuming 200px tile height
|
|
|
|
this.scene.levelScene.towerManager.createTower(type, tileX, tileY);
|
|
this.scene.removeGold(TOWERS_CONFIG[type].cost);
|
|
}
|
|
|
|
// Clear Tower Selection Regardless
|
|
this.selectedTower.destroy();
|
|
this.selectedTower = false;
|
|
}
|
|
|
|
update(time, delta) {
|
|
if (this.selectedTower) {
|
|
// Snap to current mouse position
|
|
const levelCam = this.scene.levelScene.cameras.main;
|
|
const mouse = this.scene.input.activePointer;
|
|
const worldX = mouse.position.x + levelCam.scrollX;
|
|
const worldY = mouse.position.y + levelCam.scrollY;
|
|
|
|
// Convert world coordinates to tile coordinates
|
|
const tileX = Math.floor(worldX / 200); // Assuming 200px tile width
|
|
const tileY = Math.floor(worldY / 200); // Assuming 200px tile height
|
|
|
|
if (tileX !== this.selectedTowerPos.x || tileY !== this.selectedTowerPos.y) {
|
|
this.selectedTowerPos = {
|
|
x: tileX,
|
|
y: tileY
|
|
};
|
|
|
|
// Convert back to world position for proper snapping
|
|
const snappedX = tileX * 200 + 100 - levelCam.scrollX; // Center the tower on the tile (assuming 200px tiles)
|
|
const snappedY = tileY * 200 + 100 - levelCam.scrollY;
|
|
|
|
this.selectedTower.setPosition(snappedX, snappedY);
|
|
|
|
const platformsLayer = this.scene.levelScene.platformsLayer;
|
|
if (platformsLayer) {
|
|
const tile = platformsLayer.getTileAt(tileX, tileY);
|
|
if (tile) {
|
|
this.selectedTower.iterate((child) => {
|
|
if (child.type !== 'Rectangle') {
|
|
child.setTint(0x89ff5b);
|
|
}
|
|
});
|
|
this.selectedTower.safe = true;
|
|
} else {
|
|
this.selectedTower.iterate((child) => {
|
|
if (child.type !== 'Rectangle') {
|
|
child.setTint(0xa32a00);
|
|
}
|
|
});
|
|
this.selectedTower.safe = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |