Add moving animation
This commit is contained in:
parent
b3574a8acf
commit
1e4be0ff2c
|
|
@ -48,6 +48,7 @@ export function* zip(...args: Iterable<any>[]) {
|
||||||
|
|
||||||
export const range = (size: number | string) => Object.keys((new Array(+size)).fill(0)).map(k => +k);
|
export const range = (size: number | string) => Object.keys((new Array(+size)).fill(0)).map(k => +k);
|
||||||
export const clamp = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value));
|
export const clamp = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value));
|
||||||
|
export const lerp = (start: number, end: number, t: number) => (start + (end - start) * t);
|
||||||
|
|
||||||
export const prevent = (e: Event) => (e.preventDefault(), false);
|
export const prevent = (e: Event) => (e.preventDefault(), false);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,50 @@
|
||||||
|
import { lerp } from "@common/utils";
|
||||||
import Item from "./item";
|
import Item from "./item";
|
||||||
import Tile from "./tile";
|
import Tile from "./tile";
|
||||||
|
|
||||||
const MOVE_DURATION = 0.5;
|
const MOVE_DURATION = .1;
|
||||||
|
|
||||||
export default class Character extends Item {
|
export default class Character extends Item {
|
||||||
public tile = new Tile([0, 0], 1);
|
public tile = new Tile([0, 0], 1);
|
||||||
public path: Tile[] = [];
|
private path: Tile[] = [];
|
||||||
private pathProgress = 0;
|
private pathProgress = 0;
|
||||||
|
|
||||||
public get displayPosition() {
|
public get displayPosition(): [number, number] {
|
||||||
if (this.path.length > 0) {
|
if (this.path.length > 1) {
|
||||||
// TODO calc
|
const numTransitions = this.path.length - 1;
|
||||||
|
const progress = this.pathProgress * numTransitions;
|
||||||
|
const currentTileIdx = Math.floor(progress);
|
||||||
|
|
||||||
|
const currentTile = this.path[currentTileIdx];
|
||||||
|
const nextTile = this.path[currentTileIdx + 1];
|
||||||
|
|
||||||
|
if (!nextTile) {
|
||||||
|
return [currentTile.centerX, currentTile.centerY];
|
||||||
|
}
|
||||||
|
|
||||||
|
const transitionFraction = progress - currentTileIdx;
|
||||||
|
|
||||||
|
return [
|
||||||
|
lerp(currentTile.centerX, nextTile.centerX, transitionFraction),
|
||||||
|
lerp(currentTile.centerY, nextTile.centerY, transitionFraction),
|
||||||
|
]
|
||||||
}
|
}
|
||||||
return [this.tile.centerX, this.tile.centerY];
|
return [this.tile.centerX, this.tile.centerY];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public moveTo(tile: Tile, path: Tile[]) {
|
||||||
|
this.pathProgress = 0;
|
||||||
|
this.tile = tile;
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
public update(dt: number) {
|
public update(dt: number) {
|
||||||
if (this.path.length > 0) {
|
if (this.path.length > 1) {
|
||||||
if (this.pathProgress >= 1) {
|
if (this.pathProgress >= 1) {
|
||||||
this.path = [];
|
this.path = [];
|
||||||
this.pathProgress = 0;
|
this.pathProgress = 0;
|
||||||
} else {
|
} else {
|
||||||
this.pathProgress += MOVE_DURATION * dt;
|
this.pathProgress += dt / (MOVE_DURATION * (this.path.length - 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,7 @@ export default class TileMap extends Entity {
|
||||||
|
|
||||||
get activeTiles() {
|
get activeTiles() {
|
||||||
return this.tiles.filter(tile => (
|
return this.tiles.filter(tile => (
|
||||||
tile.items.length > 0
|
tile.items.length > 0
|
||||||
|| tile.type === TileType.LOCKED_DOOR
|
|| tile.type === TileType.LOCKED_DOOR
|
||||||
|| tile.hovered
|
|| tile.hovered
|
||||||
|| (this.state === GameState.NORMAL && this.availableTiles.includes(tile))
|
|| (this.state === GameState.NORMAL && this.availableTiles.includes(tile))
|
||||||
|
|
@ -219,7 +219,7 @@ export default class TileMap extends Entity {
|
||||||
const path = Pathfinding.findPath(this.player.tile, tile);
|
const path = Pathfinding.findPath(this.player.tile, tile);
|
||||||
if (path.length > 1) {
|
if (path.length > 1) {
|
||||||
this.player.lastDoor = path.find(t => t.type === TileType.DOOR);
|
this.player.lastDoor = path.find(t => t.type === TileType.DOOR);
|
||||||
this.player.tile = tile;
|
this.player.moveTo(tile, path);
|
||||||
tile.open();
|
tile.open();
|
||||||
for (const item of tile.items.slice()) { // iterate remaining items
|
for (const item of tile.items.slice()) { // iterate remaining items
|
||||||
if (item.isPickable) {
|
if (item.isPickable) {
|
||||||
|
|
@ -316,7 +316,7 @@ export default class TileMap extends Entity {
|
||||||
|
|
||||||
private killEnemy() {
|
private killEnemy() {
|
||||||
this.player.tile.killEnemy();
|
this.player.tile.killEnemy();
|
||||||
this.player.tile.items.forEach((item) => {
|
this.player.tile.items.slice().forEach((item) => {
|
||||||
if (item.isPickable) {
|
if (item.isPickable) {
|
||||||
this.player.inventory.push(item);
|
this.player.inventory.push(item);
|
||||||
this.player.tile.removeItem(item);
|
this.player.tile.removeItem(item);
|
||||||
|
|
@ -339,9 +339,10 @@ export default class TileMap extends Entity {
|
||||||
}
|
}
|
||||||
|
|
||||||
const w = this.tileSize * 0.8;
|
const w = this.tileSize * 0.8;
|
||||||
[...this.players, this.player].forEach(c =>
|
[...this.players, this.player].forEach((player) => {
|
||||||
ctx.drawImage(c.type, c.tile.centerX - w / 2, c.tile.centerY - w / 2, w, w)
|
const [x, y] = player.displayPosition;
|
||||||
);
|
ctx.drawImage(player.type, x - w / 2, y - w / 2, w, w);
|
||||||
|
});
|
||||||
|
|
||||||
this.activeTiles.forEach(t => t.render(ctx));
|
this.activeTiles.forEach(t => t.render(ctx));
|
||||||
|
|
||||||
|
|
@ -350,4 +351,8 @@ export default class TileMap extends Entity {
|
||||||
|
|
||||||
ctx.strokeRect(this.player.tile.centerX - w / 2, this.player.tile.centerY - w / 2, w, w);
|
ctx.strokeRect(this.player.tile.centerX - w / 2, this.player.tile.centerY - w / 2, w, w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public update(dt: number) {
|
||||||
|
this.players.forEach((player) => player.update(dt));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue