vue3+threejs新手从零开发卡牌游戏(九):添加抽卡逻辑和动效

首先优化下之前的代码,把game/deck/p1.vue中修改卡组方法和渲染卡组文字方法提到公共方法中,此时utils/common.ts完整代码如下:


import { nextTick } from 'vue';
import * as THREE from 'three';
import * as TWEEN from '@tweenjs/tween.js'
import { TextGeometry } from 'three/addons/geometries/TextGeometry.js';// 坐标归一化
const transPos = (x: any, y: any) => {let pointer = new THREE.Vector2()pointer.x = ( x / window.innerWidth ) * 2 - 1;pointer.y = - ( y / window.innerHeight ) * 2 + 1;return pointer
}
export { transPos }// 修改卡组
const editDeckCard = (group:any, mesh: any, type: any) => {return new Promise((resolve, reject) => {let text = group.children.find((v: any) => v.name === "卡组数量")let shadowText = group.children.find((v: any) => v.name === "卡组数量阴影")// console.log(22, group.children, commonStore.$state.p1Deck)if (type === "remove") { // 删除卡组中的卡牌let child = group.children.find((v: any) => v.name === mesh.name)if (child) {group.remove(child)}}group.remove(text)group.remove(shadowText)group.children.forEach((v: any, i: any) => {v.position.set(0, 0.005 * i, 0)})resolve(true)})
}
export { editDeckCard }// 渲染卡组文字
const renderText = (group: any, text: any, font: any, position: any) => {return new Promise((resolve, reject) => {const geometry = new TextGeometry( `${text}`, {font,size: 0.4,height: 0,curveSegments: 4,bevelEnabled: true,bevelThickness: 0,bevelSize: 0,bevelSegments: 0});geometry.center()const material = new THREE.MeshBasicMaterial({ color: new THREE.Color("white"),alphaHash: true})const mesh = new THREE.Mesh( geometry, material ) ;mesh.position.set(position.x, position.y + 0.01, position.z)// mesh.position.set(0, 0.005 * commonStore.$state.p1Deck.length + 0.01, 0)mesh.rotateX(-90 * (Math.PI / 180)) // 弧度mesh.name = "卡组数量"// 阴影let shadowGeometry = geometry.clone()shadowGeometry.translate(0.02, 0.02, 0);let shadowMaterial = new THREE.MeshBasicMaterial({color: new THREE.Color("black"),alphaHash: true});let shadowMesh = new THREE.Mesh(shadowGeometry, shadowMaterial);shadowMesh.position.set(position.x, position.y, position.z)// shadowMesh.position.set(0, 0.005 * commonStore.$state.p1Deck.length, 0)shadowMesh.rotateX(-90 * (Math.PI / 180)) // 弧度shadowMesh.name = "卡组数量阴影"group.add(mesh)group.add(shadowMesh)resolve(true)})
}
export { renderText }

同步修改game/index.vue中对修改卡组方法的使用:


import { transPos, editDeckCard, renderText } from "@/utils/common.ts"// 初始化手牌
const initHand = () => {let cardNumber = 4let _number = 0let p1Deck = JSON.parse(JSON.stringify(commonStore.$state.p1Deck))let deckGroup = scene.getObjectByName("p1_deckGroup")let position = new THREE.Vector3(0, 0.005 * p1Deck.length, 0)let _interval = setInterval(async() => {// console.log(123, p1Deck)if (_number < cardNumber) {let obj = p1Deck[p1Deck.length - 1]p1Deck.splice(p1Deck.length-1, 1)commonStore.updateP1Deck(p1Deck)// 修改卡组await editDeckCard(deckGroup, obj, "remove")await renderText(deckGroup, `${commonStore.$state.p1Deck.length}`, commonStore.$state._font, position)// 手牌区添加手牌handRef.value.addHandCard(obj, deckGroup)} else {clearInterval(_interval)}_number++}, 200)}

之后我们思考下抽卡逻辑:
1.点击卡组,将卡组平移到页面中心位置(0, 0, 0)(y轴可以适当调高一点,这里点击事件只是为了测试抽卡,之后可以删掉)
2.然后卡组上展示“点击抽卡”的文字(文字用的是div+css的形式)

3.点击抽卡,执行抽卡动画

4.抽卡结束后,卡组移回到原位

首先我们在game/index.vue中添加点击事件,用raycaster射线进行鼠标拾取,当点击在卡组上时,执行onP1DeckEvent,这里由于是移动端所以只监听了touch事件,pc端则需要额外监听click事件:

// 鼠标按下
window.addEventListener('touchstart', onMousedown)// 鼠标按下事件
const onMousedown = (ev: any) => {// console.log(222, ev.target)// 判断是否点击到canvas上if(!(ev.target instanceof HTMLCanvasElement)){return;}// 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)let clientX = ev.clientX || ev.changedTouches[0].pageXlet clientY = ev.clientY || ev.changedTouches[0].pageY// pointer.x = ( clientX / window.innerWidth ) * 2 - 1;// pointer.y = - ( clientY / window.innerHeight ) * 2 + 1;let point = transPos(clientX, clientY) // 卡组起始位置的屏幕坐标// 通过摄像机和鼠标位置更新射线raycaster.setFromCamera( point, camera );// 点击卡组事件onP1DeckEvent()
}// 点击卡组事件
const onP1DeckEvent = () => {if (commonStore.$state.p1Deck.length <= 0) {return}let p1_deckGroup = scene.getObjectByName("p1_deckGroup")let arr = raycaster.intersectObject(p1_deckGroup, true)if (arr.length <= 0) {return}let pos1 = p1_deckGroup.userData.positionlet pos2 = new THREE.Vector3(0, 2, 0)// console.log(444, pos1, pos2)if (p1_deckGroup.position.x !== pos2.x) {drawCardRef.value.drawCardAnimate1(p1_deckGroup, pos1, pos2)}
}

然后我们在src下新建一个抽卡组件:

这个组件其实是用div+css画了一个透明的蒙层,卡组移到中央后,展示蒙层和“点击抽卡”字样,然后卡组动画我们分为两步,第一步是卡组飞到页面中心,用户点击抽卡后,执行之前的修改卡组和添加手牌方法,然后隐藏蒙层,执行第二步卡组移回原文动画,components/DrawCard.vue完整代码如下:

<!-- 抽卡 -->
<template><div v-if="state.visible" ref="maskRef" class="mask"><div class="box" @click="onDrawCard"><p>点击抽卡</p></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 { transPos, editDeckCard, renderText } from "@/utils/common.ts"const props: any = defineProps({handRef: {},deckRef: {}
})// 引入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 commonStore = useCommonStore()
const maskRef = ref()const state = reactive({visible: false
})// 卡组抽卡动画1-卡组移到页面中央
const drawCardAnimate1 = (deckGroup: any, startPos: any, endPos: any) => {// 隐藏卡组数量和卡组数量阴影几何体let textMesh = deckGroup.children.find((v: any) => v.name === "卡组数量")let textShadowMesh = deckGroup.children.find((v: any) => v.name === "卡组数量阴影")const tw = new TWEEN.Tween({x: startPos.x,y: startPos.y,z: startPos.z,opacity: 1.0,group: deckGroup})tw.to({x: endPos.x,y: endPos.y,z: endPos.z,opacity: 0.0,}, 200)tw.easing(TWEEN.Easing.Quadratic.Out)tw.onUpdate((obj: any) => {obj.group.position.set(obj.x, obj.y, obj.z)textMesh.material.opacity = obj.opacitytextShadowMesh.material.opacity = obj.opacity})tw.onComplete(function() {state.visible = trueTWEEN.remove(tw)})tw.start();
}// 卡组抽卡动画2-卡组回到原位
const drawCardAnimate2 = (deckGroup: any, startPos: any, endPos: any) => {// 隐藏卡组数量和卡组数量阴影几何体let textMesh = deckGroup.children.find((v: any) => v.name === "卡组数量")let textShadowMesh = deckGroup.children.find((v: any) => v.name === "卡组数量阴影")// textMesh.material.opacity = 1// textShadowMesh.material.opacity = 1const tw = new TWEEN.Tween({x: startPos.x,y: startPos.y,z: startPos.z,opacity: 0,group: deckGroup})tw.to({x: endPos.x,y: endPos.y,z: endPos.z,opacity: 1,}, 200)tw.easing(TWEEN.Easing.Quadratic.Out)tw.onUpdate((obj: any) => {obj.group.position.set(obj.x, obj.y, obj.z)textMesh.material.opacity = obj.opacitytextShadowMesh.material.opacity = obj.opacity})tw.onComplete(function() {TWEEN.remove(tw)})tw.start();
}// 抽卡
const onDrawCard = async () => {let p1_deckGroup = scene.getObjectByName("p1_deckGroup")let p1Deck = JSON.parse(JSON.stringify(commonStore.$state.p1Deck))let position = new THREE.Vector3(0, 0.005 * p1Deck.length, 0)let obj = p1Deck[p1Deck.length - 1]p1Deck.splice(p1Deck.length-1, 1)commonStore.updateP1Deck(p1Deck)// 修改卡组await editDeckCard(p1_deckGroup, obj, "remove")await renderText(p1_deckGroup, `${commonStore.$state.p1Deck.length}`, commonStore.$state._font, position)// 手牌区添加手牌props.handRef.addHandCard(obj, p1_deckGroup)state.visible = falsesetTimeout(() => {nextTick(() => {drawCardAnimate2(p1_deckGroup, p1_deckGroup.position, p1_deckGroup.userData.position)})}, 500)
}defineExpose({drawCardAnimate1,drawCardAnimate2
})
</script><style lang="scss" scoped>
.mask {position: fixed;top: 0;left: 0;z-index: 10;display: flex;align-items: center;justify-content: center;width: 100%;height: 100vh;// background-color: white;.box {width: 50vh;// height: 100px;text-align: center;font-size: 20px;color: #fff;}
}
</style>

注意:由于点击事件会穿透蒙层,所以我们在onMousedown方法中添加了ev.target instanceof HTMLCanvasElement进行判断是否点击到了canvas上。

最后还优化了下卡组,给卡组添加了线框,game/deck/p1.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, renderText } 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 = "p1_deckGroup"
scene.add(deckGroup)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.namedeckGroup.add( mesh );}})let position = new THREE.Vector3(0, 0.005 * commonStore.$state.p1Deck.length, 0)renderText(deckGroup, `${commonStore.$state.p1Deck.length}`, commonStore.$state._font, position)}// 设置卡组位置
const setDeckPos = () => {nextTick(() => {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>

最后看下抽卡效果:

至此基本完成了抽卡逻辑和简单动效的开发。

附录:

game/index.vue完整代码如下:

<template><div ref="sceneRef" class="scene"></div><!-- 手牌 --><Hand ref="handRef"/><!-- 卡组 --><Deck ref="deckRef"/><!-- 抽卡逻辑 --><DrawCard ref="drawCardRef" :handRef="handRef" :deckRef="deckRef"/>
</template><script setup lang="ts">
import { reactive, ref, onMounted, onBeforeUnmount, watch, defineComponent, getCurrentInstance, nextTick } from 'vue'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; // 轨道控制器
import { FontLoader } from 'three/addons/loaders/FontLoader.js';
import { useCommonStore } from "@/stores/common.ts"
import { transPos, editDeckCard, renderText } from "@/utils/common.ts"
import { Card } from "./Card.ts"
import { CARD_DICT } from "@/utils/dict/card.ts"
import Hand from "./hand/index.vue"
import Deck from "./deck/index.vue"
import DrawCard from "@/components/DrawCard.vue"// 引入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()// 场景ref
const sceneRef = ref()
const handRef = ref()
const deckRef = ref()
const drawCardRef = ref()// 坐标轴辅助
const axesHelper = new THREE.AxesHelper(5);
// 创建轨道控制器
// const controls = new OrbitControls( camera, renderer.domElement );
// 字体加载器
const fontLoader = new FontLoader();onMounted(async () => {await initResource()initScene()initGame()// 鼠标按下window.addEventListener('touchstart', onMousedown)// window.addEventListener('click', onMousedown)// 监听浏览器窗口变化进行场景自适应window.addEventListener('resize', onWindowResize, false);
})// 资源加载
const initResource = () => {// 字体加载return new Promise((resolve, reject) => {fontLoader.load('fonts/helvetiker_regular.typeface.json', (font: any) => {commonStore.loadFont(font)resolve(true)});})
}// 初始化场景
const initScene = () => {renderer.setSize( window.innerWidth, window.innerHeight );sceneRef.value.appendChild( renderer.domElement );scene.add(axesHelper)// camera.position.set( 5, 5, 5 );camera.position.set( 0, 6.5, 0 );camera.lookAt(0, 0, 0)addPlane()animate();
}// scene中添加plane几何体
const addPlane = () => {const geometry = new THREE.PlaneGeometry( 20, 20);const material = new THREE.MeshBasicMaterial( {color: new THREE.Color("gray"), side: THREE.FrontSide, alphaHash: true,// alphaTest: 0,opacity: 0} );const plane = new THREE.Mesh( geometry, material );plane.rotateX(-90 * (Math.PI / 180)) // 弧度plane.name = "地面"scene.add( plane );
}// 用requestAnimationFrame进行渲染循环
const animate = () => {requestAnimationFrame( animate );TWEEN.update()renderer.render( scene, camera );
}// 场景跟随浏览器窗口大小自适应
const onWindowResize = () => {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize(window.innerWidth, window.innerHeight);
}// 初始化游戏
const initGame = async () => {// 初始化卡组await initDeck()// 初始化手牌initHand()
}// 初始化卡组
const initDeck = () => {return new Promise((resolve, reject) => {let p1Deck = ["YZ-01","YZ-02","YZ-03","YZ-04","YZ-01","YZ-02",// "YZ-03",// "YZ-04",// "YZ-01",// "YZ-02",// "YZ-03",// "YZ-04",]// 洗牌p1Deck.sort(() => {return Math.random() - 0.5})let newDeck: any = []p1Deck.forEach((v: any, i: any) => {let obj = CARD_DICT.find((b: any) => b.card_id === v)if (obj) {newDeck.push({card_id: v,name: `${obj.name}_${i}`})}})// console.log("p1Deck", newDeck)commonStore.updateP1Deck(newDeck)nextTick(() => {handRef.value.init()deckRef.value.init()resolve(true)})})
}// 初始化手牌
const initHand = () => {let cardNumber = 4let _number = 0let p1Deck = JSON.parse(JSON.stringify(commonStore.$state.p1Deck))let deckGroup = scene.getObjectByName("p1_deckGroup")let position = new THREE.Vector3(0, 0.005 * p1Deck.length, 0)let _interval = setInterval(async() => {// console.log(123, p1Deck)if (_number < cardNumber) {let obj = p1Deck[p1Deck.length - 1]p1Deck.splice(p1Deck.length-1, 1)commonStore.updateP1Deck(p1Deck)// 修改卡组await editDeckCard(deckGroup, obj, "remove")await renderText(deckGroup, `${commonStore.$state.p1Deck.length}`, commonStore.$state._font, position)// 手牌区添加手牌handRef.value.addHandCard(obj, deckGroup)} else {clearInterval(_interval)}_number++}, 200)}// 鼠标按下事件
const onMousedown = (ev: any) => {// console.log(222, ev.target)// 判断是否点击到canvas上if(!(ev.target instanceof HTMLCanvasElement)){return;}// 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)let clientX = ev.clientX || ev.changedTouches[0].pageXlet clientY = ev.clientY || ev.changedTouches[0].pageY// pointer.x = ( clientX / window.innerWidth ) * 2 - 1;// pointer.y = - ( clientY / window.innerHeight ) * 2 + 1;let point = transPos(clientX, clientY) // 卡组起始位置的屏幕坐标// 通过摄像机和鼠标位置更新射线raycaster.setFromCamera( point, camera );// 点击卡组事件onP1DeckEvent()
}// 点击卡组事件
const onP1DeckEvent = () => {if (commonStore.$state.p1Deck.length <= 0) {return}let p1_deckGroup = scene.getObjectByName("p1_deckGroup")let arr = raycaster.intersectObject(p1_deckGroup, true)if (arr.length <= 0) {return}let pos1 = p1_deckGroup.userData.positionlet pos2 = new THREE.Vector3(0, 2, 0)// console.log(444, pos1, pos2)if (p1_deckGroup.position.x !== pos2.x) {drawCardRef.value.drawCardAnimate1(p1_deckGroup, pos1, pos2)}
}
</script><style lang="scss" scoped>
.scene {position: fixed;top: 0;left: 0;width: 100%;height: 100vh;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/765984.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

哈希表(c++)

1、介绍 哈希表&#xff0c;也称为散列表&#xff0c;是一种非常高效的数据结构。它通过将键&#xff08;Key&#xff09;映射到数组的特定位置来快速查找、插入和删除数据。这个映射过程由哈希函数&#xff08;Hash Function&#xff09;完成&#xff0c;该函数将键转化为一个…

【JS】深度学习JavaScript

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;【JS】深度学习JavaScript &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 一:JavaScript1.1 JavaScript是什么1.2 JS的引入方式1.3 JS变量1.4 数据类型1.5 …

三款优秀的伪原创改写软件,为你高效创作

近年来&#xff0c;随着互联网内容的爆炸式增长&#xff0c;原创内容的重要性日益凸显。然而&#xff0c;对于许多写手和创作者来说&#xff0c;时间和灵感可能成为限制因素。为了解决这个问题&#xff0c;伪原创改写软件应运而生。这些软件利用先进的算法和自然语言处理技术&a…

基于Java中的SSM框架实现多平台大学生创新团队管理系统项目【项目源码+论文说明】计算机毕业设计

基于Java中的SSM框架实现多平台学生创新团队管理系统演示 摘要 大学生作为社会向前发展的源动力&#xff0c;必须与知识经济时代发展要求相适应&#xff0c;具有较强的创新能力。而未来社会迫切需要的是具有创新创业能力的人才。高素质人才应具有独立生存的自信心、不断创新的…

PHP+MySQL开发组合:智慧同城便民信息小程序源码系统 带完整的安装代码包以及安装部署教程

当前&#xff0c;城市生活的节奏日益加快&#xff0c;人们对各类便民信息的需求也愈发迫切。无论是寻找家政服务、二手交易&#xff0c;还是发布租房、求职信息&#xff0c;一个高效、便捷的信息平台显得尤为重要。传统的信息发布方式往往存在信息更新不及时、查找困难等问题&a…

Cesium安装部署运行

目录 1.简介 2.Cesium项目下载 3.Cesium项目运行 4.cesium运行 1.简介 Cesium是国外一个基于JavaScript编写的使用WebGL的地图引擎。Cesium支持3D,2D,2.5D形式的地图展示&#xff0c;可以自行绘制图形&#xff0c;高亮区域&#xff0c;并提供良好的触摸支持&#xff0c;且支…

GAMMA数据处理问题(七)

phase_sim_orb报这个错是什么原因呢&#xff0c;说是我的hgt文件和模拟的干涉图行数不匹配&#xff0c;之前geocode生成hgt的参数不是在mli.par文件中看吗&#xff0c;为什么会出现行数不匹配的情况啊&#xff0c;难道不是par文件中里面看&#xff1f;&#xff1f;&#xff1f;…

2024年全国职业院校技能大赛中职组大数据应用与服务赛项题库参考答案陆续更新中,敬请期待…

2024年全国职业院校技能大赛中职组大数据应用与服务赛项题库参考答案陆续更新中&#xff0c;敬请期待… 武汉唯众智创科技有限公司 2024 年 3 月 联系人&#xff1a;辜渝傧13037102709 题号&#xff1a;试题05 ZZ052-大数据应用与服务赛项试题 05 模块一:平台搭建与运维 (一…

幻兽帕鲁Linux服务器安装Mod

系列文章目录 幻兽帕鲁游戏搭建&#xff08;docker&#xff09; 幻兽帕鲁服务器安装Mod&#xff08;Linux&#xff09; 文章目录 系列文章目录前言一、Mod类别1.模型mod2.功能性mod 二、ue4ss三、Mod选择1. N网2. 3DM MOD 四、服务器安装1.关闭服务2.上传mod3.启动服务 总结 前…

深度分析鸿蒙应用开发的准确红利期、前景、未来发展方向

近年来&#xff0c;随着互联网技术的不断发展&#xff0c;鸿蒙生态开发逐渐成为热门话题。作为一种新兴的操作系统&#xff0c;其发展趋势备受关注。同时&#xff0c;鸿蒙生态开发的价值、就业岗位需求以及相关学习方面也引起了广泛关注。 那么就目前的形势来看&#xff0c;鸿…

Docker专题-03 Log-Driver日志转存

Docker专题教程 注&#xff1a; 本教程由羞涩梦整理同步发布&#xff0c;本人技术分享站点&#xff1a;blog.hukanfa.com 转发本文请备注原文链接&#xff0c;本文内容整理日期&#xff1a;2024-03-19 csdn 博客名称&#xff1a;五维空间-影子&#xff0c;欢迎关注 说明 容器…

软考 系统架构设计师系列知识点之系统性能(1)

所属章节&#xff1a; 第2章. 计算机系统基础知识 第9节. 系统性能 系统性能是一个系统提供给用户的所有性能指标的集合。它既包括硬件性能&#xff08;如处理器主频、存储器容量、通信带宽等&#xff09;和软件性能&#xff08;如上下文切换、延迟、执行时间等&#xff09;&a…

【深度学习】四种天气分类 模版函数 从0到1手敲版本

引入该引入的库 import torch import torch.nn as nn import matplotlib.pyplot as plt import torch.nn.functional as F import torchvision import torch.optim as optim %matplotlib inline import os import shutil import glob os.environ["KMP_DUPLICATE_LIB_OK&q…

iOS应用审核问题解决方案及优化方法 ✨

摘要 本文将针对iOS应用提交审核时可能遇到的问题&#xff0c;如“你必须在Xcode中添加com.apple.developer.game-center密钥”&#xff0c;以及突然间提交送审报错情况进行探讨。通过大量查询资料和尝试&#xff0c;结合案例分析&#xff0c;提供了解决方案和优化方法&#x…

【模糊逻辑】Type-1 Fuzzy Systems-2

【模糊逻辑】Type-1 Fuzzy Systems 3.4.3 模糊化及其推理的影响3.4.3.1 Singleton Fuzzifier例3.5例3.6 3.4.3.2 Non-Singleton Fuzzifier例3.7 Non-Singleton Fuzzifier 量化求解 Firing Level 3.5 对规则触发&#xff08;Fired-Rule&#xff09;的输出集进行组合3.5.1Mamdani…

【linux】CentOS查看系统信息

一、查看版本号 在CentOS中&#xff0c;可以通过多种方法来查看版本号。以下是几种常用的方法&#xff1a; 使用cat命令查看/etc/centos-release文件&#xff1a; CentOS的版本信息存储在/etc/centos-release文件中。可以使用cat命令来显示该文件的内容&#xff0c;从而获得C…

力扣hot100:153. 寻找旋转排序数组中的最小值(二分的理解)

由力扣hot100&#xff1a;33. 搜索旋转排序数组&#xff08;二分的理解&#xff09;-CSDN博客&#xff0c;我们知道二分实际上就是找到一个策略将区间“均分”。对于旋转数组问题&#xff0c;在任何位置分开两个区间&#xff0c;如果原区间不是顺序的&#xff0c;分开后必然有一…

BRAM底层原理详细解释(1)

目录 一、原语 二、端口简述 2.1 端口简介 2.2 SDP端口映射 三、端口信号含义补充说明 3.1 字节写使能&#xff08;Byte-Write Enable&#xff09;- WEA and WEBWE&#xff1a; 3.2 地址总线—ADDRARDADDR and ADDRBWRADDR 3.3 数据总线—DIADI, DIPADIP, DIBDI, and D…

【c++初阶】C++入门(下)

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ &#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1…

AI元年,这5款AI写作能为你提供帮助

自从人工智能技术的迅猛发展以来&#xff0c;AI在各个领域都取得了巨大的进步。其中&#xff0c;AI写作工具成为越来越多人关注的焦点。在这个AI元年&#xff0c;小编想向大家分享5款可能对你有帮助的AI写作工具&#xff0c;如果你也想找AI写作相关的工具&#xff0c;那么来看看…