98 lines
2.7 KiB
JavaScript
98 lines
2.7 KiB
JavaScript
class MovingObject extends GameObject {
|
|
constructor(game, x, y) {
|
|
super(game, x, y);
|
|
this.dir = {x: 0, y: 0};
|
|
this.speed = 1;
|
|
|
|
this.turnTimeout = null;
|
|
}
|
|
|
|
changeDir(dir) {
|
|
if (this.dir.x === dir.x && this.dir.y === dir.y) {
|
|
return;
|
|
}
|
|
|
|
if (this.dir.x === dir.x || this.dir.y === dir.y) {
|
|
clearTimeout(this.turnTimeout);
|
|
this.dir = dir;
|
|
return;
|
|
}
|
|
|
|
const isX = this.dir.x !== 0;
|
|
let curPos;
|
|
let dirPositive;
|
|
|
|
if (isX) {
|
|
curPos = this.x;
|
|
dirPositive = this.dir.x > 0;
|
|
} else if (this.dir.y !== 0) {
|
|
curPos = this.y;
|
|
dirPositive = this.dir.y > 0;
|
|
}
|
|
|
|
let targetSwitch;
|
|
if (dirPositive) {
|
|
targetSwitch = Math.ceil(curPos + 0.5) - 0.5;
|
|
} else {
|
|
targetSwitch = Math.floor(curPos - 0.5) + 0.5;
|
|
}
|
|
|
|
const distance = Math.abs(curPos - targetSwitch);
|
|
const duration = distance / this.speed * 1000;
|
|
|
|
clearTimeout(this.turnTimeout);
|
|
this.turnTimeout = setTimeout(() => {
|
|
if (isX) {
|
|
this.x = targetSwitch;
|
|
} else {
|
|
this.y = targetSwitch;
|
|
}
|
|
this.dir = dir;
|
|
}, duration);
|
|
}
|
|
|
|
update(deltaTime) {
|
|
const ticks = Math.floor(deltaTime / 16);
|
|
const tickLength = deltaTime / ticks;
|
|
|
|
for(let i = 0; i < ticks; i++) {
|
|
this.x += this.dir.x * (this.speed * tickLength / 1000);
|
|
this.y += this.dir.y * (this.speed * tickLength / 1000);
|
|
|
|
const nextTile = this.getNextTile(this.dir.x, this.dir.y);
|
|
|
|
if (!nextTile.tile) {
|
|
if (nextTile.distanceX <= 0.5 || nextTile.distanceY <= 0.5) {
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (nextTile.tile.solid) {
|
|
if (nextTile.distanceX <= 0.5) {
|
|
this.x = nextTile.tile.x - this.dir.x + 0.5;
|
|
}
|
|
if (nextTile.distanceY <= 0.5) {
|
|
this.y = nextTile.tile.y - this.dir.y + 0.5;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
getNextTile(offsetX, offsetY) {
|
|
const tileX = Math.round(this.x - 0.5);
|
|
const tileY = Math.round(this.y - 0.5);
|
|
|
|
const nextX = tileX + offsetX;
|
|
const nextY = tileY + offsetY;
|
|
|
|
const distanceX = Math.abs(this.x - (offsetX >= 0 ? nextX : nextX + 1));
|
|
const distanceY = Math.abs(this.y - (offsetY >= 0 ? nextY : nextY + 1));
|
|
|
|
return {
|
|
tile: this.game.map.getTile(nextX, nextY),
|
|
distanceX: distanceX,
|
|
distanceY: distanceY,
|
|
};
|
|
}
|
|
} |