1
0
forked from noxious/client

CharHair work

This commit is contained in:
Dennis Postma 2025-01-28 16:32:16 +01:00
parent 85537840ab
commit bdbda6456c
3 changed files with 61 additions and 38 deletions

View File

@ -1,12 +1,14 @@
<template> <template>
<ChatBubble :mapCharacter="props.mapCharacter" :currentX="currentPositionX" :currentY="currentPositionY" /> <ChatBubble :mapCharacter="props.mapCharacter" :currentX="currentPositionX" :currentY="currentPositionY" />
<Healthbar :mapCharacter="props.mapCharacter" :currentX="currentPositionX" :currentY="currentPositionY" /> <Healthbar :mapCharacter="props.mapCharacter" :currentX="currentPositionX" :currentY="currentPositionY" />
<CharacterHair :mapCharacter="props.mapCharacter" :currentX="currentPositionX" :currentY="currentPositionY" />
<Sprite ref="charSprite" :depth="isometricDepth" :x="currentPositionX" :y="currentPositionY" :origin-y="1" :flipX="isFlippedX" /> <Sprite ref="charSprite" :depth="isometricDepth" :x="currentPositionX" :y="currentPositionY" :origin-y="1" :flipX="isFlippedX" />
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import config from '@/application/config' import config from '@/application/config'
import { type MapCharacter } from '@/application/types' import { type MapCharacter } from '@/application/types'
import CharacterHair from '@/components/game/character/partials/CharacterHair.vue'
import ChatBubble from '@/components/game/character/partials/ChatBubble.vue' import ChatBubble from '@/components/game/character/partials/ChatBubble.vue'
import Healthbar from '@/components/game/character/partials/Healthbar.vue' import Healthbar from '@/components/game/character/partials/Healthbar.vue'
import { loadSpriteTextures } from '@/composables/gameComposable' import { loadSpriteTextures } from '@/composables/gameComposable'
@ -103,21 +105,41 @@ const calcDirection = (oldPositionX: number, oldPositionY: number, newPositionX:
const isFlippedX = computed(() => [6, 4].includes(props.mapCharacter.character.rotation ?? 0)) const isFlippedX = computed(() => [6, 4].includes(props.mapCharacter.character.rotation ?? 0))
const currentDirection = computed(() => {
return [0, 6].includes(props.mapCharacter.character.rotation ?? 0) ? 'left_up' : 'right_down'
})
const currentAction = computed(() => {
return props.mapCharacter.isMoving ? 'walk' : 'idle'
})
const charTexture = computed(() => { const charTexture = computed(() => {
const spriteId = charSpriteId.value ?? 'idle_right_down' const spriteId = charSpriteId.value ?? 'idle_right_down'
const action = props.mapCharacter.isMoving ? 'walk' : 'idle' return `${spriteId}-${currentAction.value}_${currentDirection.value}`
const direction = [0, 6].includes(props.mapCharacter.character.rotation) ? 'left_up' : 'right_down'
return `${spriteId}-${action}_${direction}`
}) })
const updateSprite = () => { const updateSprite = () => {
if (!charSprite.value) return
if (props.mapCharacter.isMoving) { if (props.mapCharacter.isMoving) {
charSprite.value!.anims.play(charTexture.value, true) charSprite.value.anims.play(charTexture.value, true)
} else { } else {
charSprite.value!.anims.stop() charSprite.value.anims.stop()
charSprite.value!.setFrame(0) charSprite.value.setFrame(0)
charSprite.value!.setTexture(charTexture.value) charSprite.value.setTexture(charTexture.value)
}
}
const handlePositionUpdate = (newValues: any, oldValues: any) => {
if (!newValues) return
if (!oldValues || newValues.positionX !== oldValues.positionX || newValues.positionY !== oldValues.positionY) {
const direction = !oldValues ? Direction.POSITIVE : calcDirection(oldValues.positionX, oldValues.positionY, newValues.positionX, newValues.positionY)
updatePosition(newValues.positionX, newValues.positionY, direction)
}
if (newValues.isMoving !== oldValues?.isMoving || newValues.rotation !== oldValues?.rotation) {
updateSprite()
} }
} }
@ -128,19 +150,7 @@ watch(
isMoving: props.mapCharacter.isMoving, isMoving: props.mapCharacter.isMoving,
rotation: props.mapCharacter.character.rotation rotation: props.mapCharacter.character.rotation
}), }),
(newValues, oldValues) => { handlePositionUpdate
if (!newValues) return
if (!oldValues || newValues.positionX !== oldValues.positionX || newValues.positionY !== oldValues.positionY) {
const direction = !oldValues ? Direction.POSITIVE : calcDirection(oldValues.positionX, oldValues.positionY, newValues.positionX, newValues.positionY)
updatePosition(newValues.positionX, newValues.positionY, direction)
}
// Handle animation updates
if (newValues.isMoving !== oldValues?.isMoving || newValues.rotation !== oldValues?.rotation) {
updateSprite()
}
}
) )
onMounted(async () => { onMounted(async () => {
@ -155,10 +165,11 @@ onMounted(async () => {
await loadSpriteTextures(scene, spriteId) await loadSpriteTextures(scene, spriteId)
charSprite.value!.setTexture(charTexture.value) if (charSprite.value) {
charSprite.value!.setFlipX(isFlippedX.value) charSprite.value.setTexture(charTexture.value)
charSprite.value.setFlipX(isFlippedX.value)
charSprite.value!.setName(props.mapCharacter.character!.name) charSprite.value.setName(props.mapCharacter.character.name)
}
if (character.id === gameStore.character!.id) { if (character.id === gameStore.character!.id) {
mapStore.setCharacterLoaded(true) mapStore.setCharacterLoaded(true)

View File

@ -1,13 +1,14 @@
<template> <template>
<Image v-bind="imageProps" v-if="gameStore.getLoadedAsset(texture)" /> <Image v-bind="imageProps" v-if="gameStore.isTextureLoaded(texture)" />
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import type { MapCharacter, Sprite as SpriteT } from '@/application/types' import type { MapCharacter, Sprite as SpriteT } from '@/application/types'
import { loadSpriteTextures } from '@/composables/gameComposable' import { loadSpriteTextures } from '@/composables/gameComposable'
import { CharacterHairStorage, CharacterTypeStorage, SpriteStorage } from '@/storage/storages'
import { useGameStore } from '@/stores/gameStore' import { useGameStore } from '@/stores/gameStore'
import { Image, useScene } from 'phavuer' import { Image, useScene } from 'phavuer'
import { computed } from 'vue' import { computed, onMounted, ref } from 'vue'
const props = defineProps<{ const props = defineProps<{
mapCharacter: MapCharacter mapCharacter: MapCharacter
@ -17,21 +18,21 @@ const props = defineProps<{
const gameStore = useGameStore() const gameStore = useGameStore()
const scene = useScene() const scene = useScene()
const hairSpriteId = ref('')
const sprite = ref<SpriteT | null>(null)
const texture = computed(() => { const texture = computed(() => {
const { rotation, characterHair } = props.mapCharacter.character const { rotation } = props.mapCharacter.character
const spriteId = characterHair?.sprite?.id
const direction = [0, 6].includes(rotation) ? 'back' : 'front' const direction = [0, 6].includes(rotation) ? 'back' : 'front'
return `${spriteId}-${direction}` return `${hairSpriteId.value}-${direction}`
}) })
const isFlippedX = computed(() => [6, 4].includes(props.mapCharacter.character.rotation ?? 0)) const isFlippedX = computed(() => [6, 4].includes(props.mapCharacter.character.rotation ?? 0))
const imageProps = computed(() => { const imageProps = computed(() => {
// Get the current sprite action based on direction
const direction = [0, 6].includes(props.mapCharacter.character.rotation ?? 0) ? 'back' : 'front' const direction = [0, 6].includes(props.mapCharacter.character.rotation ?? 0) ? 'back' : 'front'
const spriteAction = props.mapCharacter.character.characterHair?.sprite?.spriteActions?.find((spriteAction) => spriteAction.action === direction) const spriteAction = sprite.value?.spriteActions?.find((spriteAction) => spriteAction.action === direction)
return { return {
depth: 1, depth: 1,
@ -39,13 +40,19 @@ const imageProps = computed(() => {
originY: Number(spriteAction?.originY) ?? 0, originY: Number(spriteAction?.originY) ?? 0,
flipX: isFlippedX.value, flipX: isFlippedX.value,
texture: texture.value, texture: texture.value,
y: props.mapCharacter.isMoving ? Math.floor(Date.now() / 250) % 2 : 0 y: props.currentY,
x: props.currentX
} }
}) })
loadSpriteTextures(scene, props.mapCharacter.character.characterHair?.sprite as SpriteT) onMounted(async () => {
.then(() => {}) const characterHairStorage = new CharacterHairStorage()
.catch((error) => { const spriteId = await characterHairStorage.getSpriteId(props.mapCharacter.character.characterHair!)
console.error('Error loading texture:', error) if (!spriteId) return
hairSpriteId.value = spriteId
const spriteStorage = new SpriteStorage()
sprite.value = await spriteStorage.get(spriteId)
await loadSpriteTextures(scene, spriteId)
}) })
</script> </script>

View File

@ -40,4 +40,9 @@ export class CharacterHairStorage extends BaseStorage<any> {
constructor() { constructor() {
super('characterHairs', 'id, name, createdAt, updatedAt') super('characterHairs', 'id, name, createdAt, updatedAt')
} }
async getSpriteId(characterTypeId: string) {
const characterType = await this.get(characterTypeId)
return characterType?.sprite
}
} }