Added kidney_labe and Cyste_kid
This commit is contained in:
140
kidney_lab/js/player.js
Normal file
140
kidney_lab/js/player.js
Normal file
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* player.js
|
||||
* Player state, grid movement, and inventory management.
|
||||
* No rendering, no DOM — pure logic.
|
||||
*/
|
||||
|
||||
class Player {
|
||||
constructor() {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
reset() {
|
||||
// Grid position: col 0-3 (left → right), row 0-2 (top → bottom)
|
||||
this.col = 0;
|
||||
this.row = 1;
|
||||
|
||||
// Carried goods (max SETTINGS.MAX_CARRY)
|
||||
this.goods = [];
|
||||
|
||||
// Whether the player is holding the medication vial
|
||||
this.hasMedication = false;
|
||||
|
||||
// Movement cooldown (ms)
|
||||
this.moveCooldown = 0;
|
||||
|
||||
// Walk-cycle: phase advances (radians) while moveCooldown > 0
|
||||
this.walkPhase = 0;
|
||||
this.animFrame = 0;
|
||||
this.animTimer = 0;
|
||||
|
||||
// Flash timer when interacting
|
||||
this.interactFlash = 0;
|
||||
}
|
||||
|
||||
/* ── Helpers ──────────────────────────────────────────────── */
|
||||
|
||||
/** Pixel x centre of current column inside the middle zone. */
|
||||
pixelX() {
|
||||
// Evenly distribute columns across the middle zone with a 30px margin
|
||||
// from each edge, so col 0 sits just right of the belt end and
|
||||
// col (PLAYER_COLS-1) sits just left of the right-zone border.
|
||||
const margin = 30;
|
||||
const avail = SETTINGS.MIDDLE_ZONE_END - SETTINGS.MIDDLE_ZONE_START - margin * 2;
|
||||
const step = avail / (SETTINGS.PLAYER_COLS - 1);
|
||||
return SETTINGS.MIDDLE_ZONE_START + margin + this.col * step;
|
||||
}
|
||||
|
||||
/** Pixel y centre of current row. */
|
||||
pixelY() {
|
||||
return SETTINGS.BELT_ROWS[this.row];
|
||||
}
|
||||
|
||||
canMove() {
|
||||
return this.moveCooldown <= 0;
|
||||
}
|
||||
|
||||
canCarryMore() {
|
||||
return this.goods.length < SETTINGS.MAX_CARRY;
|
||||
}
|
||||
|
||||
/* ── Movement ─────────────────────────────────────────────── */
|
||||
|
||||
move(direction) {
|
||||
if (!this.canMove()) return false;
|
||||
|
||||
let nc = this.col;
|
||||
let nr = this.row;
|
||||
|
||||
switch (direction) {
|
||||
case 'up': nr = Math.max(0, nr - 1); break;
|
||||
case 'down': nr = Math.min(SETTINGS.PLAYER_ROWS - 1, nr + 1); break;
|
||||
case 'left': nc = Math.max(0, nc - 1); break;
|
||||
case 'right': nc = Math.min(SETTINGS.PLAYER_COLS - 1, nc + 1); break;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
if (nc === this.col && nr === this.row) return false;
|
||||
|
||||
this.col = nc;
|
||||
this.row = nr;
|
||||
this.moveCooldown = SETTINGS.PLAYER_MOVE_COOLDOWN;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ── Inventory ────────────────────────────────────────────── */
|
||||
|
||||
/**
|
||||
* Attempt to add a good to the inventory.
|
||||
* Returns true on success, false if full.
|
||||
*/
|
||||
addGood(good) {
|
||||
if (!this.canCarryMore()) return false;
|
||||
this.goods.push(good);
|
||||
this.interactFlash = 300;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove and return all carried goods (for lab deposit).
|
||||
*/
|
||||
depositGoods() {
|
||||
const deposited = [...this.goods];
|
||||
this.goods = [];
|
||||
this.interactFlash = 400;
|
||||
return deposited;
|
||||
}
|
||||
|
||||
pickupMedication() {
|
||||
this.hasMedication = true;
|
||||
this.interactFlash = 400;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deliver medication to patient.
|
||||
* Returns true if medication was delivered.
|
||||
*/
|
||||
deliverMedication() {
|
||||
if (!this.hasMedication) return false;
|
||||
this.hasMedication = false;
|
||||
this.interactFlash = 600;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ── Update ───────────────────────────────────────────────── */
|
||||
|
||||
update(dt) {
|
||||
if (this.moveCooldown > 0) {
|
||||
this.moveCooldown -= dt;
|
||||
// Advance walk cycle: ~π radians per 180 ms move cooldown → one leg swing per step
|
||||
this.walkPhase += dt * 0.0175;
|
||||
}
|
||||
if (this.interactFlash > 0) this.interactFlash -= dt;
|
||||
|
||||
this.animTimer += dt;
|
||||
if (this.animTimer >= 200) {
|
||||
this.animTimer -= 200;
|
||||
this.animFrame = (this.animFrame + 1) % 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user