98 lines
3.4 KiB
Vue
98 lines
3.4 KiB
Vue
<script setup>
|
|
import { useGameStore } from '@/stores/game';
|
|
import { useBotStore } from '@/stores/bot'
|
|
import { useWebsocketStore } from '@/stores/websocket';
|
|
import boardConstructor from '@/classes/boardConstructor'
|
|
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
|
|
import { storeToRefs } from 'pinia'
|
|
import Scrollable from '@/classes/scrollable';
|
|
import router from "@/router";
|
|
import { onBeforeMount } from 'vue';
|
|
const game = useGameStore()
|
|
if (game.createdAt == null) {
|
|
router.replace({name:'index'})
|
|
}
|
|
|
|
const board = new boardConstructor(game.boardSize, game.getAvailableItems())
|
|
//Board cells in browser MB not needed
|
|
const playerView = ref()
|
|
const scrollPlayer = new Scrollable(playerView)
|
|
//Init player items
|
|
if (Object.keys(game.player.items).length <= 0) game.player.items = board.generateItems()
|
|
//Generate board
|
|
const generate = () => {
|
|
game.player.items = board.generateBoard(game.player.items)
|
|
}
|
|
//Set ready status for player
|
|
const ready = () => {
|
|
if (game.mode == 'single') useBotStore().generate()
|
|
if (board.isAllItemsReady(game.player.items)) game.ready()
|
|
}
|
|
const copyJoinLink = async () => {
|
|
try {
|
|
await navigator.clipboard.writeText(window.location.origin + '/join/' + game.id);
|
|
} catch (err) {
|
|
console.error('Failed to copy: ', err);
|
|
}
|
|
}
|
|
const drawCell = (row, col) => {
|
|
let classes = ''
|
|
let cell = ((row * game.boardSize) + col) - 1
|
|
let item = Object.values(game.player.items).filter((item) => item.cells.includes(cell))[0]
|
|
if (item != undefined) {
|
|
classes += ' ' + item.type + '-' + item.name
|
|
}
|
|
let margin = Object.values(game.player.items).filter((item) => item.marginCells.includes(cell))[0]
|
|
if (margin != undefined) {
|
|
classes += ' margin'
|
|
}
|
|
return classes
|
|
}
|
|
//Watch players changes for start game
|
|
const { player, opponent } = storeToRefs(game)
|
|
watch(player, () => { game.start() }, { deep: true, immediate: true })
|
|
watch(opponent, () => { game.start() }, { deep: true, immediate: true })
|
|
|
|
onMounted(() => {
|
|
if (game.mode != 'single') useWebsocketStore().init(game.id)
|
|
})
|
|
onBeforeMount(() => {
|
|
|
|
})
|
|
onBeforeUnmount(() => {
|
|
useWebsocketStore().disconnect()
|
|
})
|
|
|
|
</script>
|
|
|
|
<template>
|
|
<div class="lobby">
|
|
<div class="lobby-buttons">
|
|
<button v-if="game.player.status == 'lobby'" class="button-lobby" @click="generate()">{{ $t("button.generate") }}</button>
|
|
<button v-if="game.player.status == 'ready'" class="button-lobby" @click="copyJoinLink()">{{ $t("button.copyLink") }}</button>
|
|
<button class="button-lobby" @click="ready()">{{ game.player.status == 'ready' ? $t("button.cancel") : $t("button.ready") }}</button>
|
|
</div>
|
|
<div class="lake-border">
|
|
<div class="player-view" ref="playerView"
|
|
@mousedown="scrollPlayer.start($event)"
|
|
@mousemove="scrollPlayer.move($event)"
|
|
@mouseup="scrollPlayer.end()"
|
|
@touchstart="scrollPlayer.start($event)"
|
|
@touchmove="scrollPlayer.move($event)"
|
|
@touchend="scrollPlayer.end()"
|
|
>
|
|
<div class="lake">
|
|
<div v-for="key, row in game.boardSize" class="lake-row" :key="'row-' + row">
|
|
<div v-for="col in game.boardSize" class="lake-cell" :class="drawCell(row, col)"
|
|
:key="game.opponent.id + '-cell-' + (col + (row * game.boardSize))"
|
|
>{{ col + (row * game.boardSize) }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
|
|
</style> |