0.1.4
This commit is contained in:
31
src/App.vue
31
src/App.vue
@ -3,6 +3,7 @@ import { inject, onMounted, onUnmounted } from 'vue'
|
||||
import { RouterView } from 'vue-router'
|
||||
import type { AuthenticationService } from './services/AuthenticationService'
|
||||
import { useEventBusStore } from './stores/eventBus'
|
||||
import { sound } from '@pixi/sound'
|
||||
|
||||
const auth: AuthenticationService = inject<AuthenticationService>('auth') as AuthenticationService
|
||||
auth.fromStorage()
|
||||
@ -17,8 +18,38 @@ const handleBeforeUnload = (evt: any) => {
|
||||
// console.log('location.href :>> ', location.pathname)
|
||||
}
|
||||
|
||||
// document.addEventListener('visibilitychange', () => {
|
||||
// console.log('visibilitychange')
|
||||
// let playingOnHide = false
|
||||
// if (document.hidden) {
|
||||
// playingOnHide = true
|
||||
// sound.pauseAll()
|
||||
// } else {
|
||||
// // Page became visible! Resume playing if audio was "playing on hide"
|
||||
// if (playingOnHide) {
|
||||
// sound.resumeAll()
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
|
||||
// const soundContextResume = () => {
|
||||
// const context = sound.context.audioContext
|
||||
// if (context.state === 'suspended' || context.state === 'interrupted') {
|
||||
// context.resume()
|
||||
// }
|
||||
// }
|
||||
|
||||
// document.addEventListener('click', function (event) {
|
||||
// console.log('click document :>> ', event)
|
||||
// console.log('screen :>> ', screen)
|
||||
// // if (event.target instanceof HTMLButtonElement) {
|
||||
// // sound.play('click')
|
||||
// // }
|
||||
// })
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener('beforeunload', handleBeforeUnload)
|
||||
// window.addEventListener('focus', soundContextResume)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
|
@ -1,9 +1,17 @@
|
||||
:root {
|
||||
/* bulma color variables */
|
||||
--bulma-primary-h: 40deg;
|
||||
--bulma-primary-s: 48%;
|
||||
--bulma-primary-l: 48%;
|
||||
--bulma-info-h: 168deg;
|
||||
--bulma-info-s: 58%;
|
||||
--bulma-info-l: 28%;
|
||||
--bulma-primary-l: 38%;
|
||||
--bulma-link-h: 36deg;
|
||||
--bulma-link-s: 19%;
|
||||
--bulma-link-l: 16%;
|
||||
--bulma-info-h: 192deg;
|
||||
--bulma-info-l: 34%;
|
||||
--bulma-success-s: 52%;
|
||||
--bulma-success-l: 38%;
|
||||
--bulma-warning-h: 58deg;
|
||||
--bulma-warning-s: 61%;
|
||||
--bulma-warning-l: 41%;
|
||||
--bulma-danger-s: 74%;
|
||||
--bulma-danger-l: 37%;
|
||||
}
|
||||
|
@ -3,11 +3,20 @@ export const DEFAULT_CONTAINER_OPTIONS = {
|
||||
height: 100,
|
||||
x: 0,
|
||||
y: 0,
|
||||
visible: true
|
||||
visible: true,
|
||||
}
|
||||
export const ORIENTATION_ANGLES: { [key: string]: number } = {
|
||||
north: 0,
|
||||
east: Math.PI / 2,
|
||||
south: Math.PI,
|
||||
west: (3 * Math.PI) / 2
|
||||
west: (3 * Math.PI) / 2,
|
||||
}
|
||||
|
||||
export const DIRECTION_INDEXES: { [key: string]: number } = {
|
||||
north: 0,
|
||||
east: 1,
|
||||
south: 2,
|
||||
west: 3,
|
||||
}
|
||||
|
||||
export const DIRECTIONS = ['north', 'east', 'south', 'west']
|
||||
|
@ -99,8 +99,6 @@ export async function wait(ms: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms))
|
||||
}
|
||||
|
||||
export const DIRECTIONS = ['north', 'east', 'south', 'west']
|
||||
|
||||
export function isTilePair(tile: TileDto): boolean {
|
||||
return !!(tile.pips && tile.pips[0] === tile.pips[1])
|
||||
}
|
||||
|
@ -2,11 +2,11 @@ import { Application, Container, EventEmitter, Text, Ticker } from 'pixi.js'
|
||||
import { Scale, type ScaleFunction } from '@/game/utilities/scale'
|
||||
import type { AnimationOptions, Movement, PlayerDto, TileDto } from '@/common/interfaces'
|
||||
import { Tile } from '@/game/Tile'
|
||||
import { DIRECTIONS, createContainer, isTilePair } from '@/common/helpers'
|
||||
import { createContainer, isTilePair } from '@/common/helpers'
|
||||
import { createText } from '@/game/utilities/fonts'
|
||||
import { LoggingService } from '@/services/LoggingService'
|
||||
import { GlowFilter } from 'pixi-filters'
|
||||
import { ORIENTATION_ANGLES } from '@/common/constants'
|
||||
import { DIRECTION_INDEXES, DIRECTIONS, ORIENTATION_ANGLES } from '@/common/constants'
|
||||
import type { OtherHand } from './OtherHand'
|
||||
import { sound } from '@pixi/sound'
|
||||
import { t } from '@/i18n'
|
||||
@ -181,6 +181,8 @@ export class Board extends EventEmitter {
|
||||
const tileDto = tile.toPlain()
|
||||
let direction = move.type === 'left' ? this.leftDirection : this.rightDirection
|
||||
|
||||
move.direction = this.hasSpaceToMove(move)
|
||||
|
||||
if (this.tiles.length === 0) {
|
||||
x = 0
|
||||
y = 0
|
||||
@ -592,6 +594,22 @@ export class Board extends EventEmitter {
|
||||
return [canPlayNorth, canPlayEast, canPlaySouth, canPlayWest]
|
||||
}
|
||||
|
||||
hasSpaceToMove(move: Movement): string | undefined {
|
||||
if (move.tile === undefined || move.direction === undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const nextValidMoves = this.nextTileValidMoves(move.tile, move.type)
|
||||
let index = DIRECTION_INDEXES[move.direction]
|
||||
let valid = nextValidMoves[index]
|
||||
while (!valid && index < nextValidMoves.length) {
|
||||
index++
|
||||
valid = nextValidMoves[index % nextValidMoves.length]
|
||||
}
|
||||
|
||||
return DIRECTIONS[index]
|
||||
}
|
||||
|
||||
clean() {
|
||||
this.tiles = []
|
||||
this.boneyard = []
|
||||
|
@ -81,8 +81,7 @@ export class Game extends EventEmitter {
|
||||
iniialStuff(app: Application) {
|
||||
app.stage.addChild(this.backgroundLayer)
|
||||
const background = new Sprite(Assets.get(`bg-${this.options.background}`))
|
||||
background.width = this.app.canvas.width
|
||||
background.height = this.app.canvas.height
|
||||
|
||||
this.backgroundLayer.addChild(background)
|
||||
}
|
||||
|
||||
|
@ -44,5 +44,7 @@
|
||||
"starting_game": "Starting game...",
|
||||
"your-turn": "Your turn!",
|
||||
"player-turn": "{0}'s turn!"
|
||||
}
|
||||
},
|
||||
"back": "Back",
|
||||
"session-name": "Session Name"
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
"welcome-to-the-user-username-s-home-page": "Bienvenido a la página de inicio de {0}",
|
||||
"available-sessions": "Sesiones disponibles",
|
||||
"background-color": "Color de fondo",
|
||||
"blue-fabric": "Fabrica azul",
|
||||
"blue-fabric": "Tela azul",
|
||||
"cancel": "Cancelar",
|
||||
"copy": "Copiar",
|
||||
"game": {
|
||||
@ -44,5 +44,7 @@
|
||||
"seed": "Semilla",
|
||||
"seed-session-seed": "Semilla: {0}",
|
||||
"start": "Comenzar",
|
||||
"yellow-fabric": "Tela amarilla"
|
||||
"yellow-fabric": "Tela amarilla",
|
||||
"back": "Volver",
|
||||
"session-name": "Nombre de la sesión"
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
import './assets/main.css'
|
||||
|
||||
import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
|
||||
import '../node_modules/bulma/css/bulma.css'
|
||||
import './assets/main.css'
|
||||
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
|
@ -51,7 +51,7 @@ const router = createRouter({
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/game:id',
|
||||
path: '/game/:id',
|
||||
component: AuthenticatedLayout,
|
||||
children: [
|
||||
{
|
||||
|
@ -15,7 +15,7 @@ let background = ref<string>('green')
|
||||
let teamed = ref<boolean>(false)
|
||||
let pointsToWin = ref<number>(100)
|
||||
let seed = ref<string>('')
|
||||
let sessionName = ref('Test Value')
|
||||
let sessionName = ref(`Test #${Date.now()}`)
|
||||
let matchSessions = ref<MatchSessionDto[]>([])
|
||||
let dataInterval: any
|
||||
|
||||
@ -130,7 +130,6 @@ async function deleteMatch(id: string) {
|
||||
async function loadData() {
|
||||
const listResponse = await gameService.listMatchSessions()
|
||||
matchSessions.value = listResponse.data
|
||||
sessionName.value = `Test #${Date.now()}`
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
@ -156,7 +155,7 @@ function copy(sessionSeed: string) {
|
||||
</h1>
|
||||
<div class="block" v-if="!isSessionStarted">
|
||||
<div class="field">
|
||||
<label class="label">{{ $t('name') }}</label>
|
||||
<label class="label">{{ $t('session-name') }}</label>
|
||||
<div class="control">
|
||||
<input
|
||||
type="text"
|
||||
@ -174,7 +173,7 @@ function copy(sessionSeed: string) {
|
||||
class="input"
|
||||
style="margin-bottom: 0"
|
||||
v-model="seed"
|
||||
placeholder="$t('seed-placeholder')"
|
||||
:placeholder="$t('seed-placeholder')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@ -226,53 +225,64 @@ function copy(sessionSeed: string) {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="buttons" v-if="isSessionStarted">
|
||||
<button class="button" @click="setPlayerReady">
|
||||
<span v-if="!readyForStart">{{ $t('ready') }}</span
|
||||
><span v-else>{{ $t('unready') }}</span>
|
||||
</button>
|
||||
<button class="button" @click="startMatch" v-if="amIHost && readyForStart">
|
||||
<span>{{ $t('start') }}</span>
|
||||
</button>
|
||||
<div class="block" v-if="isSessionStarted">
|
||||
<h2 class="title is-4">{{ sessionState?.name }}</h2>
|
||||
<h6 class="title is-size-5">Players</h6>
|
||||
<div v-for="player in sessionState?.players" :key="player.id">
|
||||
<p>{{ player.name }}</p>
|
||||
<p>{{ player.ready ? 'Ready' : 'Not ready' }}</p>
|
||||
</div>
|
||||
<div class="buttons mt-6">
|
||||
<button class="button" @click="setPlayerReady">
|
||||
<span v-if="!readyForStart">{{ $t('ready') }}</span
|
||||
><span v-else>{{ $t('unready') }}</span>
|
||||
</button>
|
||||
<button class="button" @click="startMatch" v-if="amIHost && readyForStart">
|
||||
<span>{{ $t('start') }}</span>
|
||||
</button>
|
||||
|
||||
<button class="button" @click="cancelMatch">
|
||||
<span>{{ $t('cancel') }}</span>
|
||||
</button>
|
||||
<button class="button" @click="cancelMatch">
|
||||
<span>{{ $t('cancel') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="section available-sessions">
|
||||
<section class="section available-sessions" v-if="!isSessionStarted">
|
||||
<h2 class="title is-4">{{ $t('available-sessions') }}</h2>
|
||||
<div class="block">
|
||||
<div v-if="matchSessions.length === 0">
|
||||
<p>{{ $t('no-sessions-available') }}</p>
|
||||
</div>
|
||||
<div v-else class="grid is-col-min-12">
|
||||
<div class="cell" v-for="session in matchSessions" :key="session.id">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<p class="title is-6">{{ session.name }}</p>
|
||||
<p>{{ $t('id-session-_id', [session._id]) }}</p>
|
||||
<p>{{ $t('players-session-players-length', [session.players.length]) }}</p>
|
||||
<p>
|
||||
{{ $t('seed-session-seed', [session.seed]) }}
|
||||
<button class="button is-small" @click="() => copy(session.seed)">
|
||||
{{ $t('copy') }}
|
||||
</button>
|
||||
</p>
|
||||
<p>{{ $t('status-session-status', [session.status]) }}</p>
|
||||
<div class="buttons is-centered mt-4"></div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<p class="card-footer-item">
|
||||
<a href="#" @click.once.prevent="() => joinMatch(session._id)">
|
||||
{{ $t('join') }}
|
||||
</a>
|
||||
</p>
|
||||
<p class="card-footer-item">
|
||||
<a href="#" @click.once.prevent="() => deleteMatch(session._id)">
|
||||
{{ $t('delete') }}
|
||||
</a>
|
||||
</p>
|
||||
<div v-else class="fixed-grid has-3-cols">
|
||||
<div class="grid">
|
||||
<div class="cell" v-for="session in matchSessions" :key="session.id">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<p class="title is-6">{{ session.name }}</p>
|
||||
<p>{{ $t('id-session-_id', [session._id]) }}</p>
|
||||
<p>{{ $t('players-session-players-length', [session.players.length]) }}</p>
|
||||
<p>
|
||||
{{ $t('seed-session-seed', [session.seed]) }}
|
||||
<button class="button is-small is-ghost" @click="() => copy(session.seed)">
|
||||
{{ $t('copy') }}
|
||||
</button>
|
||||
</p>
|
||||
<p>{{ $t('status-session-status', [session.status]) }}</p>
|
||||
<div class="buttons is-centered mt-6">
|
||||
<button
|
||||
class="button is-primary"
|
||||
@click.once.prevent="() => joinMatch(session._id)"
|
||||
>
|
||||
<span>{{ $t('join') }}</span>
|
||||
</button>
|
||||
<button
|
||||
class="button is-text"
|
||||
@click.once.prevent="() => deleteMatch(session._id)"
|
||||
>
|
||||
<span>{{ $t('delete') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -73,6 +73,11 @@ onBeforeMount(() => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="buttons">
|
||||
<button class="button is-primary" @click="router.push({ name: 'home' })">
|
||||
{{ $t('back') }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="section">
|
||||
<!-- <div>{{ matchSession }}</div> -->
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user