vue3+threejs新手从零开发卡牌游戏(十五):创建对方场地和对方卡组

首先创建对方场地,game/site/p2.vue和p1.vue代码一样,注意把里面的命名“己方”修改成“对方”,game/site/index.vue代码如下,用rotateZ翻转一下即可得到镜像的对方场地:


// 添加战域plane
const addSitePlane = () => {
  return new Promise((resolve, reject) => {
    // 设置战域大小和位置
    let plane = scene.getObjectByName("地面")
    let point = transPos(0, 0) // 战域起始位置的屏幕坐标
    // 
    raycaster.setFromCamera( point, camera );
    const intersects = raycaster.intersectObject( plane );
    if (intersects.length > 0) {
      let point = intersects[0].point
      // 进行裁剪
      // let x = Math.abs(point.x) * 2 - 2.4
      // let y = Math.abs(point.z) * 2 - 4
      let x = Math.abs(point.x) * 2
      let y = Math.abs(point.z) - 2

      // 添加p1战域
      const p1SitePlane = new THREE.Group()
      p1SitePlane.name = "己方战域Plane"
      p1SitePlane.position.set(0, 0, 0.3)
      p1SitePlane.rotateX(-90 * (Math.PI / 180)) // 弧度
      p1SitePlane.userData["width"] = x
      p1SitePlane.userData["height"] = y
      scene.add(p1SitePlane)

      // 添加p2战域
      const p2SitePlane = new THREE.Group()
      p2SitePlane.name = "对方战域Plane"
      p2SitePlane.position.set(0, 0, -0.3)
      p2SitePlane.rotateX(-90 * (Math.PI / 180)) // 弧度
      p2SitePlane.rotateZ(-180 * (Math.PI / 180)) // 弧度
      p2SitePlane.userData["width"] = x
      p2SitePlane.userData["height"] = y
      scene.add(p2SitePlane)
      resolve(true)
    }
  })
}

页面效果如下:

然后添加对方卡组,game/deck/p2.vue代码和p1.vue代码一样,注意把里面的命名“己方”修改成“对方”,game/deck/p2.vue代码如下:

<template>
  <div></div>
</template>

<script setup lang="ts">
import { reactive, ref, onMounted, onBeforeUnmount, watch, defineComponent, getCurrentInstance, nextTick } from 'vue'
import { useCommonStore } from "@/stores/common.ts"
import { TextGeometry } from 'three/addons/geometries/TextGeometry.js';
import { Card } from "@/views/game/Card.ts"
import { CARD_DICT } from "@/utils/dict/card.ts"
import { transPos, renderDeckText } from "@/utils/common.ts"

// 引入threejs变量
const {proxy} = getCurrentInstance()
const THREE = proxy['THREE']
const scene = proxy['scene']
const camera = proxy['camera']
const renderer = proxy['renderer']
const TWEEN = proxy['TWEEN']

const raycaster = new THREE.Raycaster();
const pointer = new THREE.Vector2();

const commonStore = useCommonStore()

// 卡组group
const deckGroup = new THREE.Group()
deckGroup.name = "p2_deckGroup"
scene.add(deckGroup)

const init = () => {
  setDeckPos()
  addDeckWireframe()
  commonStore.$state.p2Deck.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用于实时计算当前攻击力
      deckGroup.add( mesh );
    }
  })

  let position = new THREE.Vector3(0, 0.005 * commonStore.$state.p2Deck.length, 0)
  renderDeckText(deckGroup, `${commonStore.$state.p2Deck.length}`, commonStore.$state._font, position)

}

// 设置卡组位置
const setDeckPos = () => {
  nextTick(() => {
    let sitePlane = scene.getObjectByName("对方战域Plane")
    let siteDeckMesh = sitePlane.getObjectByName("对方卡组")
    let pos = new THREE.Vector3(0, 0, 0)
    siteDeckMesh.getWorldPosition(pos)
    deckGroup.position.set(pos.x, pos.y, pos.z)
    deckGroup.userData["position"] = pos
    deckGroup.scale.set(0.8, 0.8, 0.8) // 缩放
    // let plane = scene.getObjectByName("地面")
    // let point = transPos(window.innerWidth - 15, window.innerHeight - 15) // 卡组起始位置的屏幕坐标
    // // 
    // raycaster.setFromCamera( point, camera );
    // const intersects1 = raycaster.intersectObject( plane );
    // if (intersects1.length > 0) {
    //   let point = intersects1[0].point
    //   // deckGroup.position.set(point.x, point.y, point.z)
    //   deckGroup.position.set(point.x - 0.5, point.y, point.z - 0.7)
    //   // 记录卡组位置
    //   let position = new THREE.Vector3(point.x - 0.5, point.y, point.z - 0.7)
    //   deckGroup.userData["position"] = position
    // }
  })
}

// 绘制卡组区域线框
const addDeckWireframe = () => {
  nextTick(() => {
    const edges = new THREE.EdgesGeometry( deckGroup.children[0].geometry );
    const line = new THREE.LineSegments( edges, new THREE.LineBasicMaterial( { color: 0xffffff } ) );
    deckGroup.add(line);
  })
}

defineExpose({
  init,
})
</script>

<style lang="scss" scoped>
</style>

这里封装下测试卡组,分成p1和p2两个测试卡组:

// p1测试卡组
const p1TestDeck = [
  "YZ-01",
  "YZ-02",
  "YZ-03",
  "YZ-04",
  "YZ-01",
  "YZ-02",
  // "YZ-03",
  // "YZ-04",
  // "YZ-01",
  // "YZ-02",
  // "YZ-03",
  // "YZ-04",
]

export { p1TestDeck }

// p2测试卡组
const p2TestDeck = [
  // "YZ-01",
  // "YZ-02",
  // "YZ-03",
  // "YZ-04",
  // "YZ-01",
  // "YZ-02",
  "YZ-03",
  "YZ-04",
  "YZ-01",
  "YZ-02",
  "YZ-03",
  "YZ-04",
]
export { p2TestDeck }

然后在game/index.vue代码调用,修改初始化卡组方法:


// 初始化卡组
const initDeck = () => {
  return new Promise((resolve, reject) => {
    let p1Deck: any = []
    let p2Deck: any = []
    // 洗牌
    p1TestDeck.sort(() => {
      return Math.random() - 0.5
    })
    p2TestDeck.sort(() => {
      return Math.random() - 0.5
    })
    p1TestDeck.forEach((v: any, i: any) => {
      let obj = CARD_DICT.find((b: any) => b.card_id === v)
      if (obj) {
        p1Deck.push({
          card_id: v,
          name: `${obj.name}_${i}`
        })
      }
    })
    p2TestDeck.forEach((v: any, i: any) => {
      let obj = CARD_DICT.find((b: any) => b.card_id === v)
      if (obj) {
        p2Deck.push({
          card_id: v,
          name: `${obj.name}_${i}`
        })
      }
    })
    // console.log("p1Deck", newDeck)
    commonStore.updateP1Deck(p1Deck)
    commonStore.updateP2Deck(p2Deck)
    
    nextTick(() => {
      handRef.value.init()
      deckRef.value.init()
      resolve(true)
    })
  })
}

页面效果如下:

最近更新

  1. TCP协议是安全的吗?

    2024-03-27 16:10:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-27 16:10:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-27 16:10:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-27 16:10:01       18 阅读

热门阅读

  1. 了解 C++ 中的三元运算符

    2024-03-27 16:10:01       16 阅读
  2. chrome安装vue插件vue-devtools

    2024-03-27 16:10:01       23 阅读
  3. 计算两点距离工具类

    2024-03-27 16:10:01       15 阅读
  4. ardupilot开发 --- 机载(边缘)计算机-VISP-附录 篇

    2024-03-27 16:10:01       17 阅读
  5. Python GUI编程(Tkinter)

    2024-03-27 16:10:01       15 阅读
  6. 浅析机器学习的常用方法

    2024-03-27 16:10:01       17 阅读