forked from noxious/client
Moved map character network event logic into characters component, added playAnimation function to characterComposable, finished attack animation
This commit is contained in:
parent
0c9a41c286
commit
6c7864b4d4
@ -28,7 +28,7 @@ const gameStore = useGameStore()
|
||||
const mapStore = useMapStore()
|
||||
const scene = useScene()
|
||||
|
||||
const { characterContainer, characterSprite, currentPositionX, currentPositionY, isometricDepth, isFlippedX, updatePosition, calcDirection, updateSprite, initializeSprite, cleanup } = useCharacterSpriteComposable(scene, props.tileMap, props.mapCharacter)
|
||||
const { characterContainer, characterSprite, currentPositionX, currentPositionY, isometricDepth, isFlippedX, updatePosition, playAnimation, calcDirection, updateSprite, initializeSprite, cleanup } = useCharacterSpriteComposable(scene, props.tileMap, props.mapCharacter)
|
||||
|
||||
const handlePositionUpdate = (newValues: any, oldValues: any) => {
|
||||
if (!newValues) return
|
||||
@ -51,7 +51,16 @@ watch(
|
||||
rotation: props.mapCharacter.character.rotation,
|
||||
isAttacking: props.mapCharacter.isAttacking
|
||||
}),
|
||||
handlePositionUpdate
|
||||
(oldValues, newValues) => {
|
||||
handlePositionUpdate(oldValues, newValues)
|
||||
|
||||
if (props.mapCharacter.isAttacking) {
|
||||
// Play attack animation
|
||||
playAnimation('attack')
|
||||
// Disable attack immediately after playing the animation
|
||||
mapStore.updateCharacterProperty(props.mapCharacter.character.id, 'isAttacking', false)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
onMounted(async () => {
|
||||
|
@ -3,12 +3,44 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { MapCharacter, UUID } from '@/application/types'
|
||||
import Character from '@/components/game/character/Character.vue'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useMapStore } from '@/stores/mapStore'
|
||||
import { onUnmounted } from 'vue'
|
||||
|
||||
const gameStore = useGameStore()
|
||||
const mapStore = useMapStore()
|
||||
|
||||
const props = defineProps<{
|
||||
tileMap: Phaser.Tilemaps.Tilemap
|
||||
}>()
|
||||
|
||||
gameStore.connection?.on('map:character:join', async (data: MapCharacter) => {
|
||||
mapStore.addCharacter(data)
|
||||
})
|
||||
|
||||
gameStore.connection?.on('map:character:leave', (characterId: UUID) => {
|
||||
mapStore.removeCharacter(characterId)
|
||||
})
|
||||
|
||||
gameStore.connection?.on('map:character:move', (data: { characterId: UUID; positionX: number; positionY: number; rotation: number; isMoving: boolean }) => {
|
||||
mapStore.updateCharacterPosition(data)
|
||||
// @TODO: Replace with universal class, composable or store
|
||||
if (data.characterId === gameStore.character?.id) {
|
||||
gameStore.character!.positionX = data.positionX
|
||||
gameStore.character!.positionY = data.positionY
|
||||
gameStore.character!.rotation = data.rotation
|
||||
}
|
||||
})
|
||||
|
||||
gameStore.connection?.on('map:character:attack', (characterId: UUID) => {
|
||||
mapStore.updateCharacterProperty(characterId, 'isAttacking', true)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
gameStore.connection?.off('map:character:join')
|
||||
gameStore.connection?.off('map:character:leave')
|
||||
gameStore.connection?.off('map:character:move')
|
||||
})
|
||||
</script>
|
||||
|
@ -5,7 +5,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { MapCharacter, mapLoadData, UUID } from '@/application/types'
|
||||
import type { mapLoadData } from '@/application/types'
|
||||
import { unduplicateArray } from '@/application/utilities'
|
||||
import Characters from '@/components/game/map/Characters.vue'
|
||||
import MapTiles from '@/components/game/map/MapTiles.vue'
|
||||
@ -33,28 +33,6 @@ gameStore.connection?.on('map:character:teleport', async (data: mapLoadData) =>
|
||||
mapStore.setCharacters(data.characters)
|
||||
})
|
||||
|
||||
gameStore.connection?.on('map:character:join', async (data: MapCharacter) => {
|
||||
mapStore.addCharacter(data)
|
||||
})
|
||||
|
||||
gameStore.connection?.on('map:character:leave', (characterId: UUID) => {
|
||||
mapStore.removeCharacter(characterId)
|
||||
})
|
||||
|
||||
gameStore.connection?.on('map:character:attack', (characterId: UUID) => {
|
||||
mapStore.updateCharacterProperty(characterId, 'isAttacking', true)
|
||||
})
|
||||
|
||||
gameStore.connection?.on('map:character:move', (data: { characterId: UUID; positionX: number; positionY: number; rotation: number; isMoving: boolean }) => {
|
||||
mapStore.updateCharacterPosition(data)
|
||||
// @TODO: Replace with universal class, composable or store
|
||||
if (data.characterId === gameStore.character?.id) {
|
||||
gameStore.character!.positionX = data.positionX
|
||||
gameStore.character!.positionY = data.positionY
|
||||
gameStore.character!.rotation = data.rotation
|
||||
}
|
||||
})
|
||||
|
||||
async function initialize() {
|
||||
if (!mapStore.mapId) return
|
||||
|
||||
@ -87,8 +65,5 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
gameStore.connection?.off('map:character:teleport')
|
||||
gameStore.connection?.off('map:character:join')
|
||||
gameStore.connection?.off('map:character:leave')
|
||||
gameStore.connection?.off('map:character:move')
|
||||
})
|
||||
</script>
|
||||
|
@ -59,6 +59,26 @@ export function useCharacterSpriteComposable(scene: Phaser.Scene, tilemap: Phase
|
||||
})
|
||||
}
|
||||
|
||||
const playAnimation = (animation: string, loop = false) => {
|
||||
if (!characterSprite.value || !characterSpriteId.value) return
|
||||
|
||||
const fullAnimationName = `${characterSpriteId.value}-${animation}_${currentDirection.value}`
|
||||
|
||||
// Remove any existing animation complete listeners
|
||||
characterSprite.value.off(Phaser.Animations.Events.ANIMATION_COMPLETE)
|
||||
|
||||
// Add new listener
|
||||
characterSprite.value.on(Phaser.Animations.Events.ANIMATION_COMPLETE, () => {
|
||||
characterSprite.value!.setFrame(0)
|
||||
characterSprite.value!.setTexture(charTexture.value)
|
||||
})
|
||||
|
||||
characterSprite.value.anims.play({
|
||||
key: fullAnimationName,
|
||||
repeat: loop ? -1 : 0
|
||||
})
|
||||
}
|
||||
|
||||
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
|
||||
@ -125,6 +145,7 @@ export function useCharacterSpriteComposable(scene: Phaser.Scene, tilemap: Phase
|
||||
isometricDepth,
|
||||
isFlippedX,
|
||||
updatePosition,
|
||||
playAnimation,
|
||||
calcDirection,
|
||||
updateSprite,
|
||||
initializeSprite,
|
||||
|
@ -27,7 +27,7 @@ export const useMapStore = defineStore('map', {
|
||||
addCharacter(character: MapCharacter) {
|
||||
this.characters.push(character)
|
||||
},
|
||||
updateCharacterProperty<K extends keyof MapCharacter>(characterId: UUID, property: K, value: MapCharacter[K]) {
|
||||
updateCharacterProperty<K extends keyof MapCharacter>(characterId: string, property: K, value: MapCharacter[K]) {
|
||||
const character = this.characters.find((char) => char.character.id === characterId)
|
||||
if (character) {
|
||||
character[property] = value
|
||||
|
Loading…
x
Reference in New Issue
Block a user