Skip to content

Commit

Permalink
feat: 借刀殺人距離判斷
Browse files Browse the repository at this point in the history
  • Loading branch information
Parsons committed Sep 10, 2024
1 parent e5e8a65 commit 5726949
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 9 deletions.
20 changes: 18 additions & 2 deletions components/PhaserGame.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,16 @@ const roleText = {
TRAITOR: '內奸',
}
const game = ref(null)
const myCards = ref(['BHK039', 'BH4030', 'BS8008', 'SHQ051', 'SS7007', 'SH7046', 'SHA040'])
const myCards = ref([
'BHK039',
'BH4030',
'BS8008',
'SHQ051',
'SS7007',
'SH7046',
'SHA040',
'SCQ064',
])
const myGameData = ref({})
const myGame = ref(null)
const myScene = ref(null)
Expand Down Expand Up @@ -66,7 +75,7 @@ const initDemo = () => {
) === index,
)
.map(([key, value]) => key)
.splice(0, 4)
// .splice(0, 4)
const gameData = {
seats: [
{
Expand Down Expand Up @@ -130,6 +139,13 @@ const initDemo = () => {
equipments: [],
delayScrolls: [],
},
round: {
roundPhase: '',
currentRoundPlayer: 'Tux',
activePlayer: 'Tux',
dyingPlayer: '',
showKill: false,
},
}
demo.value = true
myGame.value = new Game(gameData, myScene.value, api)
Expand Down
53 changes: 52 additions & 1 deletion src/classes/Game.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
import { Player, MainPlayer, Card, BattleScene } from './index'
import { atkLine } from '../utils/drawing'
import type { ThreeKingdomsCardIds, GameData, PlayType, EquipmentPlayType } from '~/src/types'
import type {
ThreeKingdomsCardIds,
GameData,
ThreeKingdomsCard,
PlayType,
EquipmentPlayType,
WeaponFeature,
} from '~/src/types'
import threeKingdomsCardsJson from '~/assets/cards.json'
import weaponFeaturesJson from '~/assets/weaponFeatures.json'
// import api from '~/src/utils/api'
const locations = [
{ x: 640, y: 160 },
{ x: 400, y: 120 },
{ x: 160, y: 160 },
]
const threeKingdomsCards: { [key in ThreeKingdomsCardIds]: ThreeKingdomsCard } =
threeKingdomsCardsJson as { [key in ThreeKingdomsCardIds]: ThreeKingdomsCard }
const weaponFeatures: { [key: string]: WeaponFeature } = weaponFeaturesJson
// const playCard = async (
// gameId: string,
// params: {
Expand Down Expand Up @@ -52,6 +64,7 @@ export default class Game {
}
hintInstance!: Phaser.GameObjects.Container
api: any
selectTargetPlayers: Player[] = []
constructor(gameData: any, scene: BattleScene, api: any) {
this.scene = scene
this.api = api
Expand All @@ -62,6 +75,7 @@ export default class Game {
y: locations[index].y,
scene,
handleClickPlayer: this.handleClickPlayer,
game: this,
})
playerInstance.createInstance()
return playerInstance
Expand Down Expand Up @@ -144,6 +158,23 @@ export default class Game {
console.log(player, this.me)
this.seats.forEach((player) => player.setOutOfDistance(false))
}
if (this.me.selectedCard!.name === '借刀殺人') {
// 借刀殺人要依序選擇目標
if (this.selectTargetPlayers.length === 0) {
player.setPlayerSelected(true, 'from')
this.selectTargetPlayers.push(player)
// 把此玩家攻擊範圍內的玩家設定為可選擇
this.seats.forEach((p) => {
if (p.id !== player.id && this.canAttack(player, p)) {
p.setOutOfDistance(false)
}
})
} else if (this.selectTargetPlayers.length === 1) {
// 已有選擇攻擊玩家,選擇被攻擊玩家
player.setPlayerSelected(true, 'to')
this.selectTargetPlayers.push(player)
}
}
}
skipPlayCard = () => {
const params = {
Expand Down Expand Up @@ -449,4 +480,24 @@ export default class Game {
getActivePlayer = () => {
return this.gameData.round?.activePlayer || this.gameData.round?.currentRoundPlayer
}
canAttack = (player: Player, targetPlayer: Player) => {
// 計算兩者的距離
const seats = [...this.seats, this.me]
const index1 = seats.findIndex((p) => p.id === player.id)
const index2 = seats.findIndex((p) => p.id === targetPlayer.id)
let distance = Math.abs(index1 - index2)
if (targetPlayer.equipments[3]) distance += 1
if (player.equipments[2]) {
distance -= 1
}
if (player.equipments[0]) {
// 考慮武器攻擊距離
const weaponCard = threeKingdomsCards[player.equipments[0]]
const weaponFeature = weaponFeatures[weaponCard.name]
if (weaponFeature?.attackDistance) {
distance -= weaponFeature.attackDistance - 1
}
}
return distance <= 1
}
}
47 changes: 42 additions & 5 deletions src/classes/MainPlayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export default class MainPlayer extends Player {
reactionType: string = ''
discardCount: number = 0
discardCards: Card[] = []
game: Game | null = null
discardCardsAction: ([]) => void = ([]) => {}
mainInstanceMap: { [key: string]: Phaser.GameObjects.Container } = {}
event: string = ''
Expand Down Expand Up @@ -64,7 +63,7 @@ export default class MainPlayer extends Player {
y: number
scene: BattleScene
seats: any
game: any
game: Game
}) {
super({
id,
Expand All @@ -79,11 +78,11 @@ export default class MainPlayer extends Player {
x,
y,
scene,
game,
})
this.seats = seats
this.gamePlayCardHandler = gamePlayCardHandler
this.discardCardsAction = discardCardsAction
this.game = game
this.mainInstanceMap = {}
// this.createMainPlayerInstance({ baseX: x, baseY: y, scene })
}
Expand Down Expand Up @@ -248,10 +247,11 @@ export default class MainPlayer extends Player {
}
}
playCardHandler = (card: Card) => {
if (this.game === null) return
if (this.game.getActivePlayer() !== this.id) {
// 非自己回合不能出牌
if (this.game!.getActivePlayer() !== this.id) {
return
}
/// event check
if (this.event === 'AskKillEvent') {
if (card.name !== '殺') {
return
Expand Down Expand Up @@ -371,6 +371,43 @@ export default class MainPlayer extends Player {
// card.destroy()
// this.selectedCard = null
}
if (card.name === '借刀殺人') {
if (this.selectedCard == card) {
// 卡片下移
this.scene.tweens.add({
targets: card.instance,
x: card.instance.x,
y: card.instance.y + 20,
duration: 500, // 持續時間(毫秒)
ease: 'Power2',
onComplete: () => {
this.selectedCard = null
},
})
this.resetOutofDistance()
return
}
// 判斷是否有可以施放的對象
// 該玩家身上有武器
const targetPlayers = this.seats.filter((player) => !player.equipments[0])
console.log('targetPlayers', targetPlayers)
targetPlayers.forEach((player) => {
player.setOutOfDistance(true)
})
// 卡片上移
this.selectedCard = card
let x = card.instance.x
let y = card.instance.y
this.scene.tweens.add({
targets: card.instance,
x: x,
y: y - 20,
// yoyo: true,
duration: 500, // 持續時間(毫秒)
ease: 'Power2',
})
return
}
card.playCard()
this.gamePlayCardHandler(card)
this.selectedCard = null
Expand Down
28 changes: 27 additions & 1 deletion src/classes/Player.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import generalCards from '~/assets/generalCards.json'
import threeKingdomsCards from '~/assets/cards.json'
import { roleMap, suits } from '~/src/utils/domain'
import type { ThreeKingdomsCardIds, ThreeKingdomsGeneralIds } from '~/src/types'
import type { ThreeKingdomsCardIds, ThreeKingdomsGeneralIds, WeaponFeature } from '~/src/types'
import { BattleScene } from './index'
import Game from './Game'
import weaponFeaturesJson from '~/assets/weaponFeatures.json'
const weaponFeatures: { [key: string]: WeaponFeature } = weaponFeaturesJson
export default class Player {
id: string
generral: string
Expand All @@ -26,6 +29,7 @@ export default class Player {
hintInstance!: Phaser.GameObjects.Container
isOutofDistance: boolean = false
instanceMap: { [key: string]: Phaser.GameObjects.Container } = {}
game: Game | null = null
// properties and methods go here
constructor({
id,
Expand All @@ -40,6 +44,7 @@ export default class Player {
x,
y,
scene,
game,
}: {
id: string
generral: string
Expand All @@ -56,6 +61,7 @@ export default class Player {
x: number
y: number
scene: BattleScene
game: Game
}) {
this.id = id
this.generral = generral
Expand All @@ -70,6 +76,7 @@ export default class Player {
this.x = x
this.y = y
this.scene = scene
this.game = game
}
createInstance() {
const baseX = this.x
Expand Down Expand Up @@ -257,6 +264,25 @@ export default class Player {
this.instance.setAlpha(1)
}
}
setPlayerSelected(isSelected: boolean, type: 'from' | 'to') {
// 讓物件邊緣發光
const rectangle: Phaser.GameObjects.Rectangle = this.instance.getAt(0)
if (isSelected) {
// 如果是 from 就是綠色,to 就是紅色
const color = type === 'from' ? 0x00ff00 : 0xff0000
const fx = rectangle.postFX.addGlow(color, 20, 0.5)
this.scene.tweens.add({
targets: fx,
outerStrength: 4,
duration: 1000,
ease: 'Sine.easeInOut',
yoyo: true,
loop: -1,
})
} else {
rectangle.postFX.clear()
}
}
updateEquipments(index: number) {
const equipments = ['weapon', 'armor', 'horsePlus', 'horseMinus']
const equipment = this.equipments[index]
Expand Down

0 comments on commit 5726949

Please sign in to comment.