spinner-io / server /src /game /Player.js
Phuc Long Nguyen
Init project from github
f676ff2
Raw
History Blame Contribute Delete
2.57 kB
const { MAP_WIDTH, MAP_HEIGHT, PLAYER_RADIUS, PLAYER_SPEED, ORBIT_RADIUS_BASE, ORBIT_RADIUS_STEP, SPAWN_PROTECTION_TICKS } = require('../../../shared/constants');
class Player {
constructor(id, name = 'Player', skinId = 0) {
this.id = id;
this.name = name;
this.skinId = skinId;
this.x = Math.random() * MAP_WIDTH;
this.y = Math.random() * MAP_HEIGHT;
this.radius = PLAYER_RADIUS;
this.score = 0;
this.kills = 0;
this.stamina = 100;
this.isBoosting = false;
this.input = { x: this.x, y: this.y };
this.angle = 0;
this.orbits = [];
this.protectionTicks = SPAWN_PROTECTION_TICKS;
}
setInput(x, y) {
if (typeof x !== 'number' || typeof y !== 'number') return;
this.input = {
x: Math.min(Math.max(x, 0), MAP_WIDTH),
y: Math.min(Math.max(y, 0), MAP_HEIGHT),
};
}
setBoost(boost) {
this.isBoosting = boost;
}
update() {
// 1. Calculate speed based on boosting state and stamina
let currentSpeed = PLAYER_SPEED;
if (this.isBoosting && this.stamina > 0) {
currentSpeed = PLAYER_SPEED * 1.8; // 1.8x speed boost
this.stamina = Math.max(0, this.stamina - 1.5); // Consume 1.5 stamina per tick (~45/s)
} else {
this.stamina = Math.min(100, this.stamina + 0.6); // Recover 0.6 stamina per tick (~18/s)
}
if (this.protectionTicks > 0) {
this.protectionTicks = Math.max(0, this.protectionTicks - 1);
}
const dx = this.input.x - this.x;
const dy = this.input.y - this.y;
const dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
this.angle = Math.atan2(dy, dx);
}
if (dist > currentSpeed) {
this.x += (dx / dist) * currentSpeed;
this.y += (dy / dist) * currentSpeed;
} else {
this.x = this.input.x;
this.y = this.input.y;
}
}
addOrbit(type = 'normal') {
this.orbits.push({
angle: Math.random() * Math.PI * 2,
ring: this.orbits.length % 2,
type,
hp: type === 'strong' ? 2 : 1,
});
}
removeOrbit(orbit) {
const index = this.orbits.indexOf(orbit);
if (index !== -1) {
this.orbits.splice(index, 1);
}
}
toJSON() {
return {
id: this.id,
name: this.name,
x: this.x,
y: this.y,
radius: this.radius,
score: this.score,
kills: this.kills,
angle: this.angle,
orbits: this.orbits,
skinId: this.skinId,
stamina: this.stamina,
isBoosting: this.isBoosting,
isProtected: this.protectionTicks > 0,
};
}
}
module.exports = Player;