项目02《游戏-08-开发》Unity3D
基于 项目02《游戏-07-开发》Unity3D ,
本次任务做物品相互与详情的功能,
首先要做 点击相应,
接下来用接口实现点击相应事件,具体到代码中,我们找到需要响应鼠标事件的对象,
双击PackageCell.cs脚本修改代码:添加鼠标响应接口,
三个接口分别对鼠标的点击,进入,退出事件,
Alt + Enter 实现这三个接口,
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class PackageCell : MonoBehaviour,IPointerClickHandler,IPointerEnterHandler,IPointerExitHandler{
Transform UIIcon;
Transform UIHead;
Transform UINew;
Transform UISelect;
Transform UILevel;
Transform UIStars;
Transform UIDeleteSelect;
//动态数据
PackageLocalItem packageLocalData;
//静态数据
PackageTableItem packageTableItem;
//父物体也就是PackagePanel本身
PackagePanel uiParent;
void Awake(){
InitUIName();
}
void InitUIName(){
UIIcon = transform.Find("Top/Icon");
UIHead = transform.Find("Top/Head");
UINew = transform.Find("Top/New");
UILevel = transform.Find("Bottom/LevelText");
UIStars = transform.Find("Bottom/Stars");
UISelect = transform.Find("Select");
UIDeleteSelect = transform.Find("DeleteSelect");
UIDeleteSelect.gameObject.SetActive(false);
}
//刷新
public void Refresh(PackageLocalItem packageLocalData, PackagePanel uiParent){
//数据初始化
this.packageLocalData = packageLocalData;
this.packageTableItem = MainGame.Instance.GetPackageItemById(packageLocalData.id);
this.uiParent = uiParent;
//等级信息
UILevel.GetComponent<Text>().text = "Lv." + this.packageLocalData.level.ToString();
//是否是新获得?
UINew.gameObject.SetActive(this.packageLocalData.isNew);
Debug.Log("ImagePath: " + this.packageTableItem.imagePath);
//物品的图片
Texture2D t = (Texture2D)Resources.Load(this.packageTableItem.imagePath);
if (t != null){
Sprite temp = Sprite.Create(t, new Rect(0, 0, t.width, t.height), new Vector2(0, 0));
// 继续处理 Sprite 对象
UIIcon.GetComponent<Image>().sprite = temp;
}
else{
// 处理纹理加载失败的情况
Debug.LogError("Failed to load texture.");
}
//刷新星级
RefreshStars();
}
//刷新星级
public void RefreshStars(){
for (int i = 0; i < UIStars.childCount; i++){
Transform star = UIStars.GetChild(i);
if (this.packageTableItem.star > i)
star.gameObject.SetActive(true);
else
star.gameObject.SetActive(false);
}
}
public void OnPointerClick(PointerEventData eventData){
Debug.Log($"OnPointerClick {eventData.ToString()}");
}
public void OnPointerEnter(PointerEventData eventData){
Debug.Log($"OnPointerEnter {eventData.ToString()}");
}
public void OnPointerExit(PointerEventData eventData){
Debug.Log($"OnPointerExit {eventData.ToString()}");
}
}
回到unity编辑器中,
运行项目当我们鼠标悬停在武器Icon上就会有输出显示,
下一步是处理点击事件具体响应逻辑,
当鼠标点击物品时,右侧的详情界面会根据物品的信息进行刷新,
DetailPanel是PackagePanel下的子物体,也是我们要处理的对象,我们要对DetailPanel详情界面进行更新,
所以我们在Scripts脚本文件夹中添加一个脚本PackageDetail.cs用来更新详情界面DetailPanel对象,
然后将PackageDetail.cs脚本绑定在DetailPanel对象身上,
类似于上集的PackageCell逻辑,我们可以把DetailPanel也当作一个独立的对象进行处理,
双击PackagDetail.cs脚本修改代码:
using UnityEngine;
using UnityEngine.UI;
public class PackageDetail : MonoBehaviour{
Transform UIStars;
Transform UIDescription;
Transform UIIcon;
Transform UITitle;
Transform UILevelText;
Transform UISkillDescription;
PackageLocalItem packageLocalData;
PackageTableItem packageTableItem;
PackagePanel uiParent;
void Awake(){
InitUIName();
Test();
}
void Test() {
Refresh(MainGame.Instance.GetPackageLocalData()[1], null);
}
void InitUIName(){
UIStars = transform.Find("Center/Stars");
UIDescription = transform.Find("Center/Description");
UIIcon = transform.Find("Center/Icon");
UITitle = transform.Find("Top/Title");
UILevelText = transform.Find("Bottom/LevelPnl/LevelText");
UISkillDescription = transform.Find("Bottom/Description");
}
public void Refresh(PackageLocalItem packageLocalData, PackagePanel uiParent) {
//初始化:动态数据,静态数据,父物品逻辑
this.packageLocalData = packageLocalData;
this.packageTableItem = MainGame.Instance.GetPackageItemById(packageLocalData.id);
this.uiParent = uiParent;
//等级
UILevelText.GetComponent<Text>().text = string.Format($"Lv.{this.packageLocalData.level.ToString()}");
//简短描述
UIDescription.GetComponent<Text>().text = this.packageTableItem.description;
//详细描述
UISkillDescription.GetComponent<Text>().text = this.packageTableItem.skillDescription;
//物品名称
UITitle.GetComponent<Text>().name = this.packageTableItem.name;
//图片加载
Texture2D t = (Texture2D)Resources.Load(this.packageTableItem.imagePath);
Sprite temp = Sprite.Create(t, new Rect(0, 0, t.width, t.height), new Vector2(0, 0));
UIIcon.GetComponent<Image>().sprite = temp;
//星级处理
RefreshStars();
}
public void RefreshStars(){
for (int i = 0; i < UIStars.childCount; i++) {
Transform star = UIStars.GetChild(i);
if(this.packageTableItem.star > i)
star.gameObject.SetActive(true);
else
star.gameObject.SetActive(false);
}
}
}
回到unity编辑器中,运行项目可见详情页面被替换成
测试方法的第二张图片,
下一步要做的事情是当点击某个物品时,详情界面会根据鼠标点击的物品进行展示,
打开PackagePanel.cs脚本修改代码: 这是背包的主题逻辑部分
当前选中的物品总要被记录,把记录的地方放在PackagePanel中,
using UnityEngine;
using UnityEngine.UI;
public class PackagePanel : BasePanel{
Transform UIMenu;
Transform UIMenuWeapon;
Transform UIMenuFood;
Transform UITabName;
Transform UICloseBtn;
Transform UICenter;
Transform UIScrollView;
Transform UIDetailPanel;
Transform UILeftBtn;
Transform UIRightBtn;
Transform UIDeletePanel;
Transform UIDeleteBackBtn;
Transform UIDeleteInfoText;
Transform UIDeleteConfirmBtn;
Transform UIBottomMenus;
Transform UIDeleteBtn;
Transform UIDetailBtn;
//添加
public GameObject PackageUIItemPrefab;
//添加 表示当前选中的物品时哪一个uid
string _chooseUid;
public string ChooseUid {
get { return _chooseUid; }
set {
_chooseUid = value;
RefreshDetail();
}
}
void RefreshDetail() {
//找到uid对应的动态数据
PackageLocalItem localItem = MainGame.Instance.GetPackageLocalItemByUId(ChooseUid);
//刷新详情界面
UIDetailPanel.GetComponent<PackageDetail>().Refresh(localItem, this);
}
override protected void Awake(){
base.Awake();
InitUI();
}
//添加1
void Start(){
RefreshUI();
}
//添加1
void RefreshUI(){
RefreshScroll();
}
//添加1
void RefreshScroll(){
//清理滚动容器中原本的物品
RectTransform scrollContent = UIScrollView.GetComponent<ScrollRect>().content;
for (int i = 0; i < scrollContent.childCount; i++)
Destroy(scrollContent.GetChild(i).gameObject);
//获取本地数据的方法拿到自己身上背包数据 并且根据背包数据初始化滚动容器
foreach (PackageLocalItem localData in MainGame.Instance.GetSortPackageLocalData()){
Transform PackageUIItem = Instantiate(PackageUIItemPrefab.transform, scrollContent) as Transform;
PackageCell packageCell = PackageUIItem.GetComponent<PackageCell>();
//添加2
packageCell.Refresh(localData, this);
}
}
void InitUI(){
InitUIName();
InitClick();
}
void InitUIName(){
UIMenu = transform.Find("TopCenter/Menu");
UIMenuWeapon = transform.Find("TopCenter/Menus/Weapon");
UIMenuFood = transform.Find("TopCenter/Menus/Food");
UITabName = transform.Find("LeftTop/TabName");
UICloseBtn = transform.Find("RightTop/Close");
UICenter = transform.Find("Center");
UIScrollView = transform.Find("Center/Scroll View");
UIDetailPanel = transform.Find("Center/DetailPanel");
UILeftBtn = transform.Find("Left/Button");
UIRightBtn = transform.Find("Right/Button");
UIDeletePanel = transform.Find("Bottom/DeletePanel");
UIDeleteBackBtn = transform.Find("Bottom/DeletePanel/Back");
UIDeleteInfoText = transform.Find("Bottom/DeletePanel/InfoText");
UIDeleteConfirmBtn = transform.Find("Bottom/DeletePanel/ConfirmBtn");
UIBottomMenus = transform.Find("Bottom/BottomMenus");
UIDeleteBtn = transform.Find("Bottom/BottomMenus/DeleteBtn");
UIDetailBtn = transform.Find("Bottom/BottomMenus/DetailBtn");
UIDeletePanel.gameObject.SetActive(false);
UIBottomMenus.gameObject.SetActive(true);
}
void InitClick(){
UIMenuWeapon.GetComponent<Button>().onClick.AddListener(OnClickWeapon);
UIMenuFood.GetComponent<Button>().onClick.AddListener(OnClickFood);
UICloseBtn.GetComponent<Button>().onClick.AddListener(OnClickClose);
UILeftBtn.GetComponent<Button>().onClick.AddListener(OnClickLeft);
UIRightBtn.GetComponent<Button>().onClick.AddListener(OnClickRight);
UIDeleteBackBtn.GetComponent<Button>().onClick.AddListener(OnDeleteBack);
UIDeleteConfirmBtn.GetComponent<Button>().onClick.AddListener(OnDeleteConfirm);
UIDeleteBtn.GetComponent<Button>().onClick.AddListener(OnDelete);
UIDetailBtn.GetComponent<Button>().onClick.AddListener(OnDetail);
}
void OnDetail(){
print(">>>>>>> OnDetail()");
}
void OnDelete(){
print(">>>>>>> OnDelete()");
}
void OnDeleteConfirm(){
print(">>>>>>> OnDeleteConfirm()");
}
void OnDeleteBack(){
print(">>>>>>> OnDeleteBack()");
}
void OnClickRight(){
print(">>>>>>> OnClickRight()");
}
void OnClickLeft(){
print(">>>>>>> OnClickLeft()");
}
void OnClickWeapon(){
print(">>>>>>> OnClickWeapon()");
}
void OnClickFood(){
print(">>>>>>> OnClickFood()");
}
void OnClickClose(){
ClosePanel();
}
}
因为物品的逻辑是写在PackageCell.cs脚本中,
那么找到PackageCell点击的回调方法,
也就是OnPointerClick()方法,
修改PackageCell.cs脚本:
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class PackageCell : MonoBehaviour,IPointerClickHandler,IPointerEnterHandler,IPointerExitHandler{
Transform UIIcon;
Transform UIHead;
Transform UINew;
Transform UISelect;
Transform UILevel;
Transform UIStars;
Transform UIDeleteSelect;
//动态数据
PackageLocalItem packageLocalData;
//静态数据
PackageTableItem packageTableItem;
//父物体也就是PackagePanel本身
PackagePanel uiParent;
void Awake(){
InitUIName();
}
void InitUIName(){
UIIcon = transform.Find("Top/Icon");
UIHead = transform.Find("Top/Head");
UINew = transform.Find("Top/New");
UILevel = transform.Find("Bottom/LevelText");
UIStars = transform.Find("Bottom/Stars");
UISelect = transform.Find("Select");
UIDeleteSelect = transform.Find("DeleteSelect");
UIDeleteSelect.gameObject.SetActive(false);
}
//刷新
public void Refresh(PackageLocalItem packageLocalData, PackagePanel uiParent){
//数据初始化
this.packageLocalData = packageLocalData;
this.packageTableItem = MainGame.Instance.GetPackageItemById(packageLocalData.id);
this.uiParent = uiParent;
//等级信息
UILevel.GetComponent<Text>().text = "Lv." + this.packageLocalData.level.ToString();
//是否是新获得?
UINew.gameObject.SetActive(this.packageLocalData.isNew);
Debug.Log("ImagePath: " + this.packageTableItem.imagePath);
//物品的图片
Texture2D t = (Texture2D)Resources.Load(this.packageTableItem.imagePath);
if (t != null){
Sprite temp = Sprite.Create(t, new Rect(0, 0, t.width, t.height), new Vector2(0, 0));
// 继续处理 Sprite 对象
UIIcon.GetComponent<Image>().sprite = temp;
}
else{
// 处理纹理加载失败的情况
Debug.LogError("Failed to load texture.");
}
//刷新星级
RefreshStars();
}
//刷新星级
public void RefreshStars(){
for (int i = 0; i < UIStars.childCount; i++){
Transform star = UIStars.GetChild(i);
if (this.packageTableItem.star > i)
star.gameObject.SetActive(true);
else
star.gameObject.SetActive(false);
}
}
public void OnPointerClick(PointerEventData eventData){
if (this.uiParent.ChooseUid == this.packageLocalData.uid)
return;
//根据点击设置最新的uid 进而刷新详情界面
this.uiParent.ChooseUid = this.packageLocalData.uid;
}
public void OnPointerEnter(PointerEventData eventData){
Debug.Log($"OnPointerEnter {eventData.ToString()}");
}
public void OnPointerExit(PointerEventData eventData){
Debug.Log($"OnPointerExit {eventData.ToString()}");
}
}
回到unity编辑器中运行项目,点开背包点击物品查看详情页面的更新,
已实现点击背包物品更换详情页面,
下一步实现UI动画点击效果动画,
首先在ACs动画控制器文件包中创建一个UI文件夹准备放UI动画,
在UI文件夹中创建两个PackageAC背包控制器,
其中PackageAC1代表鼠标掠过的动画控制器,PackageAC2代表鼠标选中的动画控制器,
在PackageItem预制体空间下创建两个空物体,
设置尺寸,
设置子物体Image为拉伸模式
重命名Image为Image1,并设置比例为1.1
再创建Image2,同样设置比例为1.2,拉伸模式
同样添加选中图片,
接下来在ACs的UI文件夹中创建动画Animation,命名为PackageSelectAni
在这个文件夹再创建两个动画,分别对应 鼠标进入物品 和 退出物品 的效果,
下一步绑定组件Animator,将PackageAC1拖拽给 选中对象,
打开PackageAC1动画控制器,将PackageSelectAni动画拖拽在动画控制器中,
创建一个空状态并连线,
然后添加Trigger类型的变量,
接着双击打开Animation这个窗口,
选中设置谁的动画,
同样添加Image2的color,
点击左上角的红点即可进入录制模式,点击播放修改两个image的d颜色为0,再次点击结束录制即可,
同样方法绑定鼠标点击对象组件Animator并拖拽PackageAC2,
双击PackageAC2进入动画控制器,并拖拽其余两个动画,
还是把默认条件设置为空状态,
然后创建两个转换变量In 和 Out,用来设置切换鼠标进入与鼠标退出,
对于MouseOverAni这个对象添加一个Image,并设置大小,拉伸模式
我们先将SelectAni隐藏,
还是添加一个color,
1.点击录制,
2.拖动动画线到中间,设置color d 为 0,
3.调试:
4.结束录制,
同样手法配置PackageMouseOut动画,
提醒:In的动画color透明度变化是 0 - 1 - 0,而Out的动画color透明度变化是 1 - 0,
Select的动画为 0.5 - 1-0.5 - 0,总之最后透明度均为0,
动画控制器设置完成,
下一步修改PackageCell.cs脚本:
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class PackageCell : MonoBehaviour,IPointerClickHandler,IPointerEnterHandler,IPointerExitHandler{
Transform UIIcon;
Transform UIHead;
Transform UINew;
Transform UISelect;
Transform UILevel;
Transform UIStars;
Transform UIDeleteSelect;
//添加
Transform UISelectAni;
Transform UIMouseOverAni;
//动态数据
PackageLocalItem packageLocalData;
//静态数据
PackageTableItem packageTableItem;
//父物体也就是PackagePanel本身
PackagePanel uiParent;
void Awake(){
InitUIName();
}
void InitUIName(){
UIIcon = transform.Find("Top/Icon");
UIHead = transform.Find("Top/Head");
UINew = transform.Find("Top/New");
UILevel = transform.Find("Bottom/LevelText");
UIStars = transform.Find("Bottom/Stars");
UISelect = transform.Find("Select");
UIDeleteSelect = transform.Find("DeleteSelect");
//添加
UIMouseOverAni = transform.Find("MouseOverAni");
UISelectAni = transform.Find("SelectAni");
UIDeleteSelect.gameObject.SetActive(false);
//添加
UIMouseOverAni.gameObject.SetActive(false);
UISelectAni.gameObject.SetActive(false);
}
//刷新
public void Refresh(PackageLocalItem packageLocalData, PackagePanel uiParent){
//数据初始化
this.packageLocalData = packageLocalData;
this.packageTableItem = MainGame.Instance.GetPackageItemById(packageLocalData.id);
this.uiParent = uiParent;
//等级信息
UILevel.GetComponent<Text>().text = "Lv." + this.packageLocalData.level.ToString();
//是否是新获得?
UINew.gameObject.SetActive(this.packageLocalData.isNew);
Debug.Log("ImagePath: " + this.packageTableItem.imagePath);
//物品的图片
Texture2D t = (Texture2D)Resources.Load(this.packageTableItem.imagePath);
if (t != null){
Sprite temp = Sprite.Create(t, new Rect(0, 0, t.width, t.height), new Vector2(0, 0));
// 继续处理 Sprite 对象
UIIcon.GetComponent<Image>().sprite = temp;
}
else{
// 处理纹理加载失败的情况
Debug.LogError("Failed to load texture.");
}
//刷新星级
RefreshStars();
}
//刷新星级
public void RefreshStars(){
for (int i = 0; i < UIStars.childCount; i++){
Transform star = UIStars.GetChild(i);
if (this.packageTableItem.star > i)
star.gameObject.SetActive(true);
else
star.gameObject.SetActive(false);
}
}
public void OnPointerClick(PointerEventData eventData){
if (this.uiParent.ChooseUid == this.packageLocalData.uid)
return;
//根据点击设置最新的uid 进而刷新详情界面
this.uiParent.ChooseUid = this.packageLocalData.uid;
UISelectAni.gameObject.SetActive(true);
UISelectAni.GetComponent<Animator>().SetTrigger("In");
}
public void OnPointerEnter(PointerEventData eventData){
UIMouseOverAni.gameObject.SetActive(true);
UIMouseOverAni.GetComponent<Animator>().SetTrigger("In");
}
public void OnPointerExit(PointerEventData eventData){
Debug.Log($"OnPointerExit {eventData.ToString()}");
}
}
最后这个操作可以确保我们的子物品不会影响我们点触事件的判断,
运行项目即可实现,
鼠标滑动效果,
鼠标点击效果,
点击右上角×退出键即可退出面板,
End.
相关文章:

项目02《游戏-08-开发》Unity3D
基于 项目02《游戏-07-开发》Unity3D , 本次任务做物品相互与详情的功能, 首先要做 点击相应, 接下来用接口实现点击相应事件,具体到代码中,我们找到需要响应鼠标事件的对象, 双击PackageCell…...

【数据库原理及应用】简答题归纳总结
第一章 数据库概论 1.人工管理阶段数据管理的特点: (1)数据不保存在机器中 (2)无专用的软件对数据进行管理 (3)只有程序的概念,没有文件的概念 (4)数据面向程…...

通过无线打通两个路由器
通过无线打通两个路由器 上网向导无线连接 配置比较简单,有些路由器支持有些不支持,支持的大致就是下面的方法,不过不同型号面板不一样,这里主要学习方法,所以不做路由器型号介绍。 重要的事情说三遍:学习要…...

idea 配置文件,中文出现乱码如何解决
在进行 spring 项目开发时,项目中有 application.properties/application.yml 等配置文件,在配置文件中使用中文注解时可能会出现乱码的情况,如下: 这是因为 idea 配置文件的编码和其他文件的不同,我们需要修改配置文件…...

网络协议梳理
1 引言 在计算机网络中要做到有条不紊地交换数据,就必须遵守一些事先约定好的规则。这些规则明确规定了所交换的数据的格式以及有关的同步问题。这里所说的同步不是狭义的(即同频或同频同相)而是广义的,即在一定的条件下应当发生什…...

14. 【Linux教程】文件压缩与解压
文件压缩与解压 前面小节介绍了如何对文件和目录删除、移动操作,本小节介绍如何使用命令对文件和目录进行压缩与解压操作,常见的压缩包格式有 .bz2、.Z、.gz、.zip、.xz,压缩之后的文件或目录占用更少的空间。 1. tar 命令介绍 下面列举 ta…...

ruoyi-nbcio中xxl-job的安装与使用
更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址: http://122.227.135.243:9666 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码: https://gitee.com/nbach…...
从零学算法162
162.峰值元素是指其值严格大于左右相邻值的元素。 给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。 你可以假设 nums[-1] nums[n] -∞ 。 你必须实现时间复杂度为 O…...

5.0 ZooKeeper 数据模型 znode 结构详解
数据模型 在 zookeeper 中,可以说 zookeeper 中的所有存储的数据是由 znode 组成的,节点也称为 znode,并以 key/value 形式存储数据。 整体结构类似于 linux 文件系统的模式以树形结构存储。其中根路径以 / 开头。 进入 zookeeper 安装的 …...

《数电》理论笔记-第1章-逻辑代数基础
参考:视频 和 《数字电路与逻辑设计》 电子书 一,第1章 逻辑代数基础 1 数字量和模拟量 略 2 数制(十进制,二进制,八进制和十六进制) 拨电话(BoDH)---(2八10十六&…...
计算指定路径下的可用空间大小
方法一、使用psutil库 import psutildef check_disk_space(path):usage psutil.disk_usage(path)## 1GB 1 * 1024 * 1024 * 1024字节if usage.free > 1 * 1024 * 1024 * 1024:return 1else:return 0disk_path "/home" result check_disk_space(disk_path) pr…...

2023年全球软件架构师峰会(ArchSummit上海站):核心内容与学习收获(附大会核心PPT下载)
微服务架构是当今软件架构的主流趋势之一。随着云计算和分布式系统的普及,越来越多的企业开始采用微服务架构来构建他们的应用。微服务架构可以将一个大型的应用拆分成多个小型的服务,每个服务都独立部署、独立运行,并通过轻量级的通信协议进…...
踩坑实录(Second Day)
作为公司的小菜鸟,每天都踩坑应该是一件很正常的事情吧,哈哈哈。今天遇到了比较棘手的问题,以前从来没有遇到过。然后就是在某平台上接的一个 bug 修改的单子,也拿出来和大家分享一下~ 此为第二篇(2024 年 02 月 05 日…...
已解决org.springframework.web.HttpMediaTypeNotAcceptableException异常的正确解决方法,亲测有效!!!
已解决org.springframework.web.HttpMediaTypeNotAcceptableException异常的正确解决方法,亲测有效!!! 文章目录 问题分析 报错原因 解决思路 解决方法 总结 问题分析 在Spring MVC应用中处理HTTP请求时,我们有…...

根据MySql建表语句创建Java实体类工具
点击下载《根据MySql建表语句创建Java实体类工具》 1. 前言 在软件开发领域,特别是在构建企业级应用时,数据模型与代码模型之间的映射是至关重要的。该软件是一款基于C#开发的高效工具,它将这一繁琐且容易出错的过程变得简洁且快速。此工具…...

做跨境电商需要使用住宅代理IP吗?
住宅代理IP是近年来跨境电商领域日益受到重视的技术工具,不仅可以保护隐私、优化网络速度,还能助推跨境电商的精细化管理。接下来,我们将深入探讨利用住宅代理IP如何为跨境电商业务带来竞争优势。 一、住宅代理IP与跨境电商 住宅代理IP&…...

vue3 之 组合式API—reactive和ref函数
ref() 作用:接收简单类型或者对象类型的数据传入并返回一个响应式的对象 核心步骤: 1️⃣ 从 vue 包中导入 ref 函数 2️⃣在 <script setup>// 导入import { ref } from vue// 执行函数 传入参数 变量接收const count …...

Python库-PyAutoGUI
pyautogui是一个Python库,可以自动控制键盘和鼠标,非常适合进行自动化任务。它可以用于各种场景,比如自动化测试、数据录入任务,甚至是简单的游戏机器人。下面是一个关于pyautogui的入门教程,包括它的安装、基本使用方…...
越权测试是什么?
一、越权测试是什么? 越权漏洞是web应用程序中常见的一种安全漏洞。它的威胁在于一个账户可控制全站用户数据。越权漏洞产生的原因主要是因为开发人员在对数据进行增删改查时对客户端的请求数据过分相信而遗漏了权限的判定。 二、越权漏洞的分类 越权分为2种&…...

H5 简约四色新科技风引导页源码
H5 简约四色新科技风引导页源码 源码介绍:一款四色切换自适应现代科技风动态背景的引导页源码,源码有主站按钮,分站按钮2个,QQ联系站长按钮一个。 下载地址: https://www.changyouzuhao.cn/11990.html...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...