Moved game components into a new folder, working proof of concept hair customisation

This commit is contained in:
2024-11-23 16:47:41 +01:00
parent ee3e1b55cb
commit ab97e27f27
11 changed files with 68 additions and 29 deletions

View File

@ -16,7 +16,12 @@
<div class="flex w-full h-[400px] border border-solid border-gray-500 rounded-md rounded-tl-none bg-gray">
<div class="w-1/3 h-full bg-[url('/assets/ui-texture.png')] bg-no-repeat bg-cover bg-center border-0 border-r border-solid border-gray-500 rounded-bl-md relative">
<div class="absolute right-full -top-px flex gap-1 flex-col">
<div v-for="character in characters" :key="character.id" class="character relative rounded-l border border-solid border-gray-500 w-9 h-[50px] bg-[url('/assets/ui-texture.png')] after:absolute after:w-full after:h-px after:bg-gray-500" :class="{ active: selected_character == character.id }">
<div
v-for="character in characters"
:key="character.id"
class="character relative rounded-l border border-solid border-gray-500 w-9 h-[50px] bg-[url('/assets/ui-texture.png')] after:absolute after:w-full after:h-px after:bg-gray-500"
:class="{ active: selected_character == character.id }"
>
<img src="/assets/avatar/default/head.png" class="w-9 h-9 object-contain absolute top-1/2 -translate-y-1/2" alt="Player head" />
<input class="h-full w-full absolute m-0 z-10 hover:cursor-pointer focus-visible:outline-offset-0" type="radio" name="character" :value="character.id" v-model="selected_character" />
</div>
@ -39,10 +44,10 @@
<img src="/assets/icons/triangle-icon.svg" class="w-3 h-3.5 -scale-x-100" alt="Arrow right" />
</button>
</div>
<!-- <div class="flex justify-between w-[190px]">-->
<!-- &lt;!&ndash; TODO: replace with color swatches &ndash;&gt;-->
<!-- <button v-for="n in 9" class="w-4 h-4 rounded-sm bg-white"></button>-->
<!-- </div>-->
<!-- <div class="flex justify-between w-[190px]">-->
<!-- &lt;!&ndash; TODO: replace with color swatches &ndash;&gt;-->
<!-- <button v-for="n in 9" class="w-4 h-4 rounded-sm bg-white"></button>-->
<!-- </div>-->
</div>
<!-- TODO: update gender on (selected) character -->
<div class="flex justify-between w-[190px]">
@ -66,8 +71,18 @@
<button class="bg-gray border border-solid border-gray-500 min-w-9 max-w-9 min-h-9 max-h-9 p-2 rounded-sm hover:bg-gray-500 hover:border-gray-400 focus-visible:outline-none focus-visible:border-gray-300 focus-visible:bg-gray-500">
<img src="/assets/icons/x-button-gray.svg" class="w-4 h-4 m-auto" alt="Male symbol" />
</button>
<!-- TODO: replace with hairstyles -->
<button v-for="n in 30" class="bg-gray border border-solid border-gray-500 min-w-9 max-w-9 min-h-9 max-h-9 p-2 rounded-sm hover:bg-gray-500 hover:border-gray-400 focus-visible:outline-none focus-visible:border-gray-300 focus-visible:bg-gray-500"></button>
<!-- TODO #255: make radio button so we can set a value, do the same with swatches -->
<button
v-for="hair in hairs"
class="border border-solid border-gray-500 min-w-9 max-w-9 min-h-9 max-h-9 p-2 rounded-sm hover:border-gray-400 focus-visible:outline-none focus-visible:border-gray-300 focus-visible:bg-gray-500"
@click="selectedHair = hair"
:class="{
'bg-cyan': hair.id === selectedHair?.id,
'bg-gray-500 hover:bg-gray-500': hair.id !== selectedHair?.id
}"
>
<img class="w-4 h-4 m-auto" :src="config.server_endpoint + '/assets/sprites/' + hair.spriteId + '/front.png'" alt="Male symbol" />
</button>
</div>
</div>
<div class="flex flex-col gap-3 w-full">
@ -103,7 +118,7 @@
<form method="post" @submit.prevent="create" class="h-full flex flex-col justify-between">
<div class="form-field-full">
<label for="name" class="text-white">Nickname</label>
<input class="input-field" v-model="name" name="name" id="name" placeholder="Enter a nickname.." />
<input class="input-field" v-model="name" name="name" id="name" placeholder="Enter a nickname..." />
</div>
<div class="grid grid-flow-col justify-stretch gap-4">
<button type="button" class="btn-empty py-1.5 px-4 inline-block" @click.prevent="isModalOpen = false">Cancel</button>
@ -129,10 +144,11 @@
</template>
<script setup lang="ts">
import config from '@/config'
import { useGameStore } from '@/stores/gameStore'
import { onBeforeUnmount, onMounted, ref } from 'vue'
import { onBeforeUnmount, ref, watch } from 'vue'
import Modal from '@/components/utilities/Modal.vue'
import { type Character as CharacterT } from '@/types'
import { type Character as CharacterT, type CharacterHair } from '@/types'
import ConfirmationModal from '@/components/utilities/ConfirmationModal.vue'
const gameStore = useGameStore()
@ -140,25 +156,39 @@ const isLoading = ref(true)
const characters = ref([] as CharacterT[])
const deletingCharacter = ref(null as CharacterT | null)
const hairs = ref([] as CharacterHair[])
const selectedHair = ref(null as CharacterHair | null)
watch(selectedHair, (hair: CharacterHair | null) => {
console.log(hair)
})
// Fetch characters
gameStore.connection?.on('character:list', (data: any) => {
characters.value = data
isLoading.value = false
// Fetch hairs
// @TODO: This is hacky, we should have a better way to do this
gameStore.connection?.emit('character:hair:list', {}, (data: CharacterHair[]) => {
console.log(data)
hairs.value = data
})
})
onMounted(async () => {
// wait 0.75 sec
setTimeout(() => {
gameStore.connection?.emit('character:list')
isLoading.value = false
}, 750)
})
setTimeout(() => {
gameStore.connection?.emit('character:list')
}, 750)
// Select character logics
const selected_character = ref(null)
function select_character() {
if (!selected_character.value) return
deletingCharacter.value = null
gameStore.connection?.emit('character:connect', { characterId: selected_character.value })
gameStore.connection?.emit('character:connect', {
characterId: selected_character.value,
hairId: selectedHair.value?.id
})
gameStore.connection?.on('character:connect', (data: CharacterT) => gameStore.setCharacter(data))
}