From 0e71df93013a757abe826de1d94962670bd3bb92 Mon Sep 17 00:00:00 2001 From: hxtree <19890291+hxtree@users.noreply.github.com> Date: Sat, 14 Dec 2024 06:12:34 -0600 Subject: [PATCH] feat: add render position --- .../src/core/GameEngine/GameEngine.ts | 2 +- .../IsometricCanvas/utils/IsometricRender.ts | 6 +-- .../player-client/src/dtos/Actor/Actor.dto.ts | 29 +++++------ .../src/dtos/Actor/ActorAnimation.dto.ts | 8 +++- .../src/dtos/Actor/ActorMovement.dto.ts | 48 +++++++++++++++---- 5 files changed, 61 insertions(+), 32 deletions(-) diff --git a/clients/player-client/src/core/GameEngine/GameEngine.ts b/clients/player-client/src/core/GameEngine/GameEngine.ts index aa40b5b5..06fd462f 100644 --- a/clients/player-client/src/core/GameEngine/GameEngine.ts +++ b/clients/player-client/src/core/GameEngine/GameEngine.ts @@ -82,7 +82,7 @@ export const GameEngine: React.FC = props => { data.actors[actorIndex].movement.isInMotion = true; data.actors[actorIndex].movement.currentPosition = data.actors[actorIndex].movement.targetPosition; - data.actors[actorIndex].movement.targetPositionReached = false; + data.actors[actorIndex].movement.startTimestamp = DateTime.now(); data.actors[actorIndex].movement.movementDuration = Duration.fromObject({ seconds: 10, }); diff --git a/clients/player-client/src/core/IsometricCanvas/utils/IsometricRender.ts b/clients/player-client/src/core/IsometricCanvas/utils/IsometricRender.ts index 38890bb6..603fda39 100644 --- a/clients/player-client/src/core/IsometricCanvas/utils/IsometricRender.ts +++ b/clients/player-client/src/core/IsometricCanvas/utils/IsometricRender.ts @@ -146,9 +146,9 @@ export class IsometricRender { private findActorsByPosition(position: Coordinate3D): Actor[] { return this._actors.filter( actor => - actor.position?.x === position.x && - actor.position?.y === position.y && - actor.position?.z === position.z, + actor.movement.renderPosition?.x === position.x && + actor.movement.renderPosition?.y === position.y && + actor.movement.renderPosition?.z === position.z, ); } diff --git a/clients/player-client/src/dtos/Actor/Actor.dto.ts b/clients/player-client/src/dtos/Actor/Actor.dto.ts index c075f7d4..292e1592 100644 --- a/clients/player-client/src/dtos/Actor/Actor.dto.ts +++ b/clients/player-client/src/dtos/Actor/Actor.dto.ts @@ -39,9 +39,19 @@ export class Actor { lastUpdated?: DateTime; // Timestamp for when the actor's data was last updated + /** + * Returns the current position of the actor where they should be rendered from + */ get position() { - const now = DateTime.now(); - if (this.movement.endTimestamp && now > this.movement.endTimestamp) { + // Determine if the target position is closer to the camera than the current position + if ( + this.movement.targetPosition.x > this.movement.currentPosition.x || + this.movement.targetPosition.y > this.movement.currentPosition.y + ) { + return this.movement.targetPosition; + } + + if (this.movement.targetPositionReached) { return this.movement.targetPosition; } return this.movement.currentPosition; @@ -54,19 +64,4 @@ export class Actor { } return true; } - - get targetPositionReached() { - const now = DateTime.now(); - if (this.endTimestamp && now > this.endTimestamp) { - return true; - } - return false; - } - - get endTimestamp() { - if (!this.movement.movementDuration) { - return null; - } - return this.movement.startTimestamp.plus(this.movement.movementDuration); - } } diff --git a/clients/player-client/src/dtos/Actor/ActorAnimation.dto.ts b/clients/player-client/src/dtos/Actor/ActorAnimation.dto.ts index 80456e1a..2064a2ed 100644 --- a/clients/player-client/src/dtos/Actor/ActorAnimation.dto.ts +++ b/clients/player-client/src/dtos/Actor/ActorAnimation.dto.ts @@ -32,8 +32,12 @@ export class ActorAnimation { @IsDateString() startTimestamp?: DateTime; // Time when the animation started - @IsDateString() - endTimestamp?: DateTime; // Time when the animation should end + get endTimestamp(): DateTime | null { + if (!this.startTimestamp || !this.duration) { + return null; + } + return this.startTimestamp.plus(this.duration); + } get duration(): Duration { return this.frameDuration.mapUnits(unit => unit * this.totalFrames); diff --git a/clients/player-client/src/dtos/Actor/ActorMovement.dto.ts b/clients/player-client/src/dtos/Actor/ActorMovement.dto.ts index 31702129..a5bb9deb 100644 --- a/clients/player-client/src/dtos/Actor/ActorMovement.dto.ts +++ b/clients/player-client/src/dtos/Actor/ActorMovement.dto.ts @@ -1,5 +1,5 @@ import { IsBoolean, ValidateNested, IsDateString } from 'class-validator'; -import { Type } from 'class-transformer'; +import { Transform, Type } from 'class-transformer'; import { Duration, DateTime } from 'luxon'; import { Coordinate3d } from '../Coordinate3d.dto'; @@ -15,16 +15,46 @@ export class ActorMovement { @Type(() => Coordinate3d) targetPosition: Coordinate3d; - // TODO type for duration - - movementDuration?: Duration; // Duration of the movement (in seconds) ??? - - @IsBoolean() - targetPositionReached: boolean; + @Transform(({ value }) => Duration.fromObject(value), { toClassOnly: true }) + @Transform(({ value }) => value.toObject(), { toPlainOnly: true }) + movementDuration?: Duration; @IsDateString() startTimestamp: DateTime; - @IsDateString() - endTimestamp?: DateTime; + /** + * Returns the current position of the actor where they should be rendered from + */ + get renderPosition(): Coordinate3d { + // Determine if the target position is closer to the camera than the current position + if ( + this.targetPosition.x > this.currentPosition.x || + this.targetPosition.y > this.currentPosition.y + ) { + return this.targetPosition; + } + return this.position; + } + + get position(): Coordinate3d { + if (this.targetPositionReached) { + return this.targetPosition; + } + return this.currentPosition; + } + + get endTimestamp(): DateTime | null { + if (!this.startTimestamp || !this.movementDuration) { + return null; + } + return this.startTimestamp.plus(this.movementDuration); + } + + get targetPositionReached(): boolean { + const now = DateTime.now(); + if (this.endTimestamp && now > this.endTimestamp) { + return true; + } + return false; + } }