diff --git a/src/config/faction.js b/src/config/faction.js index 3699d7d..67e7c75 100644 --- a/src/config/faction.js +++ b/src/config/faction.js @@ -6,8 +6,10 @@ export const FACTION_CONFIG = { stats: { type: 'melee', health: 5, + speed: 50, attackMin: 1, attackMax: 4, + attackRate: 2000, meleeDefense: 1, rangeDefense: 2, magicDefense: 1, diff --git a/src/faction/factions.js b/src/faction/factions.js index c8c3577..9b2804e 100644 --- a/src/faction/factions.js +++ b/src/faction/factions.js @@ -21,15 +21,20 @@ export class Faction extends Phaser.GameObjects.Sprite { Object.entries(FACTION_CONFIG[faction][frame].stats).forEach(([key, value]) => { this.stats[key] = value; }); - console.log(this); + this.stats.fullHealth = this.stats.health; // Path following properties this.path = path; this.side = side; this.currentWaypoint = 0; - this.speed = 50; this.arrived = false; this.isPathPaused = false; + this.movingToEnemy = false; + this.enemy = false; + + // Timers + this.timerSight = 0; + this.timerAttack = 0; this.animKey = `${texture}-${frame}`; this.createAnim(); @@ -50,6 +55,15 @@ export class Faction extends Phaser.GameObjects.Sprite { frameRate: 2, repeat: -1 }); + this.scene.anims.create({ + key: `${this.animKey}-attack`, + frames: [ + { key: this.texture.key, frame: this.frame.name+2 }, + { key: this.texture.key, frame: this.frame.name+3 } + ], + frameRate: 2, + repeat: -1 + }); } } @@ -94,8 +108,8 @@ export class Faction extends Phaser.GameObjects.Sprite { // Set velocity based on angle and speed this.body.setVelocity( - Math.cos(angle) * this.speed, - Math.sin(angle) * this.speed + Math.cos(angle) * this.stats.speed, + Math.sin(angle) * this.stats.speed ); } } @@ -120,10 +134,104 @@ export class Faction extends Phaser.GameObjects.Sprite { this.setFlipX(false); // Moving left, flipped } } + + // Timers + this.timerSight += delta; + this.timerAttack += delta; // Move towards next waypoint if not arrived and path is not paused if (!this.arrived && !this.isPathPaused) { this.moveToWaypoint(this.currentWaypoint); } + + // Check distance to closest unit of the other side every second + if (this.timerSight >= 500 && this.movingToEnemy === false && this.enemy === false) { + this.timerSight = 0; + this.checkSight(); + } + + // Handle moving towards an enemy + if (this.movingToEnemy && this.movingToEnemy.active) { + const distance = Phaser.Math.Distance.Between(this.x, this.y, this.movingToEnemy.x, this.movingToEnemy.y); + if (distance <= this.stats.range) { + this.enemy = this.movingToEnemy; + this.movingToEnemy = false; + this.body.setVelocity(0, 0); + this.play(`${this.animKey}-attack`, true); + } + } + else if (this.movingToEnemy !== false) { + this.movingToEnemy = false; + this.resumePath(); + } + + // Attack + if (this.enemy && this.enemy.active && this.timerAttack >= 2000) { + this.timerAttack = 0; + console.log('attack'); + this.attack(); + } + } + + checkSight() { + let enemyGroup; + if (this.side === 'left') { + enemyGroup = this.scene.factionRight; + } else { + enemyGroup = this.scene.factionLeft; + } + + if (!enemyGroup) return; + + let closestDistance = Infinity; + let closestEnemy = null; + + // Find the closest enemy unit + enemyGroup.children.iterate((enemy) => { + if (enemy && enemy !== this) { + const distance = Phaser.Math.Distance.Between(this.x, this.y, enemy.x, enemy.y); + if (distance < closestDistance) { + closestDistance = distance; + closestEnemy = enemy; + } + } + }); + + if (closestEnemy && closestDistance <= this.stats.sight) { + this.pausePath(); + this.movingToEnemy = closestEnemy; + + const angle = Phaser.Math.Angle.Between(this.x, this.y, closestEnemy.x, closestEnemy.y); + const speed = this.stats.speed; + + this.body.setVelocity( + Math.cos(angle) * speed, + Math.sin(angle) * speed + ); + } + } + + attack() { + if (this.stats.type === 'melee' && this.enemy && this.enemy.active) { + const status = this.enemy.takeDamage('melee', Phaser.Math.Between(this.stats.attackMin, this.stats.attackMax)); + if (status === 'dead') { + this.resumePath(); + } + } + } + + takeDamage(type, amount) { + const defense = this.stats[`${type}Defense`]; + const damage = Math.max(0, amount - defense); + this.stats.health -= damage; + + // Check if unit is dead + if (this.stats.health <= 0) { + this.destroy(); + return 'dead'; + } + else { + return 'alive'; + } } } \ No newline at end of file diff --git a/src/scenes/level.js b/src/scenes/level.js index 8c8168e..83e3244 100644 --- a/src/scenes/level.js +++ b/src/scenes/level.js @@ -39,9 +39,6 @@ export class Level extends Phaser.Scene { const test = new Faction(this, 4*64, 5*64, 'dark-ages', 0, 'left', 1, 'dark-ages').setOrigin(0.5); const test2 = new Faction(this, 27*64, 4*64, 'dark-ages', 0, 'right', 1, 'dark-ages').setOrigin(0.5); - - // Add collision detection - this.physics.add.overlap(this.factionLeft, this.factionRight, this.handleFactionCollision, null, this); } update(time, delta) { @@ -58,52 +55,6 @@ export class Level extends Phaser.Scene { }); } - handleFactionCollision(faction1, faction2) { - // Check if factions are on opposite sides - if (faction1.side !== faction2.side) { - // Calculate distance between factions - const distance = Phaser.Math.Distance.Between(faction1.x, faction1.y, faction2.x, faction2.y); - - // If within attack range - if (distance < 150) { - // Pause path following and move towards each other - faction1.pausePath(); - faction2.pausePath(); - - // Move towards each other - const angle = Phaser.Math.Angle.Between(faction1.x, faction1.y, faction2.x, faction2.y); - const speed = 50; - - faction1.body.setVelocity( - Math.cos(angle) * speed, - Math.sin(angle) * speed - ); - - faction2.body.setVelocity( - Math.cos(angle + Math.PI) * speed, - Math.sin(angle + Math.PI) * speed - ); - - // Flip sprites based on movement direction - if (faction1.body.velocity.x > 0) { - faction1.setFlipX(true); - } else { - faction1.setFlipX(false); - } - - if (faction2.body.velocity.x > 0) { - faction2.setFlipX(true); - } else { - faction2.setFlipX(false); - } - } else { - // If they're not close enough, resume normal path following - faction1.resumePath(); - faction2.resumePath(); - } - } - } - onPointerDown(pointer) { this.isDragging = true; this.dragStartX = pointer.x; diff --git a/start_web.sh b/start_web.sh new file mode 100755 index 0000000..ed7b91a --- /dev/null +++ b/start_web.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Start a simple HTTP server on port 8000 +python3 -m http.server 8000 \ No newline at end of file