212 lines
5.8 KiB
TypeScript
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')
|
|
}
|
|
}
|