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 mapStore = useMapStore()
|
||||||
const scene = useScene()
|
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) => {
|
const handlePositionUpdate = (newValues: any, oldValues: any) => {
|
||||||
if (!newValues) return
|
if (!newValues) return
|
||||||
@ -51,7 +51,16 @@ watch(
|
|||||||
rotation: props.mapCharacter.character.rotation,
|
rotation: props.mapCharacter.character.rotation,
|
||||||
isAttacking: props.mapCharacter.isAttacking
|
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 () => {
|
onMounted(async () => {
|
||||||
|
@ -3,12 +3,44 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { MapCharacter, UUID } from '@/application/types'
|
||||||
import Character from '@/components/game/character/Character.vue'
|
import Character from '@/components/game/character/Character.vue'
|
||||||
|
import { useGameStore } from '@/stores/gameStore'
|
||||||
import { useMapStore } from '@/stores/mapStore'
|
import { useMapStore } from '@/stores/mapStore'
|
||||||
|
import { onUnmounted } from 'vue'
|
||||||
|
|
||||||
|
const gameStore = useGameStore()
|
||||||
const mapStore = useMapStore()
|
const mapStore = useMapStore()
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
tileMap: Phaser.Tilemaps.Tilemap
|
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>
|
</script>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { MapCharacter, mapLoadData, UUID } from '@/application/types'
|
import type { mapLoadData } from '@/application/types'
|
||||||
import { unduplicateArray } from '@/application/utilities'
|
import { unduplicateArray } from '@/application/utilities'
|
||||||
import Characters from '@/components/game/map/Characters.vue'
|
import Characters from '@/components/game/map/Characters.vue'
|
||||||
import MapTiles from '@/components/game/map/MapTiles.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)
|
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() {
|
async function initialize() {
|
||||||
if (!mapStore.mapId) return
|
if (!mapStore.mapId) return
|
||||||
|
|
||||||
@ -87,8 +65,5 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gameStore.connection?.off('map:character:teleport')
|
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>
|
</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 => {
|
const calcDirection = (oldPositionX: number, oldPositionY: number, newPositionX: number, newPositionY: number): Direction => {
|
||||||
if (newPositionY < oldPositionY || newPositionX < oldPositionX) return Direction.NEGATIVE
|
if (newPositionY < oldPositionY || newPositionX < oldPositionX) return Direction.NEGATIVE
|
||||||
if (newPositionX > oldPositionX || newPositionY > oldPositionY) return Direction.POSITIVE
|
if (newPositionX > oldPositionX || newPositionY > oldPositionY) return Direction.POSITIVE
|
||||||
@ -125,6 +145,7 @@ export function useCharacterSpriteComposable(scene: Phaser.Scene, tilemap: Phase
|
|||||||
isometricDepth,
|
isometricDepth,
|
||||||
isFlippedX,
|
isFlippedX,
|
||||||
updatePosition,
|
updatePosition,
|
||||||
|
playAnimation,
|
||||||
calcDirection,
|
calcDirection,
|
||||||
updateSprite,
|
updateSprite,
|
||||||
initializeSprite,
|
initializeSprite,
|
||||||
|
@ -27,7 +27,7 @@ export const useMapStore = defineStore('map', {
|
|||||||
addCharacter(character: MapCharacter) {
|
addCharacter(character: MapCharacter) {
|
||||||
this.characters.push(character)
|
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)
|
const character = this.characters.find((char) => char.character.id === characterId)
|
||||||
if (character) {
|
if (character) {
|
||||||
character[property] = value
|
character[property] = value
|
||||||
|
Loading…
x
Reference in New Issue
Block a user