This commit is contained in:
Jose Conde
2024-07-17 22:52:07 +02:00
parent 4e75c3af77
commit 54bd7f3840
18 changed files with 242 additions and 79 deletions

View File

@ -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(() => {

View File

@ -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%;
}

View File

@ -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']

View File

@ -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])
}

View File

@ -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 = []

View File

@ -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)
}

View File

@ -44,5 +44,7 @@
"starting_game": "Starting game...",
"your-turn": "Your turn!",
"player-turn": "{0}'s turn!"
}
},
"back": "Back",
"session-name": "Session Name"
}

View File

@ -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"
}

View File

@ -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'

View File

@ -51,7 +51,7 @@ const router = createRouter({
],
},
{
path: '/game:id',
path: '/game/:id',
component: AuthenticatedLayout,
children: [
{

View File

@ -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>

View File

@ -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>