import * as constants from '/static/games/rms/constants.js'; export class Gates { constructor() { this.x = 200; this.y = 40; this.v_x = 0; this.v_y = 0; this.a_x = 0; this.a_y = 0; this.target_x = 200; this.target_y = 40; this.health = 1; } radius() { return 30; } choose_position() { const [x, y] = random_position(); this.target_x = x; this.target_y = y; } act(count) { const max_accel = (1 - this.health) * 0.75 + 0.25; const max_velocity = (1 - this.health) * 5 + 5; let dx = this.target_x - this.x; let dy = this.target_y - this.y; /* If we've arrived (close and stopped) */ if (Math.sqrt(dx * dx + dy * dy) < max_velocity / max_accel && Math.sqrt(this.v_x * this.v_x + this.v_y * this.v_y) < 0.01) { /* Then pick a new target */ this.choose_position(); } dx = this.target_x - this.x; dy = this.target_y - this.y; /* if we're close */ if (Math.sqrt(dx * dx + dy * dy) < max_velocity / max_accel) { /* Then slow down */ const [x, y] = shorten(-this.v_x, -this.v_y, max_accel); this.a_x = x; this.a_y = y; } else { /* Otherwise, speed up */ const [x, y] = shorten(dx, dy, max_accel); this.a_x = x; this.a_y = y; } /* If we're going too fast */ if (Math.sqrt(this.v_x * this.v_x + this.v_y * this.v_y) > max_velocity) { /* Then don't go faster */ if (Math.sign(this.v_x) == Math.sign(this.a_x)) { this.a_x = 0; } if (Math.sign(this.v_y) == Math.sign(this.a_y)) { this.a_y = 0; } } this.v_x += this.a_x; this.x += this.v_x; this.v_y += this.a_y; this.y += this.v_y; if (count % 20 === 0) { let num_bullets; if (this.health >= 0.8) { num_bullets = 5; } else if (this.health >= 0.7) { num_bullets = 6; } else if (this.health >= 0.5) { num_bullets = 7; } else if (this.health >= 0.4) { num_bullets = 8; } else if (this.health >= 0.3) { num_bullets = 9; } else if (this.health >= 0.2) { num_bullets = 10; } else { num_bullets = 11; } const result = []; for (let i = 0; i < num_bullets; i++) { result.push(random_bullet(this)); } return result; } else { return []; } } injure(damage) { this.health -= damage; } center() { return [16, 23]; } } export class GatesBullet { constructor(x, d_x, y, d_y) { this.x = x; this.y = y; this.d_x = d_x; this.d_y = d_y; } radius() { return 10; } center() { return [20, 20]; } } function random_position() { return [ Math.random() * (constants.x_dim - 200) + 100, Math.random() * 100, ]; } function random_bullet(enemy) { const multiplier = 2 + 3 * (1 - enemy.health); const theta = Math.random() * 2 * Math.PI / 3 + Math.PI / 6; const dx = Math.cos(theta) * multiplier; const dy = Math.sin(theta) * multiplier; return new GatesBullet(enemy.x, dx, enemy.y, dy); } function shorten(x, y, maxlen) { const len = Math.sqrt(x * x + y * y); if (len > maxlen) { return [x / len / 2, y / len / 2]; } else { return [x, y]; } }