当前位置: 首页 > news >正文

Unity太空避障Demo总结

太空避障:主要是实现飞机躲避子弹
面板基类、音乐类、排行榜类、json等等都和上一篇Unity坦克迷宫Demo总结一样,太空避障主要是对四元数的练习和使用
1.选择飞机面板
(1)通过左右按钮对显示的模型进行切换
(2)通过点击鼠标左键可以实现对飞机的拖动 观察飞机的整体
知识点
(1)四元数 * 四元数:会得到一个新的四元数,大多数用于旋转量相乘,相当于旋转(这个旋转的坐标是物体自身的坐标系)
(2)四元数 * 向量:会得到一个新的向量,对一个向量进行一定旋转,相当于旋转向量

public class SelectPanel : BasePanel<SelectPanel>
{public Button btnRight;public Button btnLeft;public Button btnStart;public Button btnClose;//标识当前已经创建的飞机 当切换时要删除该飞机private GameObject nowAirObj;//飞机的父物体位置public Transform airPos;//飞机的属性列表 通过隐藏和显示GameObject实现public GameObject[] hpList;public GameObject[] speedList;public GameObject[] voluemeList;public override void Init(){//在GameDataManager中保存了当前选中的飞机id 默认从0开始 点右按钮++ 左按钮-- 还有对边界的判断btnRight.onClick.AddListener(() =>{++GameDataManager.Instance.nowSelectAir;if(GameDataManager.Instance.nowSelectAir > GameDataManager.Instance.airData.Count - 1)GameDataManager.Instance.nowSelectAir = 0;ChangAir();});btnLeft.onClick.AddListener(() =>{--GameDataManager.Instance.nowSelectAir;if (GameDataManager.Instance.nowSelectAir < 0)GameDataManager.Instance.nowSelectAir = GameDataManager.Instance.airData.Count - 1;ChangAir();});btnStart.onClick.AddListener(() =>{SceneManager.LoadScene("GameScene");});btnClose.onClick.AddListener(() =>{BeginPanel.Instance.ShowPanel();HidePanel();});HidePanel();}//重写了隐藏和显示方法 这样就可以同时实现一些逻辑public override void ShowPanel(){base.ShowPanel();GameDataManager.Instance.nowSelectAir = 0;ChangAir();}public override void HidePanel(){base.HidePanel();DestroyObj();}public void ChangAir(){//删除上个飞机 创建新飞机 并记录DestroyObj();AirData airData = GameDataManager.Instance.airData[GameDataManager.Instance.nowSelectAir];nowAirObj = Instantiate(Resources.Load<GameObject>(airData.res));nowAirObj.transform.SetParent(airPos.transform, false);for(int i = 0; i < hpList.Length;i++){hpList[i].SetActive(i < airData.hp);speedList[i].SetActive(i < airData.speed);voluemeList[i].SetActive(i < airData.volume);}}public void DestroyObj(){if(nowAirObj != null){Destroy(nowAirObj);}}private float time;//点中可以进行拖动public bool isSelect;private void Update(){//让飞机上下缓缓飞(展示作用)通过sin函数 乘内测的数代表飞的频率 乘外侧的数代表飞的位移//基于世界坐标 飞机的展示面会倾斜 基于自己坐标是错的time += Time.deltaTime;this.airPos.Translate(Vector3.up * Mathf.Sin(time) * 0.001f,Space.World);//鼠标左键实现拖动 通过射线检测 将飞机的旋转角度以y旋转 度数为Mouse X * 10度if(Input.GetMouseButtonDown(0)){if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), 1000, 1 << LayerMask.NameToLayer("Air"))){isSelect = true;}}if(Input.GetMouseButtonUp(0)){isSelect = false;}if(isSelect && Input.GetMouseButton(0)){airPos.rotation *= Quaternion.AngleAxis(Input.GetAxis("Mouse X") * 10,Vector3.up);}}
}

2.玩家类(飞机超出屏幕问题未解决)
(1)当飞机左右移动时,需要有一定的倾斜,停止时恢复
(2)玩家类需要受伤 死亡 移动方法
知识点
(1)射线检测时销毁碰撞体(子弹)

public class PlayerObj : MonoBehaviour
{//写成一个单例类private static PlayerObj instance;public static PlayerObj Instance => instance;//maxHp代表最大血量 nowHp代表变量public int nowHp;public int maxHp;public int moveSpeed;public int rotaSpeed;//是否死亡public bool isDead;//目标四元数旋转角度Quaternion targetQ;private float hValue;private float vValue;//世界坐标的点 没有去屏幕外的点private Vector3 frontPos = new Vector3(-41,0,23);private Vector3 frontPos2 = new Vector3(41, 0, -23);//世界坐标转换为屏幕坐标的点private Vector3 nowPos;private void Awake(){instance = this;}void Update(){if (isDead)return;//GetAxisRaw 不是渐变 -1 1两个数//adhValue = Input.GetAxisRaw("Horizontal");//wsvValue = Input.GetAxisRaw("Vertical");//为0时说明静止if (hValue == 0)targetQ = Quaternion.identity;else//不为0时 按左键值会小于0 右键值会大于0 决定一下旋转的方向//可以得到一个目标的四元数targetQ = hValue < 0 ? Quaternion.AngleAxis(20, Vector3.forward) : Quaternion.AngleAxis(-20, Vector3.forward);//趋近于目标四元数this.transform.rotation = Quaternion.Slerp(this.transform.rotation, targetQ,Time.deltaTime * rotaSpeed);//正常移动this.transform.Translate(Vector3.forward * vValue * Time.deltaTime * moveSpeed);//左右移动不能使用自身坐标系 越动越会往下掉 要使用世界this.transform.Translate(Vector3.right * hValue * Time.deltaTime * moveSpeed,Space.World);//当前坐标的屏幕坐标点this.nowPos = Camera.main.WorldToScreenPoint(this.transform.position);//******************临时判断屏幕边缘的逻辑 当分辨率变化时会出错 暂未解决******************if (nowPos.x <= 0){//只管理x 不管理yzthis.transform.position = new Vector3(frontPos.x, this.transform.position.y, this.transform.position.z);}if (nowPos.y <= 0){this.transform.position = new Vector3(this.transform.position.x, this.transform.position.y, frontPos2.z);}if(nowPos.x >= Screen.width){this.transform.position = new Vector3(frontPos2.x, this.transform.position.y, this.transform.position.z);}if (nowPos.y >= Screen.height){this.transform.position = new Vector3(this.transform.position.x, this.transform.position.y, frontPos.z);}//获取碰到的对象的信息RaycastHit hit;if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 1000, 1 << LayerMask.NameToLayer("Bullet"))){//通过hit可以得到他身上所有的信息BulletObj bullet = hit.transform.GetComponent<BulletObj>();bullet.Dead();}}public void Wound(){this.nowHp -= 1;Debug.Log("当前血量" + nowHp);GamePanel.Instance.ChangHp(nowHp);if(nowHp <= 0){nowHp = 0;Dead();}}public void Dead(){isDead = true;EndPanel.Instance.ShowPanel();}
}

3.子弹类
(1)子弹的初始化数据 移动方式 生命周期 销毁以及碰撞检测

public class BulletObj : MonoBehaviour
{private BulletData data;private float time;/// <summary>/// 一个初始化方法 创建子弹时调用 传入目标数据/// </summary>/// <param name="id"></param>public void Init(int id){data = GameDataManager.Instance.bulletDatas[id - 1];//生命周期 到一定时间自动销毁子弹Invoke("DelayDestroy", data.destroyTime);}//startPos代表起始位置 下面做四元数匀速运动用的private void Awake(){startPos = this.transform;}//销毁子弹 创建特效public void Dead(){GameObject effObj = Instantiate(Resources.Load<GameObject>(data.effRes));effObj.transform.position = this.transform.position;Destroy(effObj,0.5f);Destroy(this.gameObject);}//碰撞检测public void OnTriggerEnter(Collider other){if(other.CompareTag("Player")){if(!PlayerObj.Instance.isDead){PlayerObj obj = other.GetComponent<PlayerObj>();obj.Wound();Dead();}else{this.Dead();}}}//不确定子弹会不会提前被移除掉 所以使用延迟函数 当子弹已经被移除的时候 就不会执行了public void DelayDestroy(){GameObject effObj = Instantiate(Resources.Load<GameObject>(data.effRes));effObj.transform.position = this.transform.position;Destroy(effObj, 0.5f);Destroy(this.gameObject);}//时间标识 做匀速运动用private float uniform;private Transform startPos;// Update is called once per framevoid Update(){//共同的特征 面朝向移动this.transform.Translate(Vector3.forward * data.forwardSpeed * Time.deltaTime);//1 直线运动//2 曲线运动//3 左抛物线//4 右抛物线//5 跟踪switch (data.type){case 2://sin里面的值 决定 左右变化的频率//sin后面的值 决定 左右位移的多少time += Time.deltaTime;this.transform.Translate(Vector3.right * Mathf.Sin(time * data.rightSpeed) * data.rotaSpeed * Time.deltaTime);break;case 3:this.transform.rotation *= Quaternion.AngleAxis(-data.rotaSpeed * Time.deltaTime,Vector3.up);break;case 4:this.transform.rotation *= Quaternion.AngleAxis(data.rotaSpeed * Time.deltaTime, Vector3.up);break;case 5://先快后慢 出现问题 "子弹无线接近目标旋转位置过远" 那要看一下是不是子弹的位置没有归0//这里使用匀速uniform += Time.deltaTime;Quaternion q = Quaternion.LookRotation(PlayerObj.Instance.transform.position - this.transform.position);this.transform.rotation = Quaternion.Slerp(this.startPos.rotation,q, uniform * data.rotaSpeed);break;}}
}

4.炮口点
(1)炮口的位置为上方三点 中间左右两点 下方三点
(2)炮口的初始角度(为了方便开火点四元数的计算)
(3)上下左右四个点的旋转角度是180度,四个角旋转角度都是90度,这样子弹才能合理地发射在屏幕内

public enum Type_PointType
{topLeft,topRight,topCenter,Left,Right,bottomLeft,bottomRight,bottomCenter
}
public class PointObj : MonoBehaviour
{public Type_PointType type = new Type_PointType();private Vector3 pos;//炮口的初始方向private Vector3 initPos;//炮口去拿到配置表中的数据 方便使用private int num;private float offset;private float delay;//全部的子弹数据List<BulletData> bullets;//单个开火数据public FireData fire;//单个子弹数据public BulletData bullet;// Update is called once per framevoid Update(){//初始化各个炮口的位置UpdatePos();//每次发射子弹的随机数 以及旋转角度的设置Reset();//发射子弹Fire();}public void UpdatePos(){//我们需要找到在z这一层的切面 因为其他子弹也需要在这一层//先根据玩家的世界坐标找到屏幕坐标的z是多少//然后设置世界坐标的z给pos//最后用屏幕转为世界坐标 让子弹出现的位置都在这一层即可pos.z = 40;switch(type){case Type_PointType.topLeft:pos.x = 0;pos.y = Screen.height;initPos = Vector3.right;break;case Type_PointType.topRight:pos.x = Screen.width;pos.y = Screen.height;initPos = Vector3.left;break;case Type_PointType.topCenter:pos.x = Screen.width/2;pos.y = Screen.height;initPos = Vector3.right;break;case Type_PointType.Left:pos.x = 0;pos.y = Screen.height/2;initPos = Vector3.right;break;case Type_PointType.Right:pos.x = Screen.width;pos.y = Screen.height/2;initPos = Vector3.left;break;case Type_PointType.bottomLeft:pos.x = 0;pos.y = 0;initPos = Vector3.right;break;case Type_PointType.bottomRight:pos.x = Screen.width;pos.y = 0;initPos = Vector3.left;break;case Type_PointType.bottomCenter:pos.x = Screen.width/2;pos.y = 0;initPos = Vector3.right;break;}this.transform.position = Camera.main.ScreenToWorldPoint(pos);}//旋转的角度private float angle;/// <summary>/// /// 随机数 将子弹的四种移动方式和开火的两种方式随机排列组合 想实现的功能看个人/// bullet 四种类型1.直线 2.曲线 3.左抛物线 4.右抛物线 5.跟踪  /// fire 两种类型1.连发 2.散弹/// </summary>public void Reset(){//终止条件的判断 如果子弹间隔时间和数量没有发完 不能从新随机if (offset != 0 && num != 0)return;if(fire != null){//delay代表每组子弹的间隔时间delay -= Time.deltaTime;if(delay > 0){return;}}//拿到全部的开火数据 随机选择开火方式List<FireData> fires = GameDataManager.Instance.fireData;fire = fires[Random.Range(0, fires.Count)];//本地拿到初始值this.num = fire.num;this.offset = fire.offset;this.delay = fire.delay;//拿到全部的子弹数据 随机选择子弹移动方式bullets = GameDataManager.Instance.bulletDatas;bullet = bullets[Random.Range(0, bullets.Count)];//1.左上角和右下角发射右抛物线//2.左下角和右上角发射左抛物线//3.type = 3 是左抛物线 type = 4 是右抛物线if(fire.type == 2){//2类型是散弹 需要随机角度switch (type){case Type_PointType.topLeft:case Type_PointType.bottomLeft:case Type_PointType.topRight:case Type_PointType.bottomRight:angle = 90 / num;break;case Type_PointType.topCenter:case Type_PointType.Left:case Type_PointType.Right:case Type_PointType.bottomCenter:angle = 180 / num;break;}}}private Vector3 newRot;/// <summary>/// 开火 个人决定开火口能发射怎样的子弹/// 核心点:根据不同的开火方式 去创建子弹 以及子弹特效 子弹的位置 子弹的旋转角度/// </summary>public void Fire(){if (type == Type_PointType.topLeft || type == Type_PointType.bottomRight){bullet.type = 4;}if (type == Type_PointType.topRight || type == Type_PointType.bottomLeft){bullet.type = 3;}//间隔时间和数量归0 不会进入循环if (offset == 0 && num == 0)return;//每个子弹的判断放到最前面offset -= Time.deltaTime;//当间隔时间大于0 还在等待期 if (offset > 0)return;GameObject go;switch (fire.type){case 1:go = Instantiate(Resources.Load<GameObject>(bullet.bulletRes));go.GetComponent<BulletObj>().Init(bullet.id);go.transform.position = this.transform.position;go.transform.rotation = Quaternion.LookRotation(PlayerObj.Instance.transform.position - this.transform.position);//子弹减少--num;//当子弹发射完成后 间隔时间归0 就不会再次进入循环 没发射完就重置间隔时间offset = num == 0 ? 0 : fire.offset;break;case 2://散弹不能发射曲线子弹if (bullet.type != 2){for (int i = 0; i < num; i++){go = Instantiate(Resources.Load<GameObject>(bullet.bulletRes));go.GetComponent<BulletObj>().Init(bullet.id);go.transform.position = this.transform.position;//四元数乘向量 得到新的向量//每次旋转i * 20 newRot = Quaternion.AngleAxis(i * angle, Vector3.up) * initPos;//新的方向给四元数 最后赋值给角度即可go.transform.rotation = Quaternion.LookRotation(newRot);}offset = num = 0;}else{Reset();}break;}}
}

5.Main调用
(1)最后通过Main放置在游戏场景,当进入场景时,根据选择的id创建飞机,初始化变量,更新界面的ui,其实放在GamePanel中也是一样的,都可以

相关文章:

Unity太空避障Demo总结

太空避障&#xff1a;主要是实现飞机躲避子弹 面板基类、音乐类、排行榜类、json等等都和上一篇Unity坦克迷宫Demo总结一样&#xff0c;太空避障主要是对四元数的练习和使用 1.选择飞机面板 &#xff08;1&#xff09;通过左右按钮对显示的模型进行切换 &#xff08;2&#xff…...

SpringSecurity-重写默认配置

重写UserDetailService组件 1.注入Bean的方式 /*** author: coffee* date: 2024/6/22 21:22* description: 重写springsecurity默认组件&#xff1a;注入Bean的方式*/Configuration public class ProjectConfig {/*** 重写userDetailsService组件*/Beanpublic UserDetailsSer…...

C# 判断值是否在枚举里

你还在代码里面通篇通过数字的定义类型。比如type为1 表示xx,type为2 表示yy吗&#xff1f;然后程序里面通过数字1和2来判断吗&#xff1f;比如下面类似的代码&#xff1a; if(type1){ //.... } else if(type2){ //... } else if(type3){ //... } 老鸟们一般都会用枚举来定义…...

Interview preparation--elasticSearch倒排索引原理

搜索引擎应该具备哪些要求 查询速度快 优秀的索引结构设计高效率的压缩算法快速的编码和解码速度 结果准确 ElasiticSearch 中7.0 版本之后默认使用BM25 评分算法ElasticSearch 中 7.0 版本之前使用 TP-IDF算法 倒排索引原理 当我们有如下列表数据信息&#xff0c;并且系统…...

银河麒麟高级服务器操作系统V10SP2(X86)配置bond0的mac地址为指定子网卡的mac地址

银河麒麟高级服务器操作系统V10SP2&#xff08;X86&#xff09;配置bond0的mac地址为指定子网卡的mac地址 一 系统环境二 删除和备份原有配置2.1 down掉bond02.2 备份之前的bond配置到/root/bak2.3 删除bond配置&#xff08;网卡文件根据实际情况变化&#xff09; 三 新建bond0…...

python中不同维度的Tensor向量为何可以直接相加——广播机制

文章目录 广播机制示例解释广播机制如何工作代码示例输出解释广播机制的本质 在矩阵加法中&#xff0c;如果两个张量的形状不同&#xff0c;但其中一个张量的形状可以通过广播机制扩展到与另一个张量的形状相同&#xff0c;则可以进行加法操作。广播机制在深度学习框架&#xf…...

38.MessageToMessageCodec线程安全可被共享Handler

handler被注解@Sharable修饰的。 这样的handler,创建一个实例就够了。例如: ByteToMessageCodec的子类不能被@Sharable修饰 如果自定义类是MessageToMessageCodec的子类就是线程共享的,可以被@Sharable修饰的 package com.xkj.protocol;import com.xkj.message.Message; i…...

Linux中的全局环境变量和局部环境变量

Linux中的全局环境变量和局部环境变量 一、全局环境变量二、局部环境变量三、 设置全局环境变量 bash shell用一个叫作环境变量 &#xff08;environment variable&#xff09;的特性来存储有关shell会话和工作环境的信息&#xff08;这也是它们被称作环境变量的原 因&#xff…...

【研究】AI大模型需要什么样的硬件?

关注AI大模型 x 硬件的两条思路 从22年11月OpenAI推出ChatGPT至今&#xff0c;我们看到Chatbot应用的能力不断增强&#xff0c;从最初的文字问答&#xff0c;迅速向具有自主记忆、推理、规划和执行的全自动能力的AI Agent发展。我们认为端侧智能是大模型发展的重要分支。建议投…...

人工智能--自然语言处理NLP概述

欢迎来到 Papicatch的博客 目录 &#x1f349;引言 &#x1f348;基本概念 &#x1f348;核心技术 &#x1f348;常用模型和方法 &#x1f348;应用领域 &#x1f348;挑战和未来发展 &#x1f349;案例分析 &#x1f348;机器翻译中的BERT模型 &#x1f348;情感分析在…...

基于Java微信小程序火锅店点餐系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f;感兴趣的可以先收藏起来&#xff0c;还…...

SpringCloud_GateWay服务网关

网关作用 Gateway网关是我们服务的守门神&#xff0c;所有微服务的统一入口。 网关的核心功能特性&#xff1a; 请求路由和负载均衡&#xff1a;一切请求都必须先经过gateway&#xff0c;但网关不处理业务&#xff0c;而是根据某种规则&#xff0c;把请求转发到某个微服务&a…...

使用Dropout大幅优化PyTorch模型,实现图像识别

大家好&#xff0c;在机器学习模型中&#xff0c;如果模型的参数太多&#xff0c;而训练样本又太少&#xff0c;训练出来的模型很容易产生过拟合的现象。在训练神经网络时&#xff0c;过拟合具体表现在模型训练数据损失函数较小&#xff0c;预测准确率较高&#xff0c;但是在测…...

Vue3中的常见组件通信(超详细版)

Vue3中的常见组件通信 概述 ​ 在vue3中常见的组件通信有props、mitt、v-model、 r e f s 、 refs、 refs、parent、provide、inject、pinia、slot等。不同的组件关系用不同的传递方式。常见的撘配形式如下表所示。 组件关系传递方式父传子1. props2. v-model3. $refs4. 默认…...

Stm32的DMA的学习

一&#xff0c;介绍 二&#xff0c;DMA框图 三&#xff0c;DMA通道 四&#xff0c;相关HAL库函数 五&#xff0c;配置DMA 六&#xff0c;Stm32CubeMX配置 【13.1】减少CPU传输负载 DMA直接存储器访问—Kevin带你读《STM32Cube高效开发教程基础篇》_哔哩哔哩_bilibili...

应用安全(补充)

Nessus是目前全世界最多人使用的系统漏洞扫描与分析软件。NMAP是一个网络连接端扫描软件&#xff0c;用来扫描网上电脑开放的网络连接端。X-SCAN安全漏洞扫描工具AppScan是IBM的一款web安全扫描工具&#xff0c;可以利用爬虫技术进行网站安全渗透测试&#xff0c;根据网站入口自…...

鸿蒙开发Ability Kit(程序框架服务):【FA模型切换Stage模型指导】 app和deviceConfig的切换

app和deviceConfig的切换 为了便于开发者维护应用级别的属性配置&#xff0c;Stage模型将config.json中的app和deviceConfig标签提取到了app.json5中进行配置&#xff0c;并对部分标签名称进行了修改&#xff0c;具体差异见下表。 表1 配置文件app标签差异对比 配置项FA模型…...

通过命令行配置调整KVM的虚拟网络

正文共&#xff1a;1234 字 20 图&#xff0c;预估阅读时间&#xff1a;2 分钟 在上篇文章中&#xff08;最小化安装的CentOS7部署KVM虚拟机&#xff09;&#xff0c;我们介绍了如何在最小化安装的CentOS 7系统中部署KVM组件和相关软件包。因为没有GUI图形界面&#xff0c;我们…...

Apache POI操作excel

第1部分&#xff1a;引言 1.1 Apache POI简介 Apache POI是一个开源的Java库&#xff0c;用于处理Microsoft Office文档。自2001年首次发布以来&#xff0c;它已经成为Java社区中处理Office文档事实上的标准。Apache POI支持HSSF&#xff08;用于旧版本的Excel格式&#xff0…...

Python错误集锦:faker模块生成xml文件时提示:`xml` requires the `xmltodict` Python library

原文链接&#xff1a;http://www.juzicode.com/python-error-faker-exceptions-unsupportedfeature-xml-requires-the-xmltodict-python-library 错误提示&#xff1a; faker模块生成xml文件时提示&#xff1a; xml requires the xmltodict Python library Traceback (most r…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...