working flow
This commit is contained in:
parent
1b058db6c0
commit
3755f2857a
@ -1,6 +1,7 @@
|
|||||||
import { Graphics, Container, Text } from 'pixi.js'
|
import { Graphics, Container, Text } from 'pixi.js'
|
||||||
import type { ContainerOptions, Dimension, TileDto } from './interfaces'
|
import type { ContainerOptions, Dimension, TileDto } from './interfaces'
|
||||||
import { DEFAULT_CONTAINER_OPTIONS } from './constants'
|
import { DEFAULT_CONTAINER_OPTIONS } from './constants'
|
||||||
|
import useClipboard from 'vue-clipboard3'
|
||||||
|
|
||||||
export function getColorBackground(container: Container, colorName: string, alpha: number = 0.5) {
|
export function getColorBackground(container: Container, colorName: string, alpha: number = 0.5) {
|
||||||
const graphics = new Graphics()
|
const graphics = new Graphics()
|
||||||
@ -22,6 +23,10 @@ export function createContainer(options: ContainerOptions) {
|
|||||||
if (opts.color) {
|
if (opts.color) {
|
||||||
rect.fill(opts.color)
|
rect.fill(opts.color)
|
||||||
}
|
}
|
||||||
|
if (opts.alpha) {
|
||||||
|
rect.alpha = opts.alpha
|
||||||
|
}
|
||||||
|
|
||||||
rect.visible = opts.visible
|
rect.visible = opts.visible
|
||||||
container.addChild(rect)
|
container.addChild(rect)
|
||||||
if (opts.parent) {
|
if (opts.parent) {
|
||||||
@ -78,6 +83,15 @@ export function createButton(
|
|||||||
return container
|
return container
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createCrosshair(container: Container, color: number = 0xff0000, d: Dimension) {
|
||||||
|
const verticalLine = new Graphics().moveTo(d.x, 0).lineTo(d.x, d.height).stroke(color)
|
||||||
|
const horizontalLine = new Graphics().moveTo(0, d.y).lineTo(d.width, d.y).stroke(color)
|
||||||
|
verticalLine.alpha = 0.2
|
||||||
|
horizontalLine.alpha = 0.2
|
||||||
|
container.addChild(verticalLine)
|
||||||
|
container.addChild(horizontalLine)
|
||||||
|
}
|
||||||
|
|
||||||
export async function wait(ms: number) {
|
export async function wait(ms: number) {
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms))
|
return new Promise((resolve) => setTimeout(resolve, ms))
|
||||||
}
|
}
|
||||||
@ -91,3 +105,8 @@ export function isTilePair(tile: TileDto): boolean {
|
|||||||
export function isTileVertical(tile: TileDto): boolean {
|
export function isTileVertical(tile: TileDto): boolean {
|
||||||
return tile.orientation === 'north' || tile.orientation === 'south'
|
return tile.orientation === 'north' || tile.orientation === 'south'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function copyToclipboard(value: string) {
|
||||||
|
const { toClipboard } = useClipboard()
|
||||||
|
toClipboard(value)
|
||||||
|
}
|
||||||
|
@ -74,6 +74,7 @@ export interface ContainerOptions {
|
|||||||
color?: number
|
color?: number
|
||||||
visible?: boolean
|
visible?: boolean
|
||||||
parent?: Container
|
parent?: Container
|
||||||
|
alpha?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Dimension {
|
export interface Dimension {
|
||||||
|
@ -1,31 +1,38 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { MatchSessionDto, GameDto, PlayerDto } from '@/common/interfaces'
|
import type { GameDto, PlayerDto } from '@/common/interfaces'
|
||||||
import { onMounted, onUnmounted, ref, watch, inject } from 'vue'
|
import { onMounted, onUnmounted, ref, inject, toRaw } from 'vue'
|
||||||
import { Game } from '@/game/Game'
|
import { Game } from '@/game/Game'
|
||||||
import { useGameStore } from '@/stores/game'
|
import { useGameStore } from '@/stores/game'
|
||||||
import { useEventBusStore } from '@/stores/eventBus'
|
import { useEventBusStore } from '@/stores/eventBus'
|
||||||
import type { LoggingService } from '@/services/LoggingService'
|
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
|
|
||||||
const logger: LoggingService = inject<LoggingService>('logger') as LoggingService
|
|
||||||
const emit = defineEmits(['move'])
|
|
||||||
const socketService: any = inject('socket')
|
const socketService: any = inject('socket')
|
||||||
|
|
||||||
const gameStore = useGameStore()
|
const gameStore = useGameStore()
|
||||||
const eventBus = useEventBusStore()
|
const eventBus = useEventBusStore()
|
||||||
const { playerState, sessionState, canMakeMove } = storeToRefs(gameStore)
|
const { playerState, sessionState } = storeToRefs(gameStore)
|
||||||
const { updateSessionState, updatePlayerState, updateGameState } = gameStore
|
const { updateGameState } = gameStore
|
||||||
|
|
||||||
|
const minScreenWidth = 800
|
||||||
|
const minScreenHeight = 700
|
||||||
|
|
||||||
|
let screenWidth = window.innerWidth - 10
|
||||||
|
let screenHeight = window.innerHeight - 10
|
||||||
|
|
||||||
|
if (screenWidth < minScreenWidth) screenWidth = minScreenWidth
|
||||||
|
if (screenHeight < minScreenHeight) screenHeight = minScreenHeight
|
||||||
|
|
||||||
|
const boardScale = screenWidth > 1200 ? 0.8 : screenWidth > 1200 ? 0.7 : 0.6
|
||||||
|
|
||||||
let appEl = ref<HTMLElement | null>(null)
|
let appEl = ref<HTMLElement | null>(null)
|
||||||
|
|
||||||
const game = new Game(
|
const game = new Game(
|
||||||
{
|
{
|
||||||
width: 1200,
|
width: screenWidth,
|
||||||
height: 650,
|
height: screenHeight,
|
||||||
boardScale: 0.7,
|
boardScale,
|
||||||
handScale: 1
|
handScale: 1
|
||||||
},
|
},
|
||||||
emit,
|
|
||||||
socketService,
|
socketService,
|
||||||
playerState.value?.id || '',
|
playerState.value?.id || '',
|
||||||
sessionState.value?.id || ''
|
sessionState.value?.id || ''
|
||||||
@ -61,36 +68,31 @@ onMounted(async () => {
|
|||||||
const canvas = await game.setup()
|
const canvas = await game.setup()
|
||||||
appEl.value.appendChild(canvas)
|
appEl.value.appendChild(canvas)
|
||||||
await game.preload()
|
await game.preload()
|
||||||
await game.start()
|
await game.start(sessionState?.value?.players)
|
||||||
|
|
||||||
eventBus.subscribe('server:game-finished', (data) => {
|
eventBus.subscribe('server:game-finished', (data) => {
|
||||||
console.log('server:game-finished :>> ', data)
|
|
||||||
game.gameFinished(data)
|
game.gameFinished(data)
|
||||||
})
|
})
|
||||||
|
|
||||||
eventBus.subscribe('server:server-player-move', (data) => {
|
eventBus.subscribe('server:server-player-move', (data) => {
|
||||||
console.log('server:player-move :>> ', data)
|
|
||||||
game.serverPlayerMove(data, playerState.value?.id ?? '')
|
game.serverPlayerMove(data, playerState.value?.id ?? '')
|
||||||
})
|
})
|
||||||
|
|
||||||
eventBus.subscribe('game:player-turn-started', (data: any) => {
|
eventBus.subscribe('game:player-turn-started', (data: any) => {
|
||||||
console.log('game:player-turn-started :>> ', data)
|
|
||||||
// game.setCanMakeMove(true)
|
// game.setCanMakeMove(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
eventBus.subscribe('server:hand-dealt', (playerState: PlayerDto) => {
|
eventBus.subscribe('server:hand-dealt', (data: { player: PlayerDto; gameState: GameDto }) => {
|
||||||
console.log('server:hand-dealt :>> ', playerState)
|
game.hand.update(data.player)
|
||||||
game.hand.update(playerState)
|
game.updateOtherHands(data.gameState)
|
||||||
})
|
})
|
||||||
|
|
||||||
eventBus.subscribe('server:next-turn', (gameState: GameDto) => {
|
eventBus.subscribe('server:next-turn', (gameState: GameDto) => {
|
||||||
console.log('server:next-turn :>> ', gameState)
|
|
||||||
updateGameState(gameState)
|
updateGameState(gameState)
|
||||||
game.setNextPlayer(gameState)
|
game.setNextPlayer(gameState)
|
||||||
})
|
})
|
||||||
|
|
||||||
eventBus.subscribe('server:match-finished', (data) => {
|
eventBus.subscribe('server:match-finished', (data) => {
|
||||||
console.log('server:match-finished :>> ', data)
|
|
||||||
game.matchFinished(data)
|
game.matchFinished(data)
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -115,7 +117,7 @@ onMounted(async () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
game.destroy()
|
//game.destroy()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1,27 +1,18 @@
|
|||||||
import {
|
import { Application, Assets, Container, EventEmitter, Sprite, Text, Ticker } from 'pixi.js'
|
||||||
Application,
|
|
||||||
Assets,
|
|
||||||
Container,
|
|
||||||
EventEmitter,
|
|
||||||
Graphics,
|
|
||||||
Sprite,
|
|
||||||
Text,
|
|
||||||
Ticker
|
|
||||||
} from 'pixi.js'
|
|
||||||
import { Scale, type ScaleFunction } from '@/game/utilities/scale'
|
import { Scale, type ScaleFunction } from '@/game/utilities/scale'
|
||||||
import type { AnimationOptions, Movement, PlayerDto, TileDto } from '@/common/interfaces'
|
import type { AnimationOptions, Movement, PlayerDto, TileDto } from '@/common/interfaces'
|
||||||
import { Tile } from '@/game/Tile'
|
import { Tile } from '@/game/Tile'
|
||||||
import { DIRECTIONS, createContainer, isTilePair } from '@/common/helpers'
|
import { DIRECTIONS, createContainer, createCrosshair, isTilePair } from '@/common/helpers'
|
||||||
import { createText } from '@/game/utilities/fonts'
|
import { createText } from '@/game/utilities/fonts'
|
||||||
import { LoggingService } from '@/services/LoggingService'
|
import { LoggingService } from '@/services/LoggingService'
|
||||||
import { inject } from 'vue'
|
|
||||||
import { GlowFilter } from 'pixi-filters'
|
import { GlowFilter } from 'pixi-filters'
|
||||||
import { ORIENTATION_ANGLES } from '@/common/constants'
|
import { ORIENTATION_ANGLES } from '@/common/constants'
|
||||||
|
import type { OtherHand } from './OtherHand'
|
||||||
|
|
||||||
export class Board extends EventEmitter {
|
export class Board extends EventEmitter {
|
||||||
private _scale: number = 1
|
private _scale: number = 1
|
||||||
private _canMove: boolean = false
|
private _canMove: boolean = false
|
||||||
private logger = inject<LoggingService>('logger')!
|
private logger: LoggingService = new LoggingService()
|
||||||
|
|
||||||
ticker: Ticker
|
ticker: Ticker
|
||||||
height: number
|
height: number
|
||||||
@ -50,6 +41,7 @@ export class Board extends EventEmitter {
|
|||||||
playerHand: Tile[] = []
|
playerHand: Tile[] = []
|
||||||
firstTile?: Tile
|
firstTile?: Tile
|
||||||
currentPlayer!: PlayerDto
|
currentPlayer!: PlayerDto
|
||||||
|
otherPlayerHands: OtherHand[] = []
|
||||||
|
|
||||||
constructor(app: Application) {
|
constructor(app: Application) {
|
||||||
super()
|
super()
|
||||||
@ -93,18 +85,19 @@ export class Board extends EventEmitter {
|
|||||||
visible: false
|
visible: false
|
||||||
})
|
})
|
||||||
|
|
||||||
const verticalLine = new Graphics()
|
createCrosshair(this.tilesContainer, 0xff0000, {
|
||||||
.moveTo(this.scaleX(0), 0)
|
width: this.width,
|
||||||
.lineTo(this.scaleX(0), this.height)
|
height: this.height,
|
||||||
.stroke(0xff0000)
|
x: this.scaleX(0),
|
||||||
const horizontalLine = new Graphics()
|
y: this.scaleY(0)
|
||||||
.moveTo(0, this.scaleY(0))
|
})
|
||||||
.lineTo(this.width, this.scaleY(0))
|
|
||||||
.stroke(0xff0000)
|
createCrosshair(this.interactionContainer, 0xffff00, {
|
||||||
verticalLine.alpha = 0.2
|
width: this.width,
|
||||||
horizontalLine.alpha = 0.2
|
height: this.height,
|
||||||
this.tilesContainer.addChild(verticalLine)
|
x: this.scaleX(0),
|
||||||
this.tilesContainer.addChild(horizontalLine)
|
y: this.scaleY(0)
|
||||||
|
})
|
||||||
|
|
||||||
this.textContainer = createContainer({
|
this.textContainer = createContainer({
|
||||||
width: this.width,
|
width: this.width,
|
||||||
@ -135,15 +128,6 @@ export class Board extends EventEmitter {
|
|||||||
this.calculateScale()
|
this.calculateScale()
|
||||||
}
|
}
|
||||||
|
|
||||||
get canMove() {
|
|
||||||
return this._canMove
|
|
||||||
}
|
|
||||||
|
|
||||||
set canMove(value: boolean) {
|
|
||||||
this._canMove = value
|
|
||||||
this.updateCanMoveText()
|
|
||||||
}
|
|
||||||
|
|
||||||
setPlayerHand(tiles: Tile[]) {
|
setPlayerHand(tiles: Tile[]) {
|
||||||
this.playerHand = tiles
|
this.playerHand = tiles
|
||||||
}
|
}
|
||||||
@ -153,12 +137,8 @@ export class Board extends EventEmitter {
|
|||||||
this.textContainer.addChild(createText(text, this.scaleX(0), 100))
|
this.textContainer.addChild(createText(text, this.scaleX(0), 100))
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateCanMoveText() {
|
async setPlayerTurn(player: PlayerDto) {
|
||||||
if (this.canMove) {
|
this.showText('Your turn!')
|
||||||
this.showText('Your turn!')
|
|
||||||
} else {
|
|
||||||
this.showText('Waiting for players')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async setServerPlayerTurn(currentPlayer: PlayerDto) {
|
async setServerPlayerTurn(currentPlayer: PlayerDto) {
|
||||||
@ -168,6 +148,9 @@ export class Board extends EventEmitter {
|
|||||||
async playerMove(move: any, playerId: string) {
|
async playerMove(move: any, playerId: string) {
|
||||||
const { move: lastMove } = move
|
const { move: lastMove } = move
|
||||||
if (lastMove === null) {
|
if (lastMove === null) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.emit('game:tile-animation-ended')
|
||||||
|
}, 500)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
@ -252,21 +235,46 @@ export class Board extends EventEmitter {
|
|||||||
tile.reScale(this.scale)
|
tile.reScale(this.scale)
|
||||||
this.tiles.push(tile)
|
this.tiles.push(tile)
|
||||||
|
|
||||||
|
await this.animateTile(tile, x, y, orientation, move)
|
||||||
|
this.emit('game:tile-animation-ended', tile.toPlain())
|
||||||
|
}
|
||||||
|
|
||||||
|
async animateTile(tile: Tile, x: number, y: number, orientation: string, move: Movement) {
|
||||||
|
const targetX = this.scaleX(x)
|
||||||
|
const targetY = this.scaleY(y)
|
||||||
const animation: AnimationOptions = {
|
const animation: AnimationOptions = {
|
||||||
x: this.scaleX(x),
|
x: targetX,
|
||||||
y: this.scaleY(y),
|
y: targetY,
|
||||||
rotation: ORIENTATION_ANGLES[orientation],
|
rotation: ORIENTATION_ANGLES[orientation],
|
||||||
duration: 20
|
duration: 20
|
||||||
}
|
}
|
||||||
|
const tempAlpha = tile.alpha
|
||||||
tile.setPosition(this.scaleX(x), this.scaleY(y))
|
tile.alpha = 0
|
||||||
|
const clonedTile = tile.clone()
|
||||||
|
clonedTile.addTo(this.tilesContainer)
|
||||||
|
const pos = this.getAnimationInitialPoosition(move)
|
||||||
|
clonedTile.setPosition(this.scaleX(pos.x), this.scaleY(pos.y))
|
||||||
|
await clonedTile.animateTo(animation)
|
||||||
|
clonedTile.removeFromParent()
|
||||||
tile.setOrientation(orientation)
|
tile.setOrientation(orientation)
|
||||||
|
tile.setPosition(targetX, targetY)
|
||||||
|
tile.alpha = tempAlpha
|
||||||
|
}
|
||||||
|
|
||||||
// tile.setPosition(this.scaleX(0), this.height + tile.height / 2)
|
getAnimationInitialPoosition(move: Movement): { x: number; y: number } {
|
||||||
// console.log('going to animate', tile.pips)
|
const otherHand = this.otherPlayerHands.find((h) => h.player?.id === move.playerId)
|
||||||
// await tile.animateTo(animation)
|
if (otherHand === undefined) {
|
||||||
// console.log('animated', tile.pips)
|
return { x: 0, y: this.scaleY.inverse(this.height + 50) }
|
||||||
this.emit('game:tile-animation-ended', tile.toPlain())
|
}
|
||||||
|
const position = otherHand.position
|
||||||
|
switch (position) {
|
||||||
|
case 'left':
|
||||||
|
return { x: this.scaleX.inverse(100), y: this.scaleY.inverse(100) }
|
||||||
|
case 'right':
|
||||||
|
return { x: 0, y: this.scaleY.inverse(100) }
|
||||||
|
case 'top':
|
||||||
|
return { x: this.scaleX.inverse(this.width - 100), y: this.scaleY.inverse(20) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getPlayedTile(id: string): Tile | undefined {
|
getPlayedTile(id: string): Tile | undefined {
|
||||||
@ -315,16 +323,14 @@ export class Board extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateBoard(move: Movement) {
|
async updateBoard(move: Movement, tile: Tile | undefined) {
|
||||||
try {
|
try {
|
||||||
const { tile: tileDto } = move
|
// const { tileDto: tileDto } = move
|
||||||
const tile = this.getTileInHand(tileDto?.id ?? '')
|
// const tile = this.getTileInHand(tileDto?.id ?? '')
|
||||||
|
this.movements.push(move)
|
||||||
if (tile === undefined) {
|
if (tile === undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.movements.push(move)
|
|
||||||
await this.addTile(tile, move)
|
await this.addTile(tile, move)
|
||||||
this.setFreeEnd(move)
|
this.setFreeEnd(move)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -5,17 +5,17 @@ import { Tile } from '@/game/Tile'
|
|||||||
import { Hand } from '@/game/Hand'
|
import { Hand } from '@/game/Hand'
|
||||||
import type { GameDto, Movement, PlayerDto, TileDto } from '@/common/interfaces'
|
import type { GameDto, Movement, PlayerDto, TileDto } from '@/common/interfaces'
|
||||||
import type { SocketIoClientService } from '@/services/SocketIoClientService'
|
import type { SocketIoClientService } from '@/services/SocketIoClientService'
|
||||||
import { useEventBusStore } from '@/stores/eventBus'
|
|
||||||
import { wait } from '@/common/helpers'
|
import { wait } from '@/common/helpers'
|
||||||
import { Actions } from 'pixi-actions'
|
import { Actions } from 'pixi-actions'
|
||||||
|
import { OtherHand } from './OtherHand'
|
||||||
|
|
||||||
export class Game {
|
export class Game {
|
||||||
public board!: Board
|
public board!: Board
|
||||||
public hand!: Hand
|
public hand!: Hand
|
||||||
private app: Application = new Application()
|
private app: Application = new Application()
|
||||||
private selectedTile: TileDto | undefined
|
private selectedTile: TileDto | undefined
|
||||||
private eventBus: any = useEventBusStore()
|
|
||||||
private currentMove: Movement | undefined
|
private currentMove: Movement | undefined
|
||||||
|
private otherHands: OtherHand[] = []
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private options: { boardScale: number; handScale: number; width: number; height: number } = {
|
private options: { boardScale: number; handScale: number; width: number; height: number } = {
|
||||||
@ -24,24 +24,29 @@ export class Game {
|
|||||||
width: 1200,
|
width: 1200,
|
||||||
height: 800
|
height: 800
|
||||||
},
|
},
|
||||||
private emit: any,
|
|
||||||
private socketService: SocketIoClientService,
|
private socketService: SocketIoClientService,
|
||||||
private playerId: string,
|
private playerId: string,
|
||||||
private sessionId: string
|
private sessionId: string
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async setup(): Promise<HTMLCanvasElement> {
|
async setup(): Promise<HTMLCanvasElement> {
|
||||||
const width = 1200
|
const width = this.options.width || 1200
|
||||||
const height = 800
|
const height = this.options.height || 800
|
||||||
|
|
||||||
await this.app.init({ width, height })
|
await this.app.init({ width, height })
|
||||||
this.app.ticker.add((tick) => Actions.tick(tick.deltaTime / 60))
|
this.app.ticker.add((tick) => Actions.tick(tick.deltaTime / 60))
|
||||||
return this.app.canvas
|
return this.app.canvas
|
||||||
}
|
}
|
||||||
|
|
||||||
async start() {
|
async start(players: PlayerDto[] = []) {
|
||||||
this.board = new Board(this.app)
|
this.board = new Board(this.app)
|
||||||
this.hand = new Hand(this.app)
|
this.hand = new Hand(this.app)
|
||||||
|
this.otherHands = [
|
||||||
|
new OtherHand(this.app, 'left'),
|
||||||
|
new OtherHand(this.app, 'top'),
|
||||||
|
new OtherHand(this.app, 'right')
|
||||||
|
]
|
||||||
|
this.initOtherHands(players)
|
||||||
this.hand.scale = this.options.handScale
|
this.hand.scale = this.options.handScale
|
||||||
this.board.scale = this.options.boardScale
|
this.board.scale = this.options.boardScale
|
||||||
this.setBoardEvents()
|
this.setBoardEvents()
|
||||||
@ -54,6 +59,32 @@ export class Game {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initOtherHands(players: PlayerDto[]) {
|
||||||
|
const myIndex = players.findIndex((player) => player.id === this.playerId)
|
||||||
|
const copy = [...players]
|
||||||
|
const cut = copy.splice(myIndex)
|
||||||
|
cut.shift()
|
||||||
|
const final = cut.concat(copy)
|
||||||
|
|
||||||
|
for (let i = 0; i < final.length; i++) {
|
||||||
|
const hand = this.otherHands[i]
|
||||||
|
hand.setPlayer(final[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
this.board.otherPlayerHands = this.otherHands
|
||||||
|
}
|
||||||
|
|
||||||
|
updateOtherHands(gameState: GameDto) {
|
||||||
|
const players = gameState.players
|
||||||
|
|
||||||
|
players.forEach((player) => {
|
||||||
|
const hand = this.otherHands.find((hand) => hand.player?.id === player.id)
|
||||||
|
if (hand) {
|
||||||
|
hand.setHand(player.hand)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async preload() {
|
async preload() {
|
||||||
await Assets.load(assets)
|
await Assets.load(assets)
|
||||||
}
|
}
|
||||||
@ -82,11 +113,11 @@ export class Game {
|
|||||||
sessionId: this.sessionId,
|
sessionId: this.sessionId,
|
||||||
move: move
|
move: move
|
||||||
})
|
})
|
||||||
await this.board.updateBoard(move)
|
await this.board.updateBoard(move, undefined)
|
||||||
})
|
})
|
||||||
|
|
||||||
this.hand.on('nextClick', () => {
|
this.hand.on('nextClick', () => {
|
||||||
this.socketService.sendMessage('client:set-player-ready', {
|
this.socketService.sendMessage('client:set-client-ready-for-next-game', {
|
||||||
userId: this.playerId,
|
userId: this.playerId,
|
||||||
sessionId: this.sessionId
|
sessionId: this.sessionId
|
||||||
})
|
})
|
||||||
@ -120,24 +151,18 @@ export class Game {
|
|||||||
return validEnds
|
return validEnds
|
||||||
}
|
}
|
||||||
|
|
||||||
public setCanMakeMove(value: boolean) {
|
|
||||||
this.hand.setCanMove(value, this.board.count === 0, this.board.freeEnds)
|
|
||||||
this.board.canMove = value
|
|
||||||
}
|
|
||||||
|
|
||||||
async setNextPlayer(state: GameDto) {
|
async setNextPlayer(state: GameDto) {
|
||||||
const currentPlayer = state?.currentPlayer!
|
const currentPlayer = state?.currentPlayer!
|
||||||
if (currentPlayer.id !== this.playerId) {
|
if (currentPlayer.id === this.playerId) {
|
||||||
this.setCanMakeMove(false)
|
this.hand.prepareForMove(this.board.count === 0, this.board.freeEnds)
|
||||||
this.board.setServerPlayerTurn(currentPlayer)
|
this.board.setPlayerTurn(currentPlayer)
|
||||||
} else {
|
} else {
|
||||||
this.setCanMakeMove(true)
|
this.board.setServerPlayerTurn(currentPlayer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private setBoardEvents() {
|
private setBoardEvents() {
|
||||||
this.board.on('game:board-left-action-click', async (data) => {
|
this.board.on('game:board-left-action-click', async (data) => {
|
||||||
console.log('left data :>> ', data)
|
|
||||||
if (this.selectedTile === undefined) return
|
if (this.selectedTile === undefined) return
|
||||||
const move: Movement = {
|
const move: Movement = {
|
||||||
tile: this.selectedTile,
|
tile: this.selectedTile,
|
||||||
@ -146,12 +171,11 @@ export class Game {
|
|||||||
...data
|
...data
|
||||||
}
|
}
|
||||||
this.currentMove = move
|
this.currentMove = move
|
||||||
this.hand.tileMoved(this.selectedTile)
|
const tile = this.hand.tileMoved(this.selectedTile)
|
||||||
await this.board.updateBoard({ ...move, tile: this.selectedTile })
|
await this.board.updateBoard({ ...move, tile: this.selectedTile }, tile)
|
||||||
})
|
})
|
||||||
|
|
||||||
this.board.on('game:board-right-action-click', async (data) => {
|
this.board.on('game:board-right-action-click', async (data) => {
|
||||||
console.log('right data :>> ', data)
|
|
||||||
if (this.selectedTile === undefined) return
|
if (this.selectedTile === undefined) return
|
||||||
const move: Movement = {
|
const move: Movement = {
|
||||||
tile: this.selectedTile,
|
tile: this.selectedTile,
|
||||||
@ -160,31 +184,25 @@ export class Game {
|
|||||||
...data
|
...data
|
||||||
}
|
}
|
||||||
this.currentMove = move
|
this.currentMove = move
|
||||||
this.hand.tileMoved(this.selectedTile)
|
const tile = this.hand.tileMoved(this.selectedTile)
|
||||||
await this.board.updateBoard({ ...move, tile: this.selectedTile })
|
await this.board.updateBoard({ ...move, tile: this.selectedTile }, tile)
|
||||||
})
|
})
|
||||||
|
|
||||||
this.board.on('game:tile-animation-ended', async (tile) => {
|
this.board.on('game:tile-animation-ended', async (tile) => {
|
||||||
console.log('animation ended', tile)
|
if (tile !== null && tile !== undefined && tile.playerId === this.playerId) {
|
||||||
if (tile.playerId === this.playerId) {
|
|
||||||
this.socketService.sendMessage('client:player-move', {
|
this.socketService.sendMessage('client:player-move', {
|
||||||
sessionId: this.sessionId,
|
sessionId: this.sessionId,
|
||||||
move: this.currentMove
|
move: this.currentMove
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
this.socketService.sendMessage('client:animation-ended', {
|
||||||
|
sessionId: this.sessionId,
|
||||||
|
userId: this.playerId
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendMoveEvent(move: Movement) {
|
|
||||||
// this.board.on('game:tile-animation-ended', async (tile) => {
|
|
||||||
// this.eventBus.publish('game:tile-animation-ended', tile)
|
|
||||||
// // this.socketService.sendMessageWithAck('client:tile-animation-ended', {
|
|
||||||
// // sessionId: this.sessionId,
|
|
||||||
// // tile
|
|
||||||
// // })
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
gameFinished(data: any) {
|
gameFinished(data: any) {
|
||||||
this.hand.gameFinished()
|
this.hand.gameFinished()
|
||||||
this.board.gameFinished(data)
|
this.board.gameFinished(data)
|
||||||
@ -197,6 +215,13 @@ export class Game {
|
|||||||
|
|
||||||
serverPlayerMove(data: any, playerId: string) {
|
serverPlayerMove(data: any, playerId: string) {
|
||||||
this.board.playerMove(data, playerId)
|
this.board.playerMove(data, playerId)
|
||||||
|
|
||||||
|
if (!(data.move === undefined || data.move === null)) {
|
||||||
|
const otherHand = this.otherHands.find((hand) => hand.player?.id === data.move.playerId)
|
||||||
|
if (otherHand) {
|
||||||
|
otherHand.update(data.move)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private removeBoardEvents() {
|
private removeBoardEvents() {
|
||||||
|
@ -88,30 +88,31 @@ export class Hand extends EventEmitter {
|
|||||||
this.scaleY = Scale([-scaleYSteps, scaleYSteps], [0, this.height])
|
this.scaleY = Scale([-scaleYSteps, scaleYSteps], [0, this.height])
|
||||||
}
|
}
|
||||||
|
|
||||||
setCanMove(value: boolean, isFirstMove: boolean, freeEnds?: [number, number]) {
|
prepareForMove(isFirstMove: boolean, freeEnds?: [number, number]) {
|
||||||
console.log('this.tiles :>> ', this.tiles.length)
|
this.availableTiles = isFirstMove
|
||||||
this.availableTiles =
|
? this.tiles
|
||||||
!value || isFirstMove
|
: this.tiles.filter((tile) => this.hasMoves(tile.toPlain(), freeEnds))
|
||||||
? this.tiles
|
if (this.availableTiles.length === 0) {
|
||||||
: this.tiles.filter((tile) => this.hasMoves(tile.toPlain(), freeEnds))
|
|
||||||
|
|
||||||
console.log('this.availableTiles :>> ', this.availableTiles.length)
|
|
||||||
if (value && this.availableTiles.length === 0) {
|
|
||||||
this.createPassButton()
|
this.createPassButton()
|
||||||
} else {
|
|
||||||
this.interactionsLayer.removeChild(this.buttonPass)
|
|
||||||
}
|
}
|
||||||
this.availableTiles.forEach((tile) => {
|
this.availableTiles.forEach((tile) => {
|
||||||
if (value) {
|
tile.animateTo({
|
||||||
tile.animateTo({
|
x: tile.x,
|
||||||
x: tile.x,
|
y: tile.y - 10
|
||||||
y: tile.y - 10
|
})
|
||||||
})
|
tile.interactive = true
|
||||||
// const action: Action = Actions.moveTo(tile.getSprite(), tile.x, tile.y - 10, 1,).play()
|
})
|
||||||
}
|
}
|
||||||
tile.interactive = value
|
|
||||||
|
afterMove() {
|
||||||
|
this.availableTiles.forEach((tile) => {
|
||||||
|
tile.animateTo({
|
||||||
|
x: tile.x,
|
||||||
|
y: tile.y + 10
|
||||||
|
})
|
||||||
|
tile.setPosition(tile.x, tile.y + 10)
|
||||||
|
tile.interactive = false
|
||||||
})
|
})
|
||||||
this._canMove = value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hasMoves(tile: TileDto, freeEnds?: [number, number]): boolean {
|
hasMoves(tile: TileDto, freeEnds?: [number, number]): boolean {
|
||||||
@ -166,20 +167,12 @@ export class Hand extends EventEmitter {
|
|||||||
selected.alpha = 0.7
|
selected.alpha = 0.7
|
||||||
}
|
}
|
||||||
|
|
||||||
public tileMoved(tileDto: TileDto) {
|
public tileMoved(tileDto: TileDto): Tile | undefined {
|
||||||
const tile = this.tiles.find((t) => t.id === tileDto.id)
|
const tile = this.tiles.find((t) => t.id === tileDto.id)
|
||||||
|
|
||||||
if (!tile) return
|
if (!tile) return
|
||||||
|
|
||||||
this.availableTiles
|
this.afterMove()
|
||||||
.filter((t) => t.id !== tileDto.id)
|
|
||||||
.forEach((t) => {
|
|
||||||
t.animateTo({
|
|
||||||
x: t.x,
|
|
||||||
y: t.y + 10
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
this.tiles = this.tiles.filter((t) => t.id !== tileDto.id)
|
this.tiles = this.tiles.filter((t) => t.id !== tileDto.id)
|
||||||
|
|
||||||
tile.interactive = false
|
tile.interactive = false
|
||||||
@ -187,6 +180,8 @@ export class Hand extends EventEmitter {
|
|||||||
tile.off('pointerdown')
|
tile.off('pointerdown')
|
||||||
tile.off('pointerover')
|
tile.off('pointerover')
|
||||||
tile.off('pointerout')
|
tile.off('pointerout')
|
||||||
|
this.tilesLayer.removeChild(tile.getSprite())
|
||||||
|
return tile
|
||||||
}
|
}
|
||||||
|
|
||||||
private createPassButton() {
|
private createPassButton() {
|
||||||
@ -195,7 +190,10 @@ export class Hand extends EventEmitter {
|
|||||||
this.buttonPass = createButton(
|
this.buttonPass = createButton(
|
||||||
'PASS',
|
'PASS',
|
||||||
{ x, y: this.height / 2, width: 50, height: 20 },
|
{ x, y: this.height / 2, width: 50, height: 20 },
|
||||||
() => this.emit('game:button-pass-click'),
|
() => {
|
||||||
|
this.interactionsLayer.removeChild(this.buttonPass)
|
||||||
|
this.emit('game:button-pass-click')
|
||||||
|
},
|
||||||
this.interactionsLayer
|
this.interactionsLayer
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
118
src/game/OtherHand.ts
Normal file
118
src/game/OtherHand.ts
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
import { LoggingService } from '@/services/LoggingService'
|
||||||
|
import { Application, Container, Sprite, Texture } from 'pixi.js'
|
||||||
|
import { Scale, type ScaleFunction } from './utilities/scale'
|
||||||
|
import { Tile } from './Tile'
|
||||||
|
import type { Movement, PlayerDto, TileDto } from '@/common/interfaces'
|
||||||
|
import { createContainer } from '@/common/helpers'
|
||||||
|
import { createText, playerNameText } from './utilities/fonts'
|
||||||
|
|
||||||
|
export class OtherHand {
|
||||||
|
tilesInitialNumber: number = 7
|
||||||
|
player?: PlayerDto
|
||||||
|
hand: Tile[] = []
|
||||||
|
container: Container = new Container()
|
||||||
|
height: number
|
||||||
|
width: number
|
||||||
|
scale: number = 0.5
|
||||||
|
scaleY!: ScaleFunction
|
||||||
|
scaleX!: ScaleFunction
|
||||||
|
x: number = 0
|
||||||
|
y: number = 0
|
||||||
|
grain: number = 25
|
||||||
|
logger: LoggingService = new LoggingService()
|
||||||
|
tilesLayer!: Container
|
||||||
|
interactionsLayer!: Container
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private app: Application,
|
||||||
|
public position: 'left' | 'right' | 'top' = 'left'
|
||||||
|
) {
|
||||||
|
this.height = 100
|
||||||
|
this.width = 300
|
||||||
|
app.stage.addChild(this.container)
|
||||||
|
const { x, y } = this.getPosition()
|
||||||
|
this.container.width = this.width
|
||||||
|
this.container.height = this.height
|
||||||
|
this.container.x = x
|
||||||
|
this.container.y = y
|
||||||
|
this.calculateScale()
|
||||||
|
this.initLayers()
|
||||||
|
}
|
||||||
|
|
||||||
|
setPlayer(player: PlayerDto) {
|
||||||
|
this.player = player
|
||||||
|
this.container.addChild(createText(`${player.name}`, this.width / 2, 12, playerNameText))
|
||||||
|
}
|
||||||
|
|
||||||
|
setHand(tiles: TileDto[]) {
|
||||||
|
this.hand = tiles.map((tile) => new Tile(tile.id, this.app.ticker, undefined, this.scale))
|
||||||
|
this.render()
|
||||||
|
}
|
||||||
|
|
||||||
|
update(move: Movement) {
|
||||||
|
this.hand = this.hand.filter((tile) => tile.id !== move?.tile?.id)
|
||||||
|
this.render()
|
||||||
|
}
|
||||||
|
|
||||||
|
private render() {
|
||||||
|
this.tilesLayer.removeChildren()
|
||||||
|
const x = -9
|
||||||
|
this.hand.forEach((tile, index) => {
|
||||||
|
tile.setPosition(this.scaleX(x + index * 2), this.height / 2)
|
||||||
|
this.tilesLayer.addChild(tile.getSprite())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private addBg() {
|
||||||
|
const bg = new Sprite(Texture.WHITE)
|
||||||
|
bg.alpha = 0.08
|
||||||
|
bg.width = this.width
|
||||||
|
bg.height = this.height
|
||||||
|
this.container.addChild(bg)
|
||||||
|
}
|
||||||
|
|
||||||
|
private getPosition() {
|
||||||
|
let x = 0
|
||||||
|
let y = 0
|
||||||
|
|
||||||
|
if (this.position === 'left') {
|
||||||
|
x = 0
|
||||||
|
y = 30
|
||||||
|
} else if (this.position === 'right') {
|
||||||
|
x = this.app.canvas.width - this.width
|
||||||
|
y = 30
|
||||||
|
} else {
|
||||||
|
x = (this.app.canvas.width - this.width) / 2
|
||||||
|
y = 0
|
||||||
|
}
|
||||||
|
return { x, y }
|
||||||
|
}
|
||||||
|
|
||||||
|
private initLayers() {
|
||||||
|
this.container.removeChildren()
|
||||||
|
this.addBg()
|
||||||
|
this.tilesLayer = createContainer({
|
||||||
|
width: this.width,
|
||||||
|
height: this.height,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
parent: this.container
|
||||||
|
})
|
||||||
|
this.interactionsLayer = createContainer({
|
||||||
|
width: this.width,
|
||||||
|
height: this.height,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
parent: this.container
|
||||||
|
})
|
||||||
|
this.container.addChild(this.tilesLayer)
|
||||||
|
this.container.addChild(this.interactionsLayer)
|
||||||
|
}
|
||||||
|
|
||||||
|
private calculateScale() {
|
||||||
|
const scaleXSteps = Math.floor(this.width / (this.grain * this.scale)) / 2
|
||||||
|
const scaleYSteps = Math.floor(this.height / (this.grain * this.scale)) / 2
|
||||||
|
this.scaleX = Scale([-scaleXSteps, scaleXSteps], [0, this.width])
|
||||||
|
this.scaleY = Scale([-scaleYSteps, scaleYSteps], [0, this.height])
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,11 @@
|
|||||||
import type { AnimationOptions } from '@/common/interfaces'
|
import type { AnimationOptions } from '@/common/interfaces'
|
||||||
import { Sprite, Texture, Ticker } from 'pixi.js'
|
import { Container, Sprite, Texture, Ticker } from 'pixi.js'
|
||||||
import { Tile } from './Tile'
|
import { Tile } from './Tile'
|
||||||
|
|
||||||
export abstract class SpriteBase {
|
export abstract class SpriteBase {
|
||||||
private _interactive: boolean = false
|
private _interactive: boolean = false
|
||||||
protected sprite: Sprite = new Sprite()
|
protected sprite: Sprite = new Sprite()
|
||||||
|
private container?: Container
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected ticker?: Ticker,
|
protected ticker?: Ticker,
|
||||||
@ -136,6 +137,11 @@ export abstract class SpriteBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addTo(container: any) {
|
addTo(container: any) {
|
||||||
|
this.container = container
|
||||||
container.addChild(this.sprite)
|
container.addChild(this.sprite)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeFromParent() {
|
||||||
|
this.container?.removeChild(this.sprite)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,4 +86,11 @@ export class Tile extends SpriteBase {
|
|||||||
}
|
}
|
||||||
this.orientation = value
|
this.orientation = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clone(): Tile {
|
||||||
|
const copy = new Tile(this.id, this.ticker, this.pips, this.scale, this.playerId)
|
||||||
|
copy.selected = this.selected
|
||||||
|
copy.orientation = this.orientation
|
||||||
|
return copy
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,16 @@ export const mainText = new TextStyle({
|
|||||||
stroke: '#658f56'
|
stroke: '#658f56'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const playerNameText = new TextStyle({
|
||||||
|
dropShadow: dropShadowStyle,
|
||||||
|
fill: '#a2a2a2',
|
||||||
|
fontFamily: 'Arial, Helvetica, sans-serif',
|
||||||
|
letterSpacing: 1,
|
||||||
|
stroke: '#565656',
|
||||||
|
fontSize: 15,
|
||||||
|
fontWeight: 'bold'
|
||||||
|
})
|
||||||
|
|
||||||
export function createText(str: string, x: number, y: number, style: TextStyle = mainText) {
|
export function createText(str: string, x: number, y: number, style: TextStyle = mainText) {
|
||||||
const text = new Text({ text: str, style })
|
const text = new Text({ text: str, style })
|
||||||
text.anchor.set(0.5, 0.5)
|
text.anchor.set(0.5, 0.5)
|
||||||
|
@ -31,13 +31,15 @@ onBeforeUnmount(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function copySeed() {
|
function copySeed() {
|
||||||
if (sessionState?.value?.seed) toClipboard(sessionState.value.seed)
|
if (sessionState?.value?.seed) {
|
||||||
|
toClipboard(sessionState.value.seed)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<section class="block">
|
<section class="block info">
|
||||||
<p>
|
<p>
|
||||||
Running: {{ sessionState?.sessionInProgress }} Seed: {{ sessionState?.seed }}
|
Running: {{ sessionState?.sessionInProgress }} Seed: {{ sessionState?.seed }}
|
||||||
<button @click="copySeed">Copy!</button>
|
<button @click="copySeed">Copy!</button>
|
||||||
@ -99,56 +101,15 @@ function copySeed() {
|
|||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-select {
|
|
||||||
display: flex;
|
|
||||||
gap: 16px;
|
|
||||||
align-items: start;
|
|
||||||
justify-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.game-container {
|
.game-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
.info {
|
||||||
.control {
|
|
||||||
padding: 8px;
|
|
||||||
margin-right: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
width: 100%;
|
|
||||||
height: 110px;
|
|
||||||
resize: none;
|
|
||||||
}
|
|
||||||
#response,
|
|
||||||
#status {
|
|
||||||
height: 180px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tiles-container {
|
|
||||||
display: flex;
|
|
||||||
gap: 4px;
|
|
||||||
flex-flow: row wrap;
|
|
||||||
align-content: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.board-container {
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
height: 600px;
|
top: 0;
|
||||||
padding: 10px;
|
left: 0;
|
||||||
width: calc(50% - 50px);
|
z-index: 20;
|
||||||
background-color: var(--pico-form-element-background-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.hand-container {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
height: 200px;
|
|
||||||
padding: 10px;
|
|
||||||
width: calc(50% - 50px);
|
|
||||||
background-color: var(--pico-form-element-background-color);
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -8,8 +8,9 @@ import type { GameService } from '@/services/GameService'
|
|||||||
import type { MatchSessionDto } from '@/common/interfaces'
|
import type { MatchSessionDto } from '@/common/interfaces'
|
||||||
import { useEventBusStore } from '@/stores/eventBus'
|
import { useEventBusStore } from '@/stores/eventBus'
|
||||||
import { useAuthStore } from '@/stores/auth'
|
import { useAuthStore } from '@/stores/auth'
|
||||||
|
import { copyToclipboard } from '@/common/helpers'
|
||||||
|
|
||||||
let seed = ref('')
|
let seed = ref<string>('')
|
||||||
let sessionName = ref('Test Value')
|
let sessionName = ref('Test Value')
|
||||||
let sessionId = ref('')
|
let sessionId = ref('')
|
||||||
let matchSessions = ref<MatchSessionDto[]>([])
|
let matchSessions = ref<MatchSessionDto[]>([])
|
||||||
@ -79,16 +80,19 @@ async function joinMatch(id: string) {
|
|||||||
router.push({ name: 'match', params: { id } })
|
router.push({ name: 'match', params: { id } })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
async function deleteMatch(id: string) {
|
||||||
async function startMatch() {
|
if (id) {
|
||||||
if (sessionState.value && sessionState.value.id) {
|
await socketService.connect()
|
||||||
router.push({ name: 'game' })
|
await gameService.cancelMatchSession(id)
|
||||||
|
loadData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadData() {
|
async function loadData() {
|
||||||
matchSessions.value = await gameService.listMatchSessions()
|
const listResponse = await gameService.listMatchSessions()
|
||||||
sessionName.value = `Test #${matchSessions.value.length + 1}`
|
console.log('listResponse :>> ', listResponse)
|
||||||
|
matchSessions.value = listResponse.data
|
||||||
|
sessionName.value = `Test #${listResponse.pagination.total + 1}`
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@ -101,6 +105,11 @@ onUnmounted(() => {
|
|||||||
logger.debug('Home view unmounted')
|
logger.debug('Home view unmounted')
|
||||||
clearInterval(dataInterval)
|
clearInterval(dataInterval)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function copy(sessionSeed: string) {
|
||||||
|
seed.value = sessionSeed
|
||||||
|
copyToclipboard(sessionSeed)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -132,16 +141,6 @@ onUnmounted(() => {
|
|||||||
<button class="button" @click="createMatch" v-if="!isSessionStarted">
|
<button class="button" @click="createMatch" v-if="!isSessionStarted">
|
||||||
Create Match Session
|
Create Match Session
|
||||||
</button>
|
</button>
|
||||||
<!-- <button class="button" @click="setPlayerReady" v-if="isSessionStarted">
|
|
||||||
<span v-if="!readyForStart">Ready</span><span v-else>Unready</span>
|
|
||||||
</button> -->
|
|
||||||
<!-- <button class="button" @click="startMatch" v-if="readyForStart">
|
|
||||||
<span>Start</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button class="button" @click="cancelMatch" v-if="isSessionStarted">
|
|
||||||
<span>Cancel</span>
|
|
||||||
</button> -->
|
|
||||||
</section>
|
</section>
|
||||||
<section class="section available-sessions" v-if="!isSessionStarted">
|
<section class="section available-sessions" v-if="!isSessionStarted">
|
||||||
<h2 class="title is-4">Available Sessions</h2>
|
<h2 class="title is-4">Available Sessions</h2>
|
||||||
@ -149,12 +148,19 @@ onUnmounted(() => {
|
|||||||
<div v-if="matchSessions.length === 0">
|
<div v-if="matchSessions.length === 0">
|
||||||
<p>No sessions available</p>
|
<p>No sessions available</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-else v-for="session in matchSessions" :key="session.id">
|
<div v-else class="grid is-col-min-12">
|
||||||
<p>{{ session.name }}</p>
|
<div class="cell" v-for="session in matchSessions" :key="session.id">
|
||||||
<p>{{ session }}</p>
|
<p class="title is-6">{{ session.name }}</p>
|
||||||
<button class="button" @click="() => joinMatch(session._id)">
|
<p>ID: {{ session._id }}</p>
|
||||||
Join ({{ session._id }})
|
<p>Players: {{ session.players.length }}</p>
|
||||||
</button>
|
<p>
|
||||||
|
Seed: {{ session.seed }}
|
||||||
|
<button @click="() => copy(session.seed)">Copy</button>
|
||||||
|
</p>
|
||||||
|
<p>Status: {{ session.status }}</p>
|
||||||
|
<button class="button" @click="() => joinMatch(session._id)">Join</button>
|
||||||
|
<button class="button" @click="() => deleteMatch(session._id)">Delete</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
@ -70,7 +70,9 @@ eventBus.subscribe('window-before-unload', async () => {
|
|||||||
await cancelMatch()
|
await cancelMatch()
|
||||||
})
|
})
|
||||||
|
|
||||||
eventBus.subscribe('server:match-starting', () => {
|
eventBus.subscribe('server:match-starting', (data) => {
|
||||||
|
const session = data.sessionState as MatchSessionDto
|
||||||
|
updateSessionState(session)
|
||||||
logger.debug('Match starting')
|
logger.debug('Match starting')
|
||||||
router.push({ name: 'game' })
|
router.push({ name: 'game' })
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user