diff --git a/clients/player-client/src/core/GameEngine/GameEngine.ts b/clients/player-client/src/core/GameEngine/GameEngine.ts index 9def31fef..13a64efcd 100644 --- a/clients/player-client/src/core/GameEngine/GameEngine.ts +++ b/clients/player-client/src/core/GameEngine/GameEngine.ts @@ -5,6 +5,7 @@ import { GameState } from '../../dtos/GameState.dto'; import { InputEventRecord } from '../../dtos/Player/InputEventRecord.dto'; import { DateTime, Duration } from 'luxon'; import { InputActionType } from '../../context/Input/InputActionType.type'; +import { ActorOrientation } from '../../dtos/Actor/ActorDirection.type'; export type GameEngineProps = { data: GameState; @@ -50,15 +51,23 @@ export const GameEngine: React.FC = props => { switch (inputContext.state.key) { case InputEventRecordKey.LEFT: + data.actors[actorIndex].animation.orientation = + ActorOrientation.NORTHWEST; data.actors[actorIndex].movement.targetPosition.x--; break; case InputEventRecordKey.RIGHT: + data.actors[actorIndex].animation.orientation = + ActorOrientation.SOUTHEAST; data.actors[actorIndex].movement.targetPosition.x++; break; case InputEventRecordKey.UP: + data.actors[actorIndex].animation.orientation = + ActorOrientation.NORTHEAST; data.actors[actorIndex].movement.targetPosition.y--; break; case InputEventRecordKey.DOWN: + data.actors[actorIndex].animation.orientation = + ActorOrientation.SOUTHWEST; data.actors[actorIndex].movement.targetPosition.y++; break; case InputEventRecordKey.DEBUG: diff --git a/clients/player-client/src/core/IsometricCanvas/draw/SpriteMap.ts b/clients/player-client/src/core/IsometricCanvas/draw/SpriteMap.ts index e5a03ae22..d1062831e 100644 --- a/clients/player-client/src/core/IsometricCanvas/draw/SpriteMap.ts +++ b/clients/player-client/src/core/IsometricCanvas/draw/SpriteMap.ts @@ -1,3 +1,5 @@ +import { ActorOrientation } from '../../../dtos/Actor/ActorDirection.type'; + interface Position { x: number; y: number; @@ -93,6 +95,34 @@ class SpriteMap { }); } + drawFrame( + ctx: CanvasRenderingContext2D, + orientation: ActorOrientation, + currentFrame: number, + position: Position, + opacity: number = 1, + ): void { + let row; + switch (orientation) { + case ActorOrientation.SOUTHEAST: + row = 0; + break; + case ActorOrientation.SOUTHWEST: + row = 1; + break; + case ActorOrientation.NORTHWEST: + row = 2; + break; + case ActorOrientation.NORTHEAST: + row = 3; + break; + } + + const spriteId = this.columns * row + 1 + currentFrame; + + this.draw(ctx, spriteId, position, opacity); + } + draw( ctx: CanvasRenderingContext2D, spriteId: number, diff --git a/clients/player-client/src/core/IsometricCanvas/utils/IsometricRender.ts b/clients/player-client/src/core/IsometricCanvas/utils/IsometricRender.ts index d7aaca877..4a3d35d02 100644 --- a/clients/player-client/src/core/IsometricCanvas/utils/IsometricRender.ts +++ b/clients/player-client/src/core/IsometricCanvas/utils/IsometricRender.ts @@ -304,13 +304,25 @@ export class IsometricRender { ); const actorSpriteMapId = kebabCase( - `${actor.actorId}-${actor.animation?.currentAnimation || 'dle'}`, + `${actor.actorId}-${actor.animation?.currentAnimation || 'idle'}`, ); - this._spriteMaps[actorSpriteMapId].draw(ctx, 1, { + const position = { x: vectors.right.x - (vectors.right.x - vectors.left.x), y: vectors.top.y - 17, - }); + }; + + this._spriteMaps[actorSpriteMapId].drawFrame( + ctx, + actor.animation.orientation, + actor.animation.currentFrame ?? 1, + position, + ); + + // this._spriteMaps[actorSpriteMapId].draw(ctx, 1, { + // x: vectors.right.x - (vectors.right.x - vectors.left.x), + // y: vectors.top.y - 17, + // }); // TODO determine percent based on actor's health drawMeter(ctx, { diff --git a/clients/player-client/src/dtos/Actor/ActorAnimation.dto.ts b/clients/player-client/src/dtos/Actor/ActorAnimation.dto.ts index df7c41e18..2f0080c01 100644 --- a/clients/player-client/src/dtos/Actor/ActorAnimation.dto.ts +++ b/clients/player-client/src/dtos/Actor/ActorAnimation.dto.ts @@ -1,7 +1,17 @@ -import { IsBoolean, IsDateString, IsString, IsNumber } from 'class-validator'; +import { + IsBoolean, + IsDateString, + IsString, + IsNumber, + IsEnum, +} from 'class-validator'; import { DateTime, Duration } from 'luxon'; +import { ActorOrientation } from './ActorDirection.type'; export class ActorAnimation { + @IsEnum(ActorOrientation) + orientation: ActorOrientation; + @IsBoolean() isAnimating?: false; diff --git a/clients/player-client/src/dtos/Actor/ActorDirection.type.ts b/clients/player-client/src/dtos/Actor/ActorDirection.type.ts new file mode 100644 index 000000000..5050d6418 --- /dev/null +++ b/clients/player-client/src/dtos/Actor/ActorDirection.type.ts @@ -0,0 +1,6 @@ +export enum ActorOrientation { + NORTHEAST = 'NORTHEAST', + SOUTHEAST = 'SOUTHEAST', + SOUTHWEST = 'SOUTHWEST', + NORTHWEST = 'NORTHWEST', +} diff --git a/clients/player-client/src/pages/data/Field.json b/clients/player-client/src/pages/data/Field.json index 1c94c220e..a5a0c6801 100644 --- a/clients/player-client/src/pages/data/Field.json +++ b/clients/player-client/src/pages/data/Field.json @@ -23,6 +23,7 @@ "startTimestamp": "2021-07-01T12:00:00.000Z" }, "animation": { + "orientation": "SOUTHWEST", "startingFrame": 0, "totalFrames": 4, "animationDuration": 1.0, diff --git a/clients/player-client/src/pages/data/Sewer.json b/clients/player-client/src/pages/data/Sewer.json index 92ff541b5..9c24fece6 100644 --- a/clients/player-client/src/pages/data/Sewer.json +++ b/clients/player-client/src/pages/data/Sewer.json @@ -23,6 +23,7 @@ "startTimestamp": "2021-07-01T12:00:00.000Z" }, "animation": { + "orientation": "SOUTHWEST", "startingFrame": 0, "totalFrames": 4, "animationDuration": 1.0, diff --git a/clients/player-client/src/pages/data/TrainCar.json b/clients/player-client/src/pages/data/TrainCar.json index feaac2271..c13cd5845 100644 --- a/clients/player-client/src/pages/data/TrainCar.json +++ b/clients/player-client/src/pages/data/TrainCar.json @@ -23,6 +23,7 @@ "startTimestamp": "2021-07-01T12:00:00.000Z" }, "animation": { + "orientation": "SOUTHWEST", "startingFrame": 0, "totalFrames": 4, "animationDuration": 1.0, @@ -62,6 +63,7 @@ "startTimestamp": "2021-07-01T12:00:00.000Z" }, "animation": { + "orientation": "SOUTHWEST", "startingFrame": 0, "totalFrames": 4, "animationDuration": 1.0, diff --git a/clients/player-client/src/pages/data/TrainRoom.json b/clients/player-client/src/pages/data/TrainRoom.json index 46b5edbc4..17c85fb5c 100644 --- a/clients/player-client/src/pages/data/TrainRoom.json +++ b/clients/player-client/src/pages/data/TrainRoom.json @@ -23,6 +23,7 @@ "startTimestamp": "2021-07-01T12:00:00.000Z" }, "animation": { + "orientation": "SOUTHWEST", "startingFrame": 0, "totalFrames": 4, "animationDuration": 1.0, diff --git a/clients/player-client/src/pages/data/TrainStorageCar.json b/clients/player-client/src/pages/data/TrainStorageCar.json index 7055ef24d..be3c54760 100644 --- a/clients/player-client/src/pages/data/TrainStorageCar.json +++ b/clients/player-client/src/pages/data/TrainStorageCar.json @@ -23,6 +23,7 @@ "startTimestamp": "2021-07-01T12:00:00.000Z" }, "animation": { + "orientation": "SOUTHWEST", "startingFrame": 0, "totalFrames": 4, "animationDuration": 1.0, @@ -56,6 +57,7 @@ "startTimestamp": "2021-07-01T12:00:00.000Z" }, "animation": { + "orientation": "SOUTHWEST", "startingFrame": 0, "totalFrames": 4, "animationDuration": 1.0, diff --git a/clients/player-client/src/pages/home.page.tsx b/clients/player-client/src/pages/home.page.tsx index 58cbc70c9..d9646002c 100644 --- a/clients/player-client/src/pages/home.page.tsx +++ b/clients/player-client/src/pages/home.page.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import { IsometricCanvas } from '../core/IsometricCanvas'; -import gameStateRaw from './data/TrainStorageCar.json'; +import gameStateRaw from './data/Sewer.json'; import { InputProvider } from '../context/Input/InputProvider'; import { Keyboard } from '../core/Keyboard/Keyboard'; import { GameEngine } from '../core/GameEngine/GameEngine';