Add AOE tower support, implement flamethrower and cannon towers with animations, enhance tower targeting logic, and update tower configurations including damage types and ranges.
This commit is contained in:
parent
7180612aab
commit
37a292c022
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 232 KiB After Width: | Height: | Size: 366 KiB |
Binary file not shown.
|
|
@ -13,6 +13,10 @@ export class Level extends Phaser.Scene {
|
|||
preload() {
|
||||
this.load.tilemapTiledJSON('level1', 'assets/level1.json');
|
||||
this.load.image('terrain', 'assets/terrain.png');
|
||||
this.load.spritesheet('ammo', 'assets/ammo.png', {
|
||||
frameWidth: 50,
|
||||
frameHeight: 50
|
||||
});
|
||||
this.load.spritesheet('basic-enemies', 'assets/basic-enemies.png', {
|
||||
frameWidth: 50,
|
||||
frameHeight: 50
|
||||
|
|
@ -57,23 +61,23 @@ export class Level extends Phaser.Scene {
|
|||
}
|
||||
|
||||
addControls() {
|
||||
this.input.on('wheel', (pointer, gameObjects, deltaX, deltaY) => {
|
||||
const zoomSpeed = 0.1;
|
||||
if (deltaY < 0) {
|
||||
// Zoom in
|
||||
this.cameras.main.zoom += zoomSpeed;
|
||||
} else if (deltaY > 0) {
|
||||
// Zoom out
|
||||
this.cameras.main.zoom -= zoomSpeed;
|
||||
}
|
||||
// this.input.on('wheel', (pointer, gameObjects, deltaX, deltaY) => {
|
||||
// const zoomSpeed = 0.1;
|
||||
// if (deltaY < 0) {
|
||||
// // Zoom in
|
||||
// this.cameras.main.zoom += zoomSpeed;
|
||||
// } else if (deltaY > 0) {
|
||||
// // Zoom out
|
||||
// this.cameras.main.zoom -= zoomSpeed;
|
||||
// }
|
||||
|
||||
// Limit zoom range to prevent extreme zoom levels
|
||||
this.cameras.main.zoom = Phaser.Math.Clamp(this.cameras.main.zoom, 0.5, 2);
|
||||
// // Limit zoom range to prevent extreme zoom levels
|
||||
// this.cameras.main.zoom = Phaser.Math.Clamp(this.cameras.main.zoom, 0.5, 2);
|
||||
|
||||
// Zoom toward mouse position
|
||||
const worldPoint = this.input.activePointer.positionToCamera(this.cameras.main);
|
||||
this.cameras.main.centerOn(worldPoint.x, worldPoint.y);
|
||||
});
|
||||
// // Zoom toward mouse position
|
||||
// const worldPoint = this.input.activePointer.positionToCamera(this.cameras.main);
|
||||
// this.cameras.main.centerOn(worldPoint.x, worldPoint.y);
|
||||
// });
|
||||
|
||||
// Add camera panning functionality
|
||||
this.input.on('pointerdown', (pointer) => {
|
||||
|
|
|
|||
|
|
@ -256,10 +256,6 @@ export class InterfaceManager {
|
|||
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) {
|
||||
|
|
@ -367,6 +363,11 @@ export class InterfaceManager {
|
|||
const towerInteractive = this.scene.add.rectangle(0, 0, 200, 200, 0x000000, 0);
|
||||
this.selectedTower.add(towerInteractive);
|
||||
|
||||
const rangeCircle = this.scene.add.circle(0, 0, TOWERS_CONFIG[type].level1.range, 0xc0b15c, 0.2)
|
||||
.setOrigin(0.5)
|
||||
.setScrollFactor(0);
|
||||
this.selectedTower.add(rangeCircle);
|
||||
|
||||
const towerBase = this.scene.add.sprite(0, 0, 'towers', 7)
|
||||
.setOrigin(0.5)
|
||||
.setScrollFactor(0)
|
||||
|
|
@ -442,14 +443,15 @@ export class InterfaceManager {
|
|||
const tile = platformsLayer.getTileAt(tileX, tileY);
|
||||
if (tile) {
|
||||
this.selectedTower.iterate((child) => {
|
||||
if (child.type !== 'Rectangle') {
|
||||
child.setTint(0x89ff5b);
|
||||
if (child.type !== 'Rectangle' && child.type !== 'Arc') {
|
||||
child.setTint(0x48ff00);
|
||||
}
|
||||
});
|
||||
this.selectedTower.safe = true;
|
||||
} else {
|
||||
this.selectedTower.iterate((child) => {
|
||||
if (child.type !== 'Rectangle') {
|
||||
if (child.type !== 'Rectangle' && child.type !== 'Arc') {
|
||||
console.log(child.type);
|
||||
child.setTint(0xa32a00);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,56 +3,87 @@ export const TOWERS_CONFIG = {
|
|||
'name': 'Gatlin Gun',
|
||||
'cost': 100,
|
||||
'spriteStart': 0,
|
||||
'type': 'direct',
|
||||
'aoe': 0,
|
||||
'dmgType': 'direct',
|
||||
'level1': {
|
||||
'dmgLow': 10,
|
||||
'dmgHigh': 30,
|
||||
'rate': 2000,
|
||||
'duration': 500,
|
||||
'range': 275
|
||||
'range': 300
|
||||
},
|
||||
'level2': {
|
||||
'dmgLow': 15,
|
||||
'dmgHigh': 35,
|
||||
'rate': 1500,
|
||||
'duration': 750,
|
||||
'range': 300
|
||||
'range': 350
|
||||
},
|
||||
'level3': {
|
||||
'dmgLow': 25,
|
||||
'dmgHigh': 50,
|
||||
'rate': 1000,
|
||||
'duration': 1000,
|
||||
'range': 325
|
||||
'range': 400
|
||||
}
|
||||
},
|
||||
'cannon': {
|
||||
'name': 'Cannon',
|
||||
'cost': 200,
|
||||
'spriteStart': 10,
|
||||
'type': 'aoe',
|
||||
'aoe': 50,
|
||||
'dmgType': 'aoe',
|
||||
'level1': {
|
||||
'dmgLow': 15,
|
||||
'dmgHigh': 35,
|
||||
'rate': 2000,
|
||||
'rate': 2500,
|
||||
'duration': 200,
|
||||
'range': 400
|
||||
'range': 400,
|
||||
'aoe': 50,
|
||||
},
|
||||
'level2': {
|
||||
'dmgLow': 25,
|
||||
'dmgHigh': 45,
|
||||
'rate': 2000,
|
||||
'rate': 2500,
|
||||
'duration': 500,
|
||||
'range': 450
|
||||
'range': 450,
|
||||
'aoe': 25,
|
||||
},
|
||||
'level3': {
|
||||
'dmgLow': 35,
|
||||
'dmgHigh': 65,
|
||||
'rate': 2000,
|
||||
'rate': 2500,
|
||||
'duration': 500,
|
||||
'range': 500
|
||||
'range': 500,
|
||||
'aoe': 25,
|
||||
}
|
||||
},
|
||||
'flame': {
|
||||
'name': 'Flamethrower',
|
||||
'cost': 150,
|
||||
'spriteStart': 20,
|
||||
'dmgType': 'aoe',
|
||||
'level1': {
|
||||
'dmgLow': 1,
|
||||
'dmgHigh': 5,
|
||||
'rate': 1000,
|
||||
'duration': 1000,
|
||||
'range': 300,
|
||||
'aoe': 100,
|
||||
},
|
||||
'level2': {
|
||||
'dmgLow': 3,
|
||||
'dmgHigh': 8,
|
||||
'rate': 1000,
|
||||
'duration': 1000,
|
||||
'range': 350,
|
||||
'aoe': 100,
|
||||
},
|
||||
'level3': {
|
||||
'dmgLow': 5,
|
||||
'dmgHigh': 12,
|
||||
'rate': 1000,
|
||||
'duration': 1000,
|
||||
'range': 400,
|
||||
'aoe': 100,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -89,13 +89,19 @@ export class TowerManager {
|
|||
});
|
||||
|
||||
this.following[tower.id] = furthestEnemy.props.id;
|
||||
this.attackTarget(tower, furthestEnemy);
|
||||
const dmgType = TOWERS_CONFIG[tower.props.type].dmgType;
|
||||
if (dmgType === 'aoe') {
|
||||
this.aoeAttackTarget(tower, furthestEnemy);
|
||||
} else {
|
||||
this.attackTarget(tower, furthestEnemy);
|
||||
}
|
||||
|
||||
this.lastFired[tower.id] = time;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
attackTarget(tower, enemy) {
|
||||
// Tower Properties
|
||||
const type = tower.props.type;
|
||||
|
|
@ -121,11 +127,98 @@ export class TowerManager {
|
|||
|
||||
if (enemy.props.health > 0) {
|
||||
this.createHealthBar(enemy);
|
||||
if (type === 'gun') {
|
||||
const gunfire = this.scene.physics.add.sprite(enemy.x, enemy.y, 'ammo', 0);
|
||||
gunfire.play('gunfire');
|
||||
gunfire.setVelocity(enemy.body.velocity.x, enemy.body.velocity.y);
|
||||
this.scene.time.delayedCall(config.duration, () => {
|
||||
gunfire.destroy();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.destroyEnemy(enemy, tower);
|
||||
}
|
||||
}
|
||||
|
||||
aoeAttackTarget(tower, enemy) {
|
||||
// Tower Properties
|
||||
const type = tower.props.type;
|
||||
const level = 'level'+tower.props.level;
|
||||
const config = TOWERS_CONFIG[type][level];
|
||||
const duration = TOWERS_CONFIG[type][level].duration;
|
||||
|
||||
if (!config) return;
|
||||
|
||||
const dmgLow = config.dmgLow;
|
||||
const dmgHigh = config.dmgHigh;
|
||||
|
||||
const angle = Phaser.Math.Angle.Between(tower.x, tower.y, enemy.x, enemy.y);
|
||||
tower.rotation = angle;
|
||||
|
||||
if (type === 'cannon') {
|
||||
const projDistance = 50;
|
||||
const projX = tower.x + Math.cos(angle) * projDistance;
|
||||
const projY = tower.y + Math.sin(angle) * projDistance;
|
||||
const projectile = this.scene.add.sprite(projX, projY, 'ammo', 3);
|
||||
this.scene.tweens.add({
|
||||
targets: projectile,
|
||||
x: enemy.x,
|
||||
y: enemy.y,
|
||||
duration: 100,
|
||||
onComplete: () => {
|
||||
projectile.setTexture('ammo', 4);
|
||||
this.scene.time.delayedCall(200, () => {
|
||||
projectile.destroy();
|
||||
});
|
||||
}
|
||||
});
|
||||
tower.play(`${type}-${level}-fire`, { 'duration': duration });
|
||||
}
|
||||
|
||||
if (type === 'flame') {
|
||||
const projDistance = 185;
|
||||
const projDistance2 = 220;
|
||||
const projX = tower.x + Math.cos(angle) * projDistance;
|
||||
const projY = tower.y + Math.sin(angle) * projDistance;
|
||||
const proj2X = tower.x + Math.cos(angle) * projDistance2;
|
||||
const proj2Y = tower.y + Math.sin(angle) * projDistance2;
|
||||
const projectile = this.scene.add.sprite(projX, projY, 'towers', 23).setScale(1.5).setAlpha(.5);
|
||||
projectile.rotation = angle;
|
||||
projectile.play(`flamethrower`);
|
||||
this.scene.tweens.add({
|
||||
targets: projectile,
|
||||
x: proj2X,
|
||||
y: proj2Y,
|
||||
duration:1000,
|
||||
onComplete: () => {
|
||||
projectile.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Calculate damage (random between low and high)
|
||||
const damage = Phaser.Math.Between(dmgLow, dmgHigh);
|
||||
|
||||
// Get AOE distance
|
||||
const aoeDistance = config.aoe;
|
||||
|
||||
// Apply damage to all enemies in range
|
||||
const enemiesInRange = this.scene.enemies.getChildren().filter(e => {
|
||||
return Phaser.Math.Distance.Between(e.x, e.y, enemy.x, enemy.y) <= aoeDistance;
|
||||
});
|
||||
|
||||
enemiesInRange.forEach(targetEnemy => {
|
||||
targetEnemy.props.health -= damage;
|
||||
|
||||
if (targetEnemy.props.health > 0) {
|
||||
this.createHealthBar(targetEnemy);
|
||||
} else {
|
||||
this.destroyEnemy(targetEnemy, tower);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
createHealthBar(enemy) {
|
||||
const barWidth = 30;
|
||||
const barHeight = 5;
|
||||
|
|
@ -230,6 +323,15 @@ export class TowerManager {
|
|||
}
|
||||
|
||||
createAnims() {
|
||||
this.scene.anims.create({
|
||||
key: 'gunfire',
|
||||
frames: this.scene.anims.generateFrameNumbers('ammo', {
|
||||
start:0,
|
||||
end:2
|
||||
}),
|
||||
framerate: 15,
|
||||
repeat: -1
|
||||
});
|
||||
this.scene.anims.create({
|
||||
key: 'gun-level1-fire',
|
||||
frames: this.scene.anims.generateFrameNumbers('towers', {
|
||||
|
|
@ -237,7 +339,7 @@ export class TowerManager {
|
|||
end: 1,
|
||||
}),
|
||||
frameRate: 15,
|
||||
repeat: 5,
|
||||
repeat: 6,
|
||||
yoyo: true
|
||||
});
|
||||
this.scene.anims.create({
|
||||
|
|
@ -263,12 +365,20 @@ export class TowerManager {
|
|||
this.scene.anims.create({
|
||||
key: 'cannon-level1-fire',
|
||||
frames: this.scene.anims.generateFrameNumbers('towers', {
|
||||
start: 10,
|
||||
end: 11
|
||||
start: 11,
|
||||
end: 10
|
||||
}),
|
||||
frameRate:3,
|
||||
repeat: 0,
|
||||
yoyo: true
|
||||
frameRate: 5,
|
||||
repeat: 0
|
||||
});
|
||||
this.scene.anims.create({
|
||||
key: 'flamethrower',
|
||||
frames: this.scene.anims.generateFrameNumbers('towers', {
|
||||
start: 23,
|
||||
end:25
|
||||
}),
|
||||
framerate: 4,
|
||||
repeat: -1
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue