2024-07-12 16:29:35 +02:00

212 lines
5.8 KiB
TypeScript

import { Application, Assets } from 'pixi.js'
import { Board } from '@/game/Board'
import { assets } from '@/game/utilities/assets'
import { Tile } from '@/game/Tile'
import { Hand } from '@/game/Hand'
import type { GameDto, Movement, PlayerDto, TileDto } from '@/common/interfaces'
import type { SocketIoClientService } from '@/services/SocketIoClientService'
import { useEventBusStore } from '@/stores/eventBus'
import { wait } from '@/common/helpers'
import { Actions } from 'pixi-actions'
export class Game {
public board!: Board
public hand!: Hand
private app: Application = new Application()
private selectedTile: TileDto | undefined
private eventBus: any = useEventBusStore()
private currentMove: Movement | undefined
constructor(
private options: { boardScale: number; handScale: number; width: number; height: number } = {
boardScale: 1,
handScale: 1,
width: 1200,
height: 800
},
private emit: any,
private socketService: SocketIoClientService,
private playerId: string,
private sessionId: string
) {}
async setup(): Promise<HTMLCanvasElement> {
const width = 1200
const height = 800
await this.app.init({ width, height })
this.app.ticker.add((tick) => Actions.tick(tick.deltaTime / 60))
return this.app.canvas
}
async start() {
this.board = new Board(this.app)
this.hand = new Hand(this.app)
this.hand.scale = this.options.handScale
this.board.scale = this.options.boardScale
this.setBoardEvents()
this.setHandEvents()
this.initEventBus()
wait(3000)
this.socketService.sendMessage('client:set-client-ready', {
sessionId: this.sessionId,
userId: this.playerId
})
}
async preload() {
await Assets.load(assets)
}
destroy() {
this.removeBoardEvents()
this.removeHandEvents()
this.app.destroy()
}
private initEventBus() {}
private setHandEvents() {
this.hand.on('hand-updated', (tiles: Tile[]) => {
this.board.setPlayerHand(tiles)
})
this.hand.on('game:tile-click', (tile: TileDto) => this.highlightMoves(tile))
this.hand.on('game:button-pass-click', async () => {
const move: Movement = {
id: '',
type: 'pass',
playerId: this.playerId
}
this.socketService.sendMessage('client:player-move', {
sessionId: this.sessionId,
move: move
})
await this.board.updateBoard(move)
})
this.hand.on('nextClick', () => {
this.socketService.sendMessage('client:set-player-ready', {
userId: this.playerId,
sessionId: this.sessionId
})
})
this.hand.on('hand-initialized', () => {})
}
highlightMoves(tile: TileDto) {
this.selectedTile = tile
if (tile !== undefined) {
this.board.setMovesForTile(this.getMoves(tile), tile)
} else {
this.board.cleanInteractions()
}
}
getMoves(tile: any): [boolean, boolean] {
if (tile === undefined) return [false, false]
if (this.board.count === 0) return [false, true]
const validEnds: [boolean, boolean] = [false, false]
const freeEnds = this.board.freeEnds
if (freeEnds !== undefined) {
if (tile.pips != undefined) {
validEnds[0] = tile.pips.includes(freeEnds[0])
validEnds[1] = tile.pips.includes(freeEnds[1])
}
}
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) {
const currentPlayer = state?.currentPlayer!
if (currentPlayer.id !== this.playerId) {
this.setCanMakeMove(false)
this.board.setServerPlayerTurn(currentPlayer)
} else {
this.setCanMakeMove(true)
}
}
private setBoardEvents() {
this.board.on('game:board-left-action-click', async (data) => {
console.log('left data :>> ', data)
if (this.selectedTile === undefined) return
const move: Movement = {
tile: this.selectedTile,
type: 'left',
playerId: this.playerId,
...data
}
this.currentMove = move
this.hand.tileMoved(this.selectedTile)
await this.board.updateBoard({ ...move, tile: this.selectedTile })
})
this.board.on('game:board-right-action-click', async (data) => {
console.log('right data :>> ', data)
if (this.selectedTile === undefined) return
const move: Movement = {
tile: this.selectedTile,
type: 'right',
playerId: this.playerId,
...data
}
this.currentMove = move
this.hand.tileMoved(this.selectedTile)
await this.board.updateBoard({ ...move, tile: this.selectedTile })
})
this.board.on('game:tile-animation-ended', async (tile) => {
console.log('animation ended', tile)
if (tile.playerId === this.playerId) {
this.socketService.sendMessage('client:player-move', {
sessionId: this.sessionId,
move: this.currentMove
})
}
})
}
// 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) {
this.hand.gameFinished()
this.board.gameFinished(data)
}
matchFinished(data: any) {
// this.hand.matchFinished()
this.board.matchFinished(data)
}
serverPlayerMove(data: any, playerId: string) {
this.board.playerMove(data, playerId)
}
private removeBoardEvents() {
this.board.off('game:board-left-action-click')
this.board.off('game:board-right-action-click')
}
private removeHandEvents() {
this.hand.off('game:tile-click')
this.hand.off('game:button-pass-click')
}
}