Contains game-jumpnrun and game-labyrinth projects. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
110 lines
3.2 KiB
JavaScript
110 lines
3.2 KiB
JavaScript
// Spieler-Logik
|
|
|
|
const Player = {
|
|
col: 0, // Aktuelle Grid-Position
|
|
row: 0,
|
|
targetCol: 0, // Ziel-Position (für smooth movement)
|
|
targetRow: 0,
|
|
visualX: 0, // Visuelle Position (interpoliert)
|
|
visualY: 0,
|
|
direction: 'right',
|
|
moving: false,
|
|
moveProgress: 0,
|
|
moveSpeed: 6, // Tiles pro Sekunde
|
|
animFrame: 0,
|
|
animTimer: 0,
|
|
inputQueue: null, // Gepufferter Input
|
|
|
|
init(col, row) {
|
|
this.col = col;
|
|
this.row = row;
|
|
this.targetCol = col;
|
|
this.targetRow = row;
|
|
this.visualX = col;
|
|
this.visualY = row;
|
|
this.direction = 'right';
|
|
this.moving = false;
|
|
this.moveProgress = 0;
|
|
this.inputQueue = null;
|
|
this.animFrame = 0;
|
|
},
|
|
|
|
handleInput(key) {
|
|
let dc = 0, dr = 0, dir = this.direction;
|
|
|
|
switch (key) {
|
|
case 'ArrowUp': case 'w': case 'W': dr = -1; dir = 'up'; break;
|
|
case 'ArrowDown': case 's': case 'S': dr = 1; dir = 'down'; break;
|
|
case 'ArrowLeft': case 'a': case 'A': dc = -1; dir = 'left'; break;
|
|
case 'ArrowRight': case 'd': case 'D': dc = 1; dir = 'right'; break;
|
|
default: return;
|
|
}
|
|
|
|
this.inputQueue = { dc, dr, dir };
|
|
},
|
|
|
|
tryMove(grid) {
|
|
if (!this.inputQueue) return;
|
|
const { dc, dr, dir } = this.inputQueue;
|
|
|
|
const newCol = this.col + dc;
|
|
const newRow = this.row + dr;
|
|
|
|
this.direction = dir;
|
|
|
|
if (Utils.isWalkable(grid, newCol, newRow)) {
|
|
this.targetCol = newCol;
|
|
this.targetRow = newRow;
|
|
this.moving = true;
|
|
this.moveProgress = 0;
|
|
this.inputQueue = null;
|
|
}
|
|
},
|
|
|
|
update(dt, grid) {
|
|
// Versuche gepufferten Input
|
|
if (!this.moving) {
|
|
this.tryMove(grid);
|
|
}
|
|
|
|
if (this.moving) {
|
|
this.moveProgress += this.moveSpeed * dt;
|
|
this.animTimer += dt;
|
|
|
|
if (this.animTimer > 0.15) {
|
|
this.animFrame = (this.animFrame + 1) % 2;
|
|
this.animTimer = 0;
|
|
}
|
|
|
|
if (this.moveProgress >= 1) {
|
|
this.moveProgress = 1;
|
|
this.col = this.targetCol;
|
|
this.row = this.targetRow;
|
|
this.moving = false;
|
|
this.moveProgress = 0;
|
|
|
|
// Sofort nächsten Input verarbeiten
|
|
this.tryMove(grid);
|
|
}
|
|
|
|
// Smooth interpolation
|
|
this.visualX = Utils.lerp(this.col - (this.targetCol - this.col) * (this.moving ? 0 : 1),
|
|
this.targetCol, this.moving ? this.moveProgress : 1);
|
|
this.visualY = Utils.lerp(this.row - (this.targetRow - this.row) * (this.moving ? 0 : 1),
|
|
this.targetRow, this.moving ? this.moveProgress : 1);
|
|
}
|
|
|
|
if (this.moving) {
|
|
this.visualX = Utils.lerp(this.col, this.targetCol, this.moveProgress);
|
|
this.visualY = Utils.lerp(this.row, this.targetRow, this.moveProgress);
|
|
} else {
|
|
this.visualX = this.col;
|
|
this.visualY = this.row;
|
|
}
|
|
},
|
|
|
|
draw(time) {
|
|
Renderer.drawPlayer(this.visualX, this.visualY, this.direction, this.animFrame, time);
|
|
}
|
|
};
|