diff --git a/src/application/enums.ts b/src/application/enums.ts
new file mode 100644
index 0000000..8dd4620
--- /dev/null
+++ b/src/application/enums.ts
@@ -0,0 +1,5 @@
+export enum Direction {
+ POSITIVE,
+ NEGATIVE,
+ UNCHANGED
+}
diff --git a/src/components/game/character/Character.vue b/src/components/game/character/Character.vue
index 29596bf..f1d2593 100644
--- a/src/components/game/character/Character.vue
+++ b/src/components/game/character/Character.vue
@@ -1,134 +1,43 @@
-
+
diff --git a/src/components/game/character/partials/Healthbar.vue b/src/components/game/character/partials/HealthBar.vue
similarity index 100%
rename from src/components/game/character/partials/Healthbar.vue
rename to src/components/game/character/partials/HealthBar.vue
diff --git a/src/composables/useCharacterSpriteComposable.ts b/src/composables/useCharacterSpriteComposable.ts
new file mode 100644
index 0000000..500d768
--- /dev/null
+++ b/src/composables/useCharacterSpriteComposable.ts
@@ -0,0 +1,131 @@
+import { type MapCharacter } from '@/application/types'
+import { loadSpriteTextures } from '@/composables/gameComposable'
+import { calculateIsometricDepth, tileToWorldX, tileToWorldY } from '@/composables/mapComposable'
+import { CharacterTypeStorage } from '@/storage/storages'
+import { refObj } from 'phavuer'
+import { computed, ref } from 'vue'
+import { Direction } from '@/application/enums'
+
+export function useCharacterSprite(scene: Phaser.Scene, tilemap: Phaser.Tilemaps.Tilemap, mapCharacter: MapCharacter) {
+ const charSprite = refObj()
+ const charSpriteId = ref('')
+ const currentPositionX = ref(0)
+ const currentPositionY = ref(0)
+ const isometricDepth = ref(1)
+ const isInitialPosition = ref(true)
+ const tween = ref(null)
+
+ const updateIsometricDepth = (positionX: number, positionY: number) => {
+ isometricDepth.value = calculateIsometricDepth(positionX, positionY, 28, 94, true)
+ }
+
+ const updatePosition = (positionX: number, positionY: number, direction: Direction) => {
+ const newPositionX = tileToWorldX(tilemap, positionX, positionY)
+ const newPositionY = tileToWorldY(tilemap, positionX, positionY)
+
+ if (isInitialPosition.value) {
+ currentPositionX.value = newPositionX
+ currentPositionY.value = newPositionY
+ isInitialPosition.value = false
+ return
+ }
+
+ if (tween.value?.isPlaying()) {
+ tween.value.stop()
+ }
+
+ const distance = Math.sqrt(Math.pow(newPositionX - currentPositionX.value, 2) + Math.pow(newPositionY - currentPositionY.value, 2))
+ const baseSpeed = 150 // pixels per second
+ const duration = (distance / baseSpeed) * 1000 // Convert to milliseconds
+
+ tween.value = tilemap.scene.tweens.add({
+ targets: charSprite.value,
+ x: newPositionX,
+ y: newPositionY,
+ duration,
+ ease: 'Linear',
+ onStart: () => {
+ if (direction === Direction.POSITIVE) {
+ updateIsometricDepth(positionX, positionY)
+ }
+ },
+ onUpdate: () => {
+ currentPositionX.value = charSprite.value?.x ?? currentPositionX.value
+ currentPositionY.value = charSprite.value?.y ?? currentPositionY.value
+ },
+ onComplete: () => {
+ if (direction === Direction.NEGATIVE) {
+ updateIsometricDepth(positionX, positionY)
+ }
+ }
+ })
+ }
+
+ const calcDirection = (oldPositionX: number, oldPositionY: number, newPositionX: number, newPositionY: number): Direction => {
+ if (newPositionY < oldPositionY || newPositionX < oldPositionX) return Direction.NEGATIVE
+ if (newPositionX > oldPositionX || newPositionY > oldPositionY) return Direction.POSITIVE
+ return Direction.UNCHANGED
+ }
+
+ const isFlippedX = computed(() => [6, 4].includes(mapCharacter.character.rotation ?? 0))
+
+ const currentDirection = computed(() => {
+ return [0, 6].includes(mapCharacter.character.rotation ?? 0) ? 'left_up' : 'right_down'
+ })
+
+ const currentAction = computed(() => {
+ return mapCharacter.isMoving ? 'walk' : 'idle'
+ })
+
+ const charTexture = computed(() => {
+ const spriteId = charSpriteId.value ?? 'idle_right_down'
+ return `${spriteId}-${currentAction.value}_${currentDirection.value}`
+ })
+
+ const updateSprite = () => {
+ if (!charSprite.value) return
+
+ if (mapCharacter.isMoving) {
+ charSprite.value.anims.play(charTexture.value, true)
+ } else {
+ charSprite.value.anims.stop()
+ charSprite.value.setFrame(0)
+ charSprite.value.setTexture(charTexture.value)
+ }
+ }
+
+ const initializeSprite = async () => {
+ const characterTypeStorage = new CharacterTypeStorage()
+ const spriteId = await characterTypeStorage.getSpriteId(mapCharacter.character.characterType!)
+ if (!spriteId) return
+
+ charSpriteId.value = spriteId
+ await loadSpriteTextures(scene, spriteId)
+
+ if (charSprite.value) {
+ charSprite.value.setTexture(charTexture.value)
+ charSprite.value.setFlipX(isFlippedX.value)
+ charSprite.value.setName(mapCharacter.character.name)
+ }
+
+ updatePosition(mapCharacter.character.positionX, mapCharacter.character.positionY, mapCharacter.character.rotation)
+ }
+
+ const cleanup = () => {
+ tween.value?.stop()
+ }
+
+ return {
+ charSprite,
+ charSpriteId,
+ currentPositionX,
+ currentPositionY,
+ isometricDepth,
+ isFlippedX,
+ updatePosition,
+ calcDirection,
+ updateSprite,
+ initializeSprite,
+ cleanup
+ }
+}
\ No newline at end of file