75 lines
2.1 KiB
JavaScript
75 lines
2.1 KiB
JavaScript
import { GameObject } from '../engine/GameObject.js';
|
|
|
|
export const PICKUP_TYPES = {
|
|
rapid: { name: 'Rapid Fire', color: [1, 0.8, 0.2, 1] },
|
|
damage: { name: 'Damage +1', color: [1, 0.3, 0.3, 1] },
|
|
multishot: { name: 'Multishot', color: [0.2, 0.8, 1, 1] },
|
|
speed: { name: 'Bullet Speed', color: [0.6, 0.9, 1, 1] },
|
|
};
|
|
|
|
const PICKUP_KEYS = Object.keys(PICKUP_TYPES);
|
|
|
|
export const randomPickupType = (types = PICKUP_KEYS) => (
|
|
types[Math.floor(Math.random() * types.length)]
|
|
);
|
|
|
|
export class Pickup extends GameObject {
|
|
constructor(x, y, type, { container, viewport, life = 10, collectRadius = 46 } = {}) {
|
|
super(x, y);
|
|
this.type = type;
|
|
this.container = container;
|
|
this.viewport = viewport;
|
|
this.life = life;
|
|
this.collectRadius = collectRadius;
|
|
this._time = 0;
|
|
this.size = 16;
|
|
this.width = this.size;
|
|
this.height = this.size;
|
|
this.color = PICKUP_TYPES[type].color;
|
|
}
|
|
|
|
intersect(other) {
|
|
const dx = this.pos.x - other.pos.x;
|
|
const dy = this.pos.y - other.pos.y;
|
|
return dx * dx + dy * dy <= this.collectRadius * this.collectRadius
|
|
|| super.intersect(other);
|
|
}
|
|
|
|
update(dt) {
|
|
this._time += dt;
|
|
if (this._time >= this.life) {
|
|
this.remove(this.container);
|
|
}
|
|
}
|
|
|
|
draw(renderer, textRenderer) {
|
|
const remaining = this.life - this._time;
|
|
let alpha = 1;
|
|
if (remaining < 2) {
|
|
alpha = 0.3 + 0.7 * Math.max(0, Math.sin(remaining * 6));
|
|
}
|
|
|
|
const pulse = 1 + 0.15 * Math.sin(this._time * 6);
|
|
const s = this.size * pulse;
|
|
renderer.drawTexture(
|
|
renderer.whiteTexture,
|
|
this.pos.x - s / 2,
|
|
this.pos.y - s / 2,
|
|
s,
|
|
s,
|
|
[...this.color.slice(0, 3), alpha],
|
|
);
|
|
|
|
const label = PICKUP_TYPES[this.type].name;
|
|
const opts = { size: 12, fillStyle: '#fff', bold: true };
|
|
const entry = textRenderer?.measure(label, opts);
|
|
const textHeight = entry ? entry.height : 0;
|
|
textRenderer?.draw(
|
|
renderer,
|
|
label,
|
|
this.pos.x - (entry ? entry.width / 2 : label.length * 4.5),
|
|
this.pos.y - s / 2 - textHeight - 4,
|
|
opts,
|
|
);
|
|
}
|
|
} |