这里优化了一些游戏细节和代码逻辑:
1.添加先手第一回合不能攻击的逻辑
2.卡牌添加攻击次数,默认每回合只能攻击1次
3.卡牌添加资源值(Mana),每回合双方玩家最多只能使用6点能量值,用于召唤怪兽上场或使用物品
主要部分代码如下:
game/index.vue:
// 鼠标选中场上卡牌事件
const onSelectSiteCard = () => {
if (commonStore.$state.flowIndex !== 2) { // 非战斗阶段不进行该操作
return
}
if (commonStore.$state.round === 1) { // 第一回合不能进行攻击
return
}
let p1Cards = scene.children.filter((v: any) => v.userData?.areaType?.indexOf("己方怪兽区") > -1)
if (p1Cards.length <= 0) {
return
}
let arr = raycaster.intersectObjects(p1Cards, true)
if (arr.length > 0) {
// 找到对应卡牌
let _selectedCard: any = arr[0].object
if (_selectedCard.name === "攻击力") {
_selectedCard = _selectedCard.parent
}
if (_selectedCard.userData.AttackFrequency <= 0) { // 如果该卡攻击次数小于等于0,那么跳过
return
}
selectedCard.value = _selectedCard
}
}
// 获取目标对象
const getTargetMesh = () => {
let p2Cards = scene.children.filter((v: any) => v.userData?.areaType?.indexOf("对方怪兽区") > -1)
if (p2Cards.length <= 0) {
selectedTargetCard.value = null
return
}
let arr = raycaster.intersectObjects(p2Cards, true)
if (arr.length > 0) {
let _selectedTargetCard: any = arr[0].object
if (_selectedTargetCard.name === "攻击力") {
_selectedTargetCard = _selectedTargetCard.parent
}
selectedTargetCard.value = _selectedTargetCard
} else {
selectedTargetCard.value = null
}
}
dragControls.addEventListener( 'dragend', function ( event: any ) {
if (commonStore.$state.currentPlayer === "p1" && commonStore.$state.flowIndex === 1) {
dragControls.enabled = true
event.object.position.y -= 0.04
// 如果mana不够则不能上场
if (commonStore.$state.p1Mana < event.object?.userData.Mana) {
handRef.value.backPosition(event.object)
return
}
let p1SitePlane = scene.getObjectByName("己方战域Plane")
let point = transPos(pointer.x, pointer.y)
// 通过摄像机和鼠标位置更新射线
raycaster.setFromCamera( point, camera );
const intersects = raycaster.intersectObjects(p1SitePlane.children);
if (intersects.length > 0) {
dialogRef.value.init({
type: "handToSite",
obj: event.object,
message: "是否上场该卡牌"
})
} else {
handRef.value.backPosition(event.object)
}
} else {
dragControls.enabled = false
}
});
// 绘制场上卡牌
const renderSiteCard = async (handGroup: any, data: any, mesh: any) => {
let position = new THREE.Vector3(0, 0, 0)
mesh.getWorldPosition(position)
mesh.userData.empty = false
let oldMesh = handGroup.children.find((v: any) => v.name === data.name)
let newMesh = oldMesh.clone()
newMesh.userData.areaType = mesh.name // 用来记录卡牌在哪个区域,怪兽区、墓地、手牌、卡组、场地等
newMesh.scale.set(0.8, 0.8, 0.8)
if (handGroup.name === "p1_handGroup") {
// 更新mana
let mana = JSON.parse(JSON.stringify(commonStore.$state.p1Mana))
mana -= newMesh.userData.Mana
commonStore.updateP1Mana(mana)
//
handRef.value.removeP1HandCard(oldMesh)
} else if (handGroup.name === "p2_handGroup") {
// 更新mana
let mana = JSON.parse(JSON.stringify(commonStore.$state.p2Mana))
mana -= newMesh.userData.Mana
commonStore.updateP2Mana(mana)
//
handRef.value.removeP2HandCard(oldMesh)
newMesh.rotateX(180 * (Math.PI / 180)) // 弧度
newMesh.rotateY(180 * (Math.PI / 180)) // 弧度
}
scene.add(newMesh)
newMesh.position.set(position.x, position.y, position.z)
await renderSiteCardText(handGroup, newMesh, commonStore.$state._font)
}
game/deck/p1.vue(game/deck/p2.vue同步修改):
const init = () => {
setDeckPos()
addDeckWireframe()
commonStore.$state.p1Deck.forEach((v: any, i: any) => {
let obj = CARD_DICT.find((b: any) => b.card_id === v.card_id)
if (obj) {
let card = new Card(obj)
let mesh = card.init()
mesh.position.set(0, 0.005 * i, 0)
mesh.rotateX(180 * (Math.PI / 180)) // 弧度
mesh.name = v.name
mesh.userData._ATK = mesh.userData.ATK // _ATK用于实时计算当前攻击力
mesh.userData.AttackFrequency = 1 // 攻击次数,初始默认设置为1,即每回合怪兽只能攻击一次
deckGroup.add( mesh );
}
})
let position = new THREE.Vector3(0, 0.005 * commonStore.$state.p1Deck.length, 0)
renderDeckText(deckGroup, `${commonStore.$state.p1Deck.length}`, commonStore.$state._font, position)
}
页面效果如下(其中青眼白龙设置为了6能量值,所以此时能量不够无法召唤上场):