54. UE5 RPG 增加伤害类型
在正常的RPG游戏中,都存在一个类别就是属性伤害,比如,在一个游戏里面有一个火属性的技能,它造成的伤害就是火属性类型的,并且它还有可能有附加伤害,比如给予目标一个灼烧效果,每秒造成多少的火属性伤害。目标角色会有一个火属性伤害抵抗,根据百分比减少伤害。
比如英雄联盟技能伤害区分物理伤害和魔法伤害,有些技能能够造成两种伤害,比如卡特和永恩。
接下来,我们为游戏的伤害增加属性。
增加新的技能类
首先,我们基于自定义的技能类,创建一个派生的子类,专门用于处理具有伤害的技能。基类作为所有技能的基类,有可能技能时回血的,那么它的伤害相应的属性是使用不到的,属于浪费。

取名为RPGDamageGameplayAbility 专门用于处理伤害的技能的基类

记得将投掷技能释放物的类继承修改掉

将设置伤害的GE配置项从UProjectileSpell里面移到伤害类,并将基类上的伤害设置删除掉,为了能够让技能实现多种类型的伤害,我们通过一个Map来创建一个配置,可以在Map中设置多种伤害类型,并设置对应需造成的伤害。

增加对应的属性抗性标签
既然要增加伤害的类型,我们则需要增加对应的伤害类型以及类型抗性
打开我们之前在C++创建标签的文件RPGGameplayTags.h,先增加伤害类型
FGameplayTag Damage; //伤害 标签FGameplayTag Damage_Fire; //火属性伤害 标签FGameplayTag Damage_Lightning; //雷属性伤害 标签FGameplayTag Damage_Arcane; //魔法伤害 标签FGameplayTag Damage_Physical; //物理伤害 标签
在cpp文件中,增加标签注册
GameplayTags.Damage = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Damage"),FString("伤害标签"));GameplayTags.Damage_Fire = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Damage.Fire"),FString("火属性伤害"));GameplayTags.Damage_Lightning = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Damage.Lightning"),FString("雷属性伤害"));GameplayTags.Damage_Arcane = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Damage.Arcane"),FString("魔法伤害"));GameplayTags.Damage_Physical = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Damage.Physical"),FString("物理伤害"));
然后增加抗性标签
//属性伤害抗性FGameplayTag Attributes_Resistance_Fire; //火属性伤害抵抗 标签FGameplayTag Attributes_Resistance_Lightning; //雷属性伤害抵抗 标签FGameplayTag Attributes_Resistance_Arcane; //魔法伤害抵抗 标签FGameplayTag Attributes_Resistance_Physical; //物理伤害抵抗 标签
并注册
/* 属性抗性标签 */GameplayTags.Attributes_Resistance_Fire = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Resistance.Fire"),FString("火属性抗性"));GameplayTags.Attributes_Resistance_Lightning = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Resistance.Lightning"),FString("雷属性抗性"));GameplayTags.Attributes_Resistance_Arcane = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Resistance.Arcane"),FString("魔法伤害抗性"));GameplayTags.Attributes_Resistance_Physical = UGameplayTagsManager::Get().AddNativeGameplayTag(FName("Resistance.Physical"),FString("物理伤害抗性"));
设置完成伤害类型和对应的抗性标签后,我们还需要将其对应起来,我们增加一个Map标签
TMap<FGameplayTag, FGameplayTag> DamageTypesToResistance; //属性伤害标签对应属性抵抗标签
并在注册完成后,将其一一对应起来
/* 将属性和抗性标签对应 */GameplayTags.DamageTypesToResistance.Add(GameplayTags.Damage_Fire, GameplayTags.Attributes_Resistance_Fire);GameplayTags.DamageTypesToResistance.Add(GameplayTags.Damage_Lightning, GameplayTags.Attributes_Resistance_Lightning);GameplayTags.DamageTypesToResistance.Add(GameplayTags.Damage_Arcane, GameplayTags.Attributes_Resistance_Arcane);GameplayTags.DamageTypesToResistance.Add(GameplayTags.Damage_Physical, GameplayTags.Attributes_Resistance_Physical);
这样,就完成了标签的添加。
增加抗性属性
标签添加完成,我们还需要在AttributeSet里面增加对应的抗性属性,用于记录当前角色抗性值,如果想完整的查看,请查看此文章 20. UE5 RPG创建次级属性并实现设置,下面我们快速实现抗性属性的添加。
/** 属性伤害抗性*/UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_FireResistance, Category="Resistance Attributes")FGameplayAttributeData FireResistance; // 火属性抗性ATTRIBUTE_ACCESSORS(URPGAttributeSet, FireResistance);UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_LightningResistance, Category="Resistance Attributes")FGameplayAttributeData LightningResistance; // 雷属性抗性ATTRIBUTE_ACCESSORS(URPGAttributeSet, LightningResistance);UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_ArcaneResistance, Category="Resistance Attributes")FGameplayAttributeData ArcaneResistance; // 魔法抗性ATTRIBUTE_ACCESSORS(URPGAttributeSet, ArcaneResistance);UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_PhysicalResistance, Category="Resistance Attributes")FGameplayAttributeData PhysicalResistance; // 物理抗性ATTRIBUTE_ACCESSORS(URPGAttributeSet, PhysicalResistance);
然后增加对应的复制函数
UFUNCTION()void OnRep_FireResistance(const FGameplayAttributeData& OldFireResistance) const;UFUNCTION()void OnRep_LightningResistance(const FGameplayAttributeData& OldLightningResistance) const;UFUNCTION()void OnRep_ArcaneResistance(const FGameplayAttributeData& OldArcaneResistance) const;UFUNCTION()void OnRep_PhysicalResistance(const FGameplayAttributeData& OldPhysicalResistance) const;
在cpp中实现复制函数
void URPGAttributeSet::OnRep_FireResistance(const FGameplayAttributeData& OldFireResistance) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, FireResistance, OldFireResistance);
}void URPGAttributeSet::OnRep_LightningResistance(const FGameplayAttributeData& OldLightningResistance) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, LightningResistance, OldLightningResistance);
}void URPGAttributeSet::OnRep_ArcaneResistance(const FGameplayAttributeData& OldArcaneResistance) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, ArcaneResistance, OldArcaneResistance);
}void URPGAttributeSet::OnRep_PhysicalResistance(const FGameplayAttributeData& OldPhysicalResistance) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, PhysicalResistance, OldPhysicalResistance);
}
在同步时,设置同步
void URPGAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{Super::GetLifetimeReplicatedProps(OutLifetimeProps);...//抗性属性DOREPLIFETIME_CONDITION_NOTIFY(URPGAttributeSet, FireResistance, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(URPGAttributeSet, LightningResistance, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(URPGAttributeSet, ArcaneResistance, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(URPGAttributeSet, PhysicalResistance, COND_None, REPNOTIFY_Always);...
}
在初始化时,将标签和属性对应
URPGAttributeSet::URPGAttributeSet()
{const FRPGGameplayTags& GameplayTags = FRPGGameplayTags::Get();//------------------------------------------------属性标签和属性关联------------------------------------------------.../** Resistance Attribute*/TagsToAttributes.Add(GameplayTags.Attributes_Resistance_Fire, GetFireResistanceAttribute);TagsToAttributes.Add(GameplayTags.Attributes_Resistance_Lightning, GetLightningResistanceAttribute);TagsToAttributes.Add(GameplayTags.Attributes_Resistance_Arcane, GetArcaneResistanceAttribute);TagsToAttributes.Add(GameplayTags.Attributes_Resistance_Physical, GetPhysicalResistanceAttribute);
}
这样就完成的属性标签的创建。
在UI上面显示抗性值
接下来,我们要在UI面板显示角色的对不同类型的伤害的抗性值。如果查看UI面板的具体实现,看我之前的文章:23. UE5 RPG制作属性面板(一)
首先,我们在设置角色次级属性的GE里面增加对应的计算

这里我设置的火属性抗性和雷属性抗性都是基于加的抗性点来实现

而魔法抗性和物理抗性则基于智力和护甲值来设置,这里我也是随便填写的数值用于测试,就不截全了。在实际项目中,这个计算通常需要策划的配合。

我们还需要在DA_AttributeInfo文件中增加对应在UI上显示的标签对应的名称和描述,它是被设置在BP_AttributeMenuController上面的,实现这个也是方便属性列表设置时,我们只需要在列表上面设置标签名称,函数会帮我们实现下面的工作。

然后就是打开UI用户空间,在属性列表增加四个子项,用于显示抗性数值。

通过我们之前的设置,现在只需要修改标签,其它的工作就不用做了

接着运行项目查看UI上面是否正确的显示了对应的属性

实现伤害类型的计算
首先我们要重新设置技能伤害,并设置类型,比如我们创建的火属性类型技能,伤害是火属性的,我们设置火属性伤害标签,并设置上对应的伤害

接下来,就需要去代码里将逻辑重新修改掉。
在生成发射物的技能类里,我们创建GE的地方,将属性的伤害通过SetByCaller方式设置给GE
我们可以遍历将在技能列表上设置的所有的属性类型和伤害设置过去。
//设置技能伤害 SetByCaller获取 通过Tag
const FRPGGameplayTags GameplayTags = FRPGGameplayTags::Get(); //获取标签单例
for(auto& Pair : DamageTypes)
{const float ScaledDamage = Pair.Value.GetValueAtLevel(GetAbilityLevel()); //根据等级获取技能伤害UAbilitySystemBlueprintLibrary::AssignTagSetByCallerMagnitude(SpecHandle, Pair.Key, ScaledDamage);
}
设置属性伤害就算完成了,接下来我们转到ExecCalc_Damage.cpp文件里,增加对目标的属性获取
首先在静态实例类里面增加对抗性属性设置
struct SDamageStatics
{...DECLARE_ATTRIBUTE_CAPTUREDEF(FireResistance);DECLARE_ATTRIBUTE_CAPTUREDEF(LightningResistance);DECLARE_ATTRIBUTE_CAPTUREDEF(ArcaneResistance);DECLARE_ATTRIBUTE_CAPTUREDEF(PhysicalResistance);SDamageStatics(){//参数:1.属性集 2.属性名 3.目标还是自身 4.是否设置快照(true为创建时获取,false为应用时获取)...DEFINE_ATTRIBUTE_CAPTUREDEF(URPGAttributeSet, FireResistance, Target, false);DEFINE_ATTRIBUTE_CAPTUREDEF(URPGAttributeSet, LightningResistance, Target, false);DEFINE_ATTRIBUTE_CAPTUREDEF(URPGAttributeSet, ArcaneResistance, Target, false);DEFINE_ATTRIBUTE_CAPTUREDEF(URPGAttributeSet, PhysicalResistance, Target, false);}
};
然后在构造时,将参数添加到捕获列表中
UExecCalc_Damage::UExecCalc_Damage()
{//添加监听...RelevantAttributesToCapture.Add(DamageStatics().FireResistanceDef);RelevantAttributesToCapture.Add(DamageStatics().LightningResistanceDef);RelevantAttributesToCapture.Add(DamageStatics().ArcaneResistanceDef);RelevantAttributesToCapture.Add(DamageStatics().PhysicalResistanceDef);
}
我本来想把Map写到静态实例类里,发现在代码的运行过程中,单例实例创建时,标签还没有设置成功,这就导致在单例实例里面无法获取到标签,所以,我转到了Execute_Implementation函数中,创建Map的原因是,我们这样就不需要在for循环中进行二次遍历了,只需要通过Map获取对应的Value即可。
//存储标签和属性快照对应的MapTMap<FGameplayTag, FGameplayEffectAttributeCaptureDefinition> TagsToCaptureDefs;//添加标签和属性快照对应的数据TagsToCaptureDefs.Add(GameplayTags.Attributes_Resistance_Fire, DamageStatics().FireResistanceDef);TagsToCaptureDefs.Add(GameplayTags.Attributes_Resistance_Lightning, DamageStatics().LightningResistanceDef);TagsToCaptureDefs.Add(GameplayTags.Attributes_Resistance_Arcane, DamageStatics().ArcaneResistanceDef);TagsToCaptureDefs.Add(GameplayTags.Attributes_Resistance_Physical, DamageStatics().PhysicalResistanceDef);
由于我们在函数内无法获取技能设置了几种伤害类型和伤害,所以,我们要把所有的类型都遍历到,所以,我们从标签单例中获取到伤害类型和抵抗类型的对照标签Map,并将其遍历
for(const TTuple<FGameplayTag, FGameplayTag>& Pair : GameplayTags.DamageTypesToResistance)
然后通过抗性类型的标签去获取快照引用
const FGameplayTag DamageType = Pair.Key;
const FGameplayTag ResistanceType = Pair.Value;
//检查对应的属性快照是否设置,防止报错
checkf(TagsToCaptureDefs.Contains(ResistanceType), TEXT("在ExecCalc_Damage中,无法获取到Tag[%s]对应的属性快照"), *ResistanceType.ToString());
//通过抗性标签获取到属性快照
const FGameplayEffectAttributeCaptureDefinition CaptureDef = TagsToCaptureDefs[ResistanceType];
获取到快照了,我们可以通过快照去获取目标的抗性值,这里限制到0-100是防止预算出错,超一百了,会出现攻击负值的情况,应用到角色那就是加血了。
//获取抗性值
float Resistance = 0.f;
ExecutionParams.AttemptCalculateCapturedAttributeMagnitude(CaptureDef, EvaluationParameters, Resistance);
Resistance = FMath::Clamp(Resistance, 0.f, 100.f); //将抗住限制在0到100
接着通过SetByCaller获取到伤害类型的伤害,如果没有设置,获取的值将为0
//通过Tag获取对应伤害类型的值,如果没设置SetByCaller将获取0float DamageTypeValue = Spec.GetSetByCallerMagnitude(DamageType);
最后,计算出能够造成的伤害,并将伤害叠加做后续计算
//通过抗性计算出能够对角色造成的伤害值DamageTypeValue *= (100.f - Resistance) / 100.f;//将每种属性伤害值合并进行后续计算Damage += DamageTypeValue;
计算完成以后,我们可以进行debug测试,这是火球术,火属性伤害,本来能造成的伤害为5,受到抵抗后,伤害减少了百分之11.5,最总火球术造成的伤害为4.425

相关文章:
54. UE5 RPG 增加伤害类型
在正常的RPG游戏中,都存在一个类别就是属性伤害,比如,在一个游戏里面有一个火属性的技能,它造成的伤害就是火属性类型的,并且它还有可能有附加伤害,比如给予目标一个灼烧效果,每秒造成多少的火属…...
llama3 微调教程之 llama factory 的 安装部署与模型微调过程,模型量化和gguf转换。
本文记录了从环境部署到微调模型、效果测试的全过程,以及遇到几个常见问题的解决办法,亲测可用(The installed version of bitsandbytes was compiled without GPU support. NotImplementedError: Architecture ‘LlamaForCausalLM’ not sup…...
C++三剑客之std::any(二) : 源码剖析
目录 1.引言 2.std::any的存储分析 3._Any_big_RTTI与_Any_small_RTTI 4.std::any的构造函数 4.1.从std::any构造 4.2.可变参数模板构造函数 4.3.赋值构造与emplace函数 5.reset函数 6._Cast函数 7.make_any模版函数 8.std::any_cast函数 9.总结 1.引言 C三剑客之s…...
【C语言】8.C语言操作符详解(2)
文章目录 6.单⽬操作符7.逗号表达式8.下标访问[]、函数调⽤()8.1 [ ] 下标引⽤操作符8.2 函数调⽤操作符 9.结构成员访问操作符9.1 结构体9.1.1 结构的声明9.1.2 结构体变量的定义和初始化 9.2 结构成员访问操作符9.2.1 结构体成员的直接访问9.2.2 结构体成员的间接访问 6.单⽬…...
vivado 物理约束KEEP_HIERARCHY
KEEP_HIERARCHY Applied To Cells Constraint Values • TRUE • FALSE • YES • NO UCF Example INST u1 KEEP_HIERARCHY TRUE; XDC Example set_property DONT_TOUCH true [get_cells u1] IOB Applied To Cells Constraint Values IOB_XnYn UCF Examp…...
Linux 三十六章
🐶博主主页:ᰔᩚ. 一怀明月ꦿ ❤️🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C,linux 🔥座右铭:“不要…...
ntsd用法+安装包
ntsd是一个强大的进程终止软件,除了少数系统进程之外一律杀掉 用法 1.ntsd -c q -p 进程的pid 2.ntsd -c q -pn 进程名 记得解压到System32里面 当然,资源管理器的进程是可以杀的所以也可以让电脑黑屏 同样可以让电脑黑屏的还有taskkill /f /im 进程…...
Nacos 微服务管理
Nacos 本教程将为您提供Nacos的基本介绍,并带您完成Nacos的安装、服务注册与发现、配置管理等功能。在这个过程中,您将学到如何使用Nacos进行微服务管理。下方是官方文档: Nacos官方文档 1. Nacos 简介 Nacos(Naming and Confi…...
Kubernetes集群上的Etcd备份和恢复
在本教程中,您将学习如何在Kubernetes集群上使用etcd快照进行etcd备份和恢复。 在Kubernetes架构中,etcd是集群的重要组成部分。所有集群对象及其状态都存储在etcd中。为了更好地理解Kubernetes,有几点关于etcd的信息是您需要了解的。 它是…...
创建型模式 (Python版)
单例模式 懒汉式 class SingleTon:# 类属性_obj None # 用来存储对象# 创造对象def __new__(cls, *args, **kwargs):# 如果对象不存在,就创造一个对象if cls._obj is None:cls._obj super().__new__(cls, *args, *kwargs)# 返回对象return cls._objif __name__…...
【收录 Hello 算法】9.4 小结
目录 9.4 小结 1. 重点回顾 2. Q & A 9.4 小结 1. 重点回顾 图由顶点和边组成,可以表示为一组顶点和一组边构成的集合。相较于线性关系(链表)和分治关系(树),网络关系(图&am…...
MYSQL数据库基础语法
目录 友情提醒第一章:数据库简述1)数据库简述2)常见的数据库软件3)MySQL数据库安装和连接4)SQL语句分类①DDL(Data Definition)②DML(Data Manipulation)③DQL࿰…...
R实验 参数检验(二)
实验目的:掌握正态分布和二项分布中,功效与样本容量之间的关系;学会利用R软件完成一个正态总体方差和两个正态总体方差比的区间估计和检验。 实验内容: (习题5.28)一种药物可治疗眼内高压,目的…...
【Linux】进程信号及相关函数/系统调用的简单认识与使用
文章目录 前言一、相关函数/系统调用1. signal2. kill3. abort (库函数)4. raise (库函数)5. alarm 前言 现实生活中, 存在着诸多信号, 比如红绿灯, 上下课铃声…我们在接收到信号时, 就会做出相应的动作. 对于进程也是如此的, 进程也会收到来自 OS 发出的信号, 根据信号的不同…...
Spring (14)什么是Spring Boot
Spring Boot是一个开源的Java基础框架,旨在简化Spring应用的创建和开发过程。Spring Boot通过提供一套默认配置(convention over configuration),自动配置和启动器(starters)来减少开发者的开发工作量和配置…...
区间预测 | Matlab实现CNN-KDE卷积神经网络结合核密度估计多置信区间多变量回归区间预测
区间预测 | Matlab实现CNN-KDE卷积神经网络结合核密度估计多置信区间多变量回归区间预测 目录 区间预测 | Matlab实现CNN-KDE卷积神经网络结合核密度估计多置信区间多变量回归区间预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现CNN-KDE卷积神经网络结合…...
Java集合框架全景解读:从源码到实践精通指南
1. Java集合框架简介 在Java中,集合框架是用于存储和处理数据集合的一组类和接口。它提供了一系列的数据结构,比如列表(List)、集(Set)和映射(Map)。这些数据结构为开发者处理数据提…...
Python | Leetcode Python题解之第107题二叉树的层序遍历II
题目: 题解: class Solution:def levelOrderBottom(self, root: TreeNode) -> List[List[int]]:levelOrder list()if not root:return levelOrderq collections.deque([root])while q:level list()size len(q)for _ in range(size):node q.popl…...
H4vdo 台湾APT-27视频投放工具
地址:https://github.com/MartinxMax/H4vdo 视频 关于 H4vdo RTMP lock 屏播放视频工具,可以向目标发送有效载荷,播放目标的屏幕内容。目标无法曹作计算机 使用方法 安装依赖 根据你的操作系统选择一个安装程序 RTMP 服务端 ./rtsp-simple-server.…...
数据结构(树)
1.树的概念和结构 树,顾名思义,它看起来像一棵树,是由n个结点组成的非线性的数据结构。 下面就是一颗树: 树的一些基本概念: 结点的度:一个结点含有的子树的个数称为该结点的度; 如上图&#…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...
STM32标准库-ADC数模转换器
文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”:输入模块(GPIO、温度、V_REFINT)1.4.2 信号 “调度站”:多路开关1.4.3 信号 “加工厂”:ADC 转换器(规则组 注入…...
