spinner-io / server /src /game /Bot.js
Phuc Long Nguyen
Init project from github
f676ff2
Raw
History Blame Contribute Delete
2.91 kB
const Player = require('./Player');
const { BOT_LIFETIME_MIN_MS, BOT_LIFETIME_MAX_MS } = require('../../../shared/constants');
class Bot extends Player {
constructor(id, name, skinId) {
super(id, name, skinId);
this.isBot = true;
this.decisionTimer = 0;
// Track when the bot was created and assign a random lifetime between min/max
this.spawnTime = Date.now();
this.lifetime = BOT_LIFETIME_MIN_MS + Math.floor(Math.random() * (BOT_LIFETIME_MAX_MS - BOT_LIFETIME_MIN_MS));
}
updateAI(room) {
this.decisionTimer--;
if (this.decisionTimer <= 0) {
// Make a new decision every 15-30 frames (~500ms - 1s) to simulate human reaction delay
this.decisionTimer = 15 + Math.floor(Math.random() * 15);
let targetX = this.x;
let targetY = this.y;
// 1. Scan for the nearest player/other bot
let closestPlayer = null;
let minPlayerDist = Infinity;
for (const other of room.players.values()) {
if (other.id === this.id) continue;
const dx = other.x - this.x;
const dy = other.y - this.y;
const dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minPlayerDist) {
minPlayerDist = dist;
closestPlayer = other;
}
}
// If a target is close enough (within 450 pixels)
if (closestPlayer && minPlayerDist < 450) {
// If we have more orbits, chase them!
if (this.orbits.length > closestPlayer.orbits.length) {
targetX = closestPlayer.x;
targetY = closestPlayer.y;
this.isBoosting = this.stamina > 30; // Boost when chasing if we have enough stamina
} else {
// Otherwise, run away from them in the opposite direction!
const dx = closestPlayer.x - this.x;
const dy = closestPlayer.y - this.y;
targetX = this.x - dx * 2;
targetY = this.y - dy * 2;
this.isBoosting = this.stamina > 20; // Boost to escape!
}
} else {
this.isBoosting = false; // Rest and recover stamina when collecting/wandering
// 2. Otherwise, look for the nearest pickup
let closestPickup = null;
let minPickupDist = Infinity;
for (const pickup of room.pickups.list()) {
const dx = pickup.x - this.x;
const dy = pickup.y - this.y;
const dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minPickupDist) {
minPickupDist = dist;
closestPickup = pickup;
}
}
if (closestPickup) {
targetX = closestPickup.x;
targetY = closestPickup.y;
} else {
// Random wander if no pickups or players
targetX = this.x + (Math.random() - 0.5) * 400;
targetY = this.y + (Math.random() - 0.5) * 400;
}
}
this.setInput(targetX, targetY);
}
}
}
module.exports = Bot;