151 lines
4.6 KiB
JavaScript
151 lines
4.6 KiB
JavaScript
export class Player extends Phaser.GameObjects.Sprite {
|
|
constructor(scene, x, y) {
|
|
super(scene, x, y, 'player');
|
|
|
|
// Add to scene
|
|
scene.add.existing(this);
|
|
scene.physics.world.enable(this);
|
|
this.body.setCollideWorldBounds(true);
|
|
this.body.setSize(50,100);
|
|
|
|
// Set player properties
|
|
this.speed = 200;
|
|
this.isMoving = false;
|
|
this.targetX = x;
|
|
this.targetY = y;
|
|
|
|
// Add input listener for mouse clicks
|
|
scene.input.on('pointerdown', (pointer) => {
|
|
this.moveToPoint(pointer.worldX, pointer.worldY);
|
|
});
|
|
|
|
// Create animations
|
|
this.anims.create({
|
|
key: 'player-up',
|
|
frames: this.anims.generateFrameNumbers('player', { start: 10, end: 15 }),
|
|
frameRate: 10,
|
|
repeat: -1
|
|
});
|
|
|
|
this.anims.create({
|
|
key: 'player-side',
|
|
frames: this.anims.generateFrameNumbers('player', { start: 0, end: 5 }),
|
|
frameRate: 10,
|
|
repeat: -1
|
|
});
|
|
|
|
this.anims.create({
|
|
key: 'player-down',
|
|
frames: this.anims.generateFrameNumbers('player', { start: 20, end: 25 }),
|
|
frameRate: 10,
|
|
repeat: -1
|
|
});
|
|
|
|
this.anims.create({
|
|
key: 'player-idle',
|
|
frames: [
|
|
{ key: 'player', frame: 30 }
|
|
],
|
|
frameRate: 5,
|
|
repeat: -1
|
|
});
|
|
|
|
// Set initial animation
|
|
this.anims.play('player-idle');
|
|
}
|
|
|
|
moveToPoint(x, y) {
|
|
// Set target position
|
|
this.targetX = x;
|
|
this.targetY = y;
|
|
|
|
// Calculate direction to target
|
|
const dx = x - this.x;
|
|
const dy = y - this.y;
|
|
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
|
|
if (distance > 100) { // Only move if target is far enough
|
|
this.isMoving = true;
|
|
|
|
// Set velocity towards target
|
|
const speedRatio = this.speed / distance;
|
|
this.body.setVelocityX(dx * speedRatio);
|
|
this.body.setVelocityY(dy * speedRatio);
|
|
}
|
|
}
|
|
|
|
update() {
|
|
// Check if player has reached target
|
|
if (this.isMoving) {
|
|
const dx = this.targetX - this.x;
|
|
const dy = this.targetY - this.y;
|
|
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
|
|
// Stop when close enough to target
|
|
if (distance < 10) {
|
|
this.body.setVelocity(0, 0);
|
|
this.isMoving = false;
|
|
|
|
// Play idle animation when stopping
|
|
this.anims.play('player-idle');
|
|
} else {
|
|
// Update animation based on movement direction
|
|
this.updateAnimation();
|
|
}
|
|
} else {
|
|
// If not moving and velocity is zero, play idle
|
|
if (this.body && this.body.velocity.x === 0 && this.body.velocity.y === 0) {
|
|
this.anims.play('player-idle');
|
|
}
|
|
}
|
|
}
|
|
|
|
updateAnimation() {
|
|
// Get current velocity
|
|
const velX = this.body.velocity.x;
|
|
const velY = this.body.velocity.y;
|
|
|
|
// Calculate magnitude of velocity
|
|
const speed = Math.sqrt(velX * velX + velY * velY);
|
|
|
|
if (speed < 5) { // If moving very slowly, play idle
|
|
this.anims.play('player-idle');
|
|
return;
|
|
}
|
|
|
|
// Determine dominant direction based on velocity components
|
|
const absVelX = Math.abs(velX);
|
|
const absVelY = Math.abs(velY);
|
|
|
|
if (absVelY > absVelX) {
|
|
// Moving mostly vertically
|
|
if (velY < 0) {
|
|
// Moving up
|
|
this.anims.play('player-up', true);
|
|
} else {
|
|
// Moving down
|
|
this.anims.play('player-down', true);
|
|
}
|
|
} else {
|
|
// Moving mostly horizontally
|
|
if (velX < 0) {
|
|
// Moving left - use side animation with flipX = true
|
|
this.anims.play('player-side', true);
|
|
this.setFlipX(false);
|
|
} else {
|
|
// Moving right - use side animation with flipX = false
|
|
this.anims.play('player-side', true);
|
|
this.setFlipX(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Method to stop player movement
|
|
stop() {
|
|
this.setVelocity(0, 0);
|
|
this.isMoving = false;
|
|
|
|
// Play idle animation when stopping
|
|
this.anims.play('player-idle');
|
|
}
|
|
} |