82. UE5 RPG 实现角色升级系统(下)

书接上回,在上一篇博客里,我们实现了角色升级的基础的功能。给敌人增加的经验奖励配置,并且在敌人死亡时,能够将经验通过事件传递给击杀者,玩家定义了被动技能,在被动技能中接收传递的事件,通过SetByCaller的GE应用给自身。并在AttributeSet中打印出获得的经验。
我们还修改了PlayerState,在内部增加了对经验和等级添改查的,并创建对应的委托,在UI的Controller里面,实现了对委托的监听,并实现回调函数,通过经验获取等级和升级进度广播给UI表现出来。

创建玩家接口类

有了之前制作的内容,我们接下来,将实现玩家在AS里获取到经验后,设置的PlayerState上,这里防止耦合度太高,我们选择创建一个新的接口实现此功能。
新添加一个接口类
在这里插入图片描述
作为玩家专用的命名为PlayerInterface ,除了它我们还有CombateInterface(战斗接口)EnemyInterface(敌人接口)
在这里插入图片描述
在接口类里,我们增加一个增加经验的函数

class RPG_API IPlayerInterface
{GENERATED_BODY()// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:UFUNCTION(BlueprintNativeEvent)void AddToXP(int32 InXP); //增加经验
};

在玩家角色类继承此接口

class RPG_API ARPGHero : public ARPGCharacter, public IPlayerInterface
{GENERATED_BODY()

并覆写此函数

	/* IPlayerInterface战斗接口 */virtual void AddToXP_Implementation(int32 InXP) override;/* IPlayerInterface战斗接口 结束 */

在实现这里,获取到PlayerState,并调用PlayerState身上的增加经验的函数

void ARPGHero::AddToXP_Implementation(int32 InXP)
{ARPGPlayerState* PlayerStateBase = GetPlayerState<ARPGPlayerState>();check(PlayerStateBase); //检测是否有效,无限会暂停游PlayerStateBase->AddToXP(InXP);
}

最后在AS里,我们通过调用此函数实现经验增长

	if(Data.EvaluatedData.Attribute == GetIncomingXPAttribute()){const float LocalIncomingXP = GetIncomingXP();SetIncomingXP(0);// UE_LOG(LogRPG, Log, TEXT("获取传入经验值:%f"), LocalIncomingXP);//将经验应用给自身if(Props.SourceCharacter->Implements<UPlayerInterface>()){IPlayerInterface::Execute_AddToXP(Props.SourceCharacter, LocalIncomingXP);}}

在UI上实现对经验变动监听

现在,玩家角色可以获得经验,并通过接口设置给PlayerState,然后广播给UI的控制器了。我们要先将之前创建的升级数据设置给PlayerState
在这里插入图片描述
在WBP_Overlay里面,给经验条设置控制器
在这里插入图片描述
在经验条的事件中,设置控制器回调中,绑定对经验变动的监听,在变动时,获取经验条的百分比
在这里插入图片描述
接下来可以测试了,发现上一篇文章里面,在最后类型转换时,需要提前转换将一个数值转换为浮点数类型 ,浮点数/整型 结果就可以是浮点型,要不然,整型除以整型结果还是整型,获取的结果为0
在这里插入图片描述
接着,你就会发现经验条随着怪物死亡,增长了一丝
在这里插入图片描述
然后测试杀死两只,给的经验是否一致
在这里插入图片描述

重构战斗接口中的获取等级函数

我们想将之前书写的获取等级的函数修改成可以在蓝图定义的,达到结构统一,所以,需要额外修改一些内容

	UFUNCTION(BlueprintNativeEvent)int32 GetPlayerLevel(); //获取玩家等级

修改后编译会发现一些报错
在这里插入图片描述
按照之前方式,将其名称后续加上_Implementation即可

	/* ICombatInterface战斗接口 */virtual int32 GetPlayerLevel_Implementation() override;/* ICombatInterface战斗接口 结束 */

接下来编译,会发现还有一些额外报错,这是因为调用的地方没有修改
在这里插入图片描述
我们可以通过双击shift键,打开搜索,找到调用的地方依次修改。
在这里插入图片描述
找到需要修改的地方,将代码修改成以下类型。注意:Implements后面的类型是以U开头的接口,它是UE增加的,而调用的时候是I开头是c++内置的接口调用方式。

	//从战斗接口获取到角色的等级int32 CharacterLevel = 1;if(ASC->GetAvatarActor()->Implements<UCombatInterface>()){CharacterLevel = ICombatInterface::Execute_GetPlayerLevel(ASC->GetAvatarActor());}

增加角色接口函数

为了实现接下来角色升级的功能,我们扩展角色接口的函数

class RPG_API IPlayerInterface
{GENERATED_BODY()// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:UFUNCTION(BlueprintNativeEvent)int32 FindLevelForXP(int32 InXP) const; //根据经验获取等级UFUNCTION(BlueprintNativeEvent)int32 GetXP() const; //获取当前经验值UFUNCTION(BlueprintNativeEvent)int32 GetAttributePointsReward(int32 Level) const; //获取属性点奖励UFUNCTION(BlueprintNativeEvent)int32 GetSpellPointsReward(int32 Level) const; //获取技能点奖励UFUNCTION(BlueprintNativeEvent)void AddToXP(int32 InXP); //增加经验UFUNCTION(BlueprintNativeEvent)void AddToPlayerLevel(int32 InPlayerLevel); //增加等级UFUNCTION(BlueprintNativeEvent)void AddToAttributePoints(int32 InAttributePoints); //增加属性点UFUNCTION(BlueprintNativeEvent)void AddToSpellPoints(int32 InSpellPoints); //增加技能点UFUNCTION(BlueprintNativeEvent)void LevelUp(); //升级
};

接下来,我们在继承接口的玩家角色类里面覆写函数

	/* IPlayerInterface战斗接口 */virtual void AddToXP_Implementation(int32 InXP) override;virtual void LevelUp_Implementation() override;virtual int32 GetXP_Implementation() const override;virtual int32 FindLevelForXP_Implementation(int32 InXP) const override;virtual int32 GetAttributePointsReward_Implementation(int32 Level) const override;virtual int32 GetSpellPointsReward_Implementation(int32 Level) const override;virtual void AddToPlayerLevel_Implementation(int32 InPlayerLevel) override;virtual void AddToAttributePoints_Implementation(int32 InAttributePoints) override;virtual void AddToSpellPoints_Implementation(int32 InSpellPoints) override;/* IPlayerInterface战斗接口 结束 */

除了已经实现的添加经验的函数,我们将其它函数依次实现。

首先是升级函数,这个函数主要用于提供角色升级时,播放一下升级表现效果,因为当前类是在服务器运行的,我们要实现一个在每个客户端都可以运行的效果,就需要增加一个可以在多端运行的函数,这个在稍微讲解。

接下来是获取当前角色经验值

int32 ARPGHero::GetXP_Implementation() const
{const ARPGPlayerState* PlayerStateBase = GetPlayerState<ARPGPlayerState>();check(PlayerStateBase); //检测是否有效,无限会暂停游戏return PlayerStateBase->GetXP();
}

通过经验值获取当前等级

int32 ARPGHero::FindLevelForXP_Implementation(const int32 InXP) const
{const ARPGPlayerState* PlayerStateBase = GetPlayerState<ARPGPlayerState>();check(PlayerStateBase); //检测是否有效,无限会暂停游戏return PlayerStateBase->LevelUpInfo->FindLevelForXP(InXP);
}

获取当前等级奖级的属性点

int32 ARPGHero::GetAttributePointsReward_Implementation(const int32 Level) const
{const ARPGPlayerState* PlayerStateBase = GetPlayerState<ARPGPlayerState>();check(PlayerStateBase); //检测是否有效,无限会暂停游戏return PlayerStateBase->LevelUpInfo->LevelUpInformation[Level].AttributePointAward;
}

获取当前等级奖励的技能点

int32 ARPGHero::GetSpellPointsReward_Implementation(const int32 Level) const
{const ARPGPlayerState* PlayerStateBase = GetPlayerState<ARPGPlayerState>();check(PlayerStateBase); //检测是否有效,无限会暂停游戏return PlayerStateBase->LevelUpInfo->LevelUpInformation[Level].SpellPointAward;
}

设置当前角色升级,主要是修改角色的数值

void ARPGHero::AddToPlayerLevel_Implementation(int32 InPlayerLevel)
{ARPGPlayerState* PlayerStateBase = GetPlayerState<ARPGPlayerState>();check(PlayerStateBase); //检测是否有效,无限会暂停游戏PlayerStateBase->AddToLevel(InPlayerLevel);
}

还有在后续章节中添加的属性修改功能函数,为角色增加属性点和技能点

void ARPGHero::AddToAttributePoints_Implementation(int32 InAttributePoints)
{//TODO:实现增加属性点
}void ARPGHero::AddToSpellPoints_Implementation(int32 InSpellPoints)
{//TODO:实现增加技能点
}

实现等级升级

接下来,我们在AS里面获得经验后,处理升级相关逻辑。
首先判断是否升级,逻辑是当前经验+获得的经验是否能够升级,获取到增加经验后的等级和原来的等级是否一致,如果增加了,意味着角色等级得到了提升。

//获取获得经验后的新等级
const int32 CurrentLevel = ICombatInterface::Execute_GetPlayerLevel(Props.SourceCharacter);
const int32 NewLevel = IPlayerInterface::Execute_FindLevelForXP(Props.SourceCharacter, CurrentXP + LocalIncomingXP);
const int32 NumLevelUps = NewLevel - CurrentLevel; //查看等级是否有变化
if(NumLevelUps > 0)
{...
}

在升级逻辑里面,我们首先获取当前等级提供的属性点和技能点的奖励

//获取升级提供的技能点和属性点
int32 AttributePointsReward = IPlayerInterface::Execute_GetAttributePointsReward(Props.SourceCharacter, CurrentLevel);
int32 SpellPointsReward = IPlayerInterface::Execute_GetSpellPointsReward(Props.SourceCharacter, CurrentLevel);

然后提升角色等级,并应用奖励

//提升等级,增加角色技能点和属性点
IPlayerInterface::Execute_AddToPlayerLevel(Props.SourceCharacter, NumLevelUps);
IPlayerInterface::Execute_AddToAttributePoints(Props.SourceCharacter, AttributePointsReward);
IPlayerInterface::Execute_AddToSpellPoints(Props.SourceCharacter, SpellPointsReward);

调用升级表现函数

IPlayerInterface::Execute_LevelUp(Props.SourceCharacter); //升级

升级时,将血量和蓝量填满

//将血量和蓝量填充满
SetHealth(GetMaxHealth());
SetMana(GetMana());

下面列出来完整代码

	if(Data.EvaluatedData.Attribute == GetIncomingXPAttribute()){const float LocalIncomingXP = GetIncomingXP();SetIncomingXP(0);// UE_LOG(LogRPG, Log, TEXT("获取传入经验值:%f"), LocalIncomingXP);if(Props.SourceCharacter->Implements<UPlayerInterface>() && Props.SourceCharacter->Implements<UCombatInterface>()){//获取角色当前等级和经验const int32 CurrentLevel = ICombatInterface::Execute_GetPlayerLevel(Props.SourceCharacter);const int32 CurrentXP = IPlayerInterface::Execute_GetXP(Props.SourceCharacter);//获取获得经验后的新等级const int32 NewLevel = IPlayerInterface::Execute_FindLevelForXP(Props.SourceCharacter, CurrentXP + LocalIncomingXP);const int32 NumLevelUps = NewLevel - CurrentLevel; //查看等级是否有变化if(NumLevelUps > 0){//获取升级提供的技能点和属性点int32 AttributePointsReward = IPlayerInterface::Execute_GetAttributePointsReward(Props.SourceCharacter, CurrentLevel);int32 SpellPointsReward = IPlayerInterface::Execute_GetSpellPointsReward(Props.SourceCharacter, CurrentLevel);//提升等级,增加角色技能点和属性点IPlayerInterface::Execute_AddToPlayerLevel(Props.SourceCharacter, NumLevelUps);IPlayerInterface::Execute_AddToAttributePoints(Props.SourceCharacter, AttributePointsReward);IPlayerInterface::Execute_AddToSpellPoints(Props.SourceCharacter, SpellPointsReward);IPlayerInterface::Execute_LevelUp(Props.SourceCharacter); //升级//将血量和蓝量填充满SetHealth(GetMaxHealth());SetMana(GetMana());}//将经验应用给自身,通过事件传递,在玩家角色被动技能GA_ListenForEvents里接收IPlayerInterface::Execute_AddToXP(Props.SourceCharacter, LocalIncomingXP);}}

在ui上面显示等级

我们现在角色有了等级,需要在UI上面表现出来。
我们首先处理回调,之前实现了经验的表现,我们在PlayerState类里面设置和升级时,会调用委托广播
在这里插入图片描述
那么,我们在UI Controller里面添加一个委托,用于广播给UI监听,等级为整型参数

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPlayerStateChangedSignature, int32, NewValue); //当玩家状态该表回调类型

接着创建对应类型的变量

	UPROPERTY(BlueprintAssignable, Category="GAS|Level")FOnPlayerStateChangedSignature OnPlayerLevelChangeDelegate; //等级变动回调

绑定一个匿名函数,用于监听PlayerState的等级回调

	//绑定等级相关回调RPGPlayerState->OnLevelChangedDelegate.AddLambda([this](int32 NewLevel){OnPlayerLevelChangeDelegate.Broadcast(NewLevel);});

接下来,我们基于WBP_SpellGlobe复制一份,创建一个用于显示等级的ui
在这里插入图片描述
将使用图标设置的部分删除,我们不需要在等级显示UI里面设置图标
在这里插入图片描述
在设置控制器回调里面监听等级委托,回调触发修改等级显示文字
在这里插入图片描述
为了方便设置,我们可以修改对应怪物提供的经验值
在这里插入图片描述
将其拖入到WBP_Overlay上面,并设置对应控制器
在这里插入图片描述
接下来,我们就可以运行查看效果
在这里插入图片描述

创建角色图标

接下来,我们想在左上角显示对应角色的图标,这里使用WBP_GlobeProgressbar作为模版复制一份
在这里插入图片描述
命名为WBP_PictureFrame
在这里插入图片描述
移动到对应的文件夹中
在这里插入图片描述
删除一些无用的函数
在这里插入图片描述
增加一个用于显示头像的节点
在这里插入图片描述
设置对应头像
在这里插入图片描述
在WBP_Overlay里面应用,并设置好位置
在这里插入图片描述

设置升级效果

接下来,我们将上面略过的等级升级效果函数实现一下,我们需要增加一个粒子特效在升级时播放特效。由于特效是平面播放,它会跟随角色的角度,有时候看到是一个竖条的,所以我们还需要将相机在代码里创建,方便后续获取相机的旋转。
我们首先在代码里创建相机和弹簧臂

	UPROPERTY(VisibleAnywhere)TObjectPtr<UCameraComponent> TopDownCameraComponent; //相机组件UPROPERTY(VisibleAnywhere)TObjectPtr<USpringArmComponent> CameraBoom; //弹簧臂组件

在初始化时创建它们

	//设置相机CameraBoom = CreateDefaultSubobject<USpringArmComponent>("CameraBoom");CameraBoom->SetupAttachment(GetRootComponent());CameraBoom->SetUsingAbsoluteRotation(true);CameraBoom->bDoCollisionTest = false;TopDownCameraComponent = CreateDefaultSubobject<UCameraComponent>("TopDownCameraComponent");TopDownCameraComponent->SetupAttachment(CameraBoom, USpringArmComponent::SocketName);TopDownCameraComponent->bUsePawnControlRotation = false;

然后创建一个NiagaraComponent,用于设置使用的粒子特效,它需要在蓝图中设置使用的粒子资源

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)TObjectPtr<UNiagaraComponent> LevelUpNiagaraComponent; //升级特效组件

在构造函数中初始化,并将自动播放关闭,我们在角色升级的时候让其播放

	//设置升级特效组件LevelUpNiagaraComponent = CreateDefaultSubobject<UNiagaraComponent>("LevelUpNiagaraComponent");LevelUpNiagaraComponent->SetupAttachment(GetRootComponent()); //设置附加组件LevelUpNiagaraComponent->bAutoActivate = false; //设置不自动激活

我们还需要创建一个支持多客户端调用的函数,它将在每个客户端都实现调用,这样,在每个客户端都能看到同样的效果

	UFUNCTION(NetMulticast, Reliable)void MulticastLevelUpParticles() const; //在多人游戏,每个客户端上播放升级特效

在实现这里,我们将通过相机和粒子位置的朝向,注意,这个朝向是世界坐标系的,然后通过朝向获取旋转,设置给粒子

void ARPGHero::MulticastLevelUpParticles_Implementation() const
{if(IsValid(LevelUpNiagaraComponent)){const FVector CameraLocation = TopDownCameraComponent->GetComponentLocation();const FVector NiagaraSystemLocation = LevelUpNiagaraComponent->GetComponentLocation();const FRotator TopCameraRotation = (CameraLocation - NiagaraSystemLocation).Rotation(); //获取相机位置和离职特效的朝向LevelUpNiagaraComponent->SetWorldRotation(TopCameraRotation); //设置粒子的转向LevelUpNiagaraComponent->Activate(true); //激活特效}
}

并在AS调用函数时,调用此函数,因为AS只在服务器运行,再调用此函数,实现了每个客户端的运行

void ARPGHero::LevelUp_Implementation()
{MulticastLevelUpParticles(); //调用播放升级特效
}

接着编译打开UE,设置粒子特效
在这里插入图片描述
并将之前在蓝图中创建的相机和弹簧臂删除掉,将之前的碰撞盒移动到代码创建的弹簧臂上面
在这里插入图片描述
删除蓝图创建的相机和弹簧臂
在这里插入图片描述
运行查看效果。
在这里插入图片描述

创建升级消息提示

接下来,我们优化效果,在升级时提供消息提示UI,并播放音效。
在这里插入图片描述
父类选择我们自定义的RPGUserWidget
在这里插入图片描述

命名为WBP_LevelUpMessage 为升级提示
在这里插入图片描述
我们在里面添加一个覆层,作为全屏显示,并在覆层下面添加一个包裹框,文字超出范围后会自动换行
在这里插入图片描述
为了防止文字在最顶部显示,我们在上面添加一个间隔区,用来填充空间,宽度设置的尽量大一些,防止文字在间隔区后面显示。
在这里插入图片描述
增加一个文本,设置好样式,让其可以占用一整行
在这里插入图片描述
下面添加一个水平框,框内设置两个文本,显示等级和实际等级数字
在这里插入图片描述
水平框设置对其和填充空间以及强制换新行,文本向左向右对其,这样,就可以居中显示
在这里插入图片描述
实际效果如下
在这里插入图片描述
我们也可以用上下设置垂直框,这样更方便设置
在这里插入图片描述
接着,我们要在WBP_Overlay里面在设置了控制器后,监听等级的变动,在监听到等级变化后,将现存的等级提示删除,然后接着创建一个新的控件,并将目标等级设置,并添加到视口。这样可以防止连续升级时,多层覆盖的问题。
在这里插入图片描述
运行查看效果。
在这里插入图片描述
接下来,我们优化一下,制作一个动画
在这里插入图片描述
在事件开始后,播放音效和动画,并延迟三秒将UI销毁
在这里插入图片描述
接下来查看最终效果
在这里插入图片描述

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

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

相关文章

iOS 开发包管理之CocoaPods

CocoaPods&#xff08;Objective-C 时期&#xff0c;支持Objective-C和swift&#xff09;&#xff0c;CocoaPods下载第三方库源代码后会将其编译成静态库.a 文件 或动态库框架.framework 文件 的形式&#xff0c;并将它们添加到项目中&#xff0c;建立依赖关系&#xff0c;这种…

Redis实现用户会话

1.分布式会话 (1)什么是会话 会话Session代表的是客户端与服务器的一次交互过程&#xff0c;这个过程可以是连续也可以是时断时续的。曾经的Servlet时代&#xff08;jsp&#xff09;&#xff0c;一旦用户与服务端交互&#xff0c;服务器tomcat就会为用户创建一个session&#…

开源PDF解析工具marker 和 MinerU的解析效果对比

RAG中的文档解析需求&#xff1a;需要的是文档的完整段落&#xff0c;标题&#xff0c;图片&#xff0c;表格。我们希望删除的是md格式&#xff0c;或者josn格式。 MinerU 和 maker恰好。都是能够满足此需求的开源工具。这篇文章分享一下对两者的对比。整理出来目前还存在的问题…

RPG素材Unity7月20闪促限时4折游戏开发资产兽人角色模型动画休闲放置模板物理交互流体水下焦散VR界面UI2D模板场景20240720

今天这个是RPG素材比较多&#xff0c;还有一些休闲放置模板、FPS场景素材、角色模型、动画、特效。 详细内容展示&#xff1a;www.bilibili.com/video/BV1Tx4y1s7vm 闪促限时4折&#xff1a;https://prf.hn/l/0eEOG1P 半价促销&#xff1a;https://prf.hn/l/RlDmDeQ 7月闪促…

谷粒商城实战-Vue学习过程中踩坑记录

一&#xff0c;自闭合的<script>标签 第一次使用Vue&#xff0c;按照步骤引入vue.js&#xff0c;创建div&#xff0c;创建Vue对象&#xff0c;但是未达预期效果。 插值表达式{{name}}没被替换为data对象中的属性值。 F12看了下网页源代码&#xff0c;发现创建Vue对象的…

OpenAI突发新模型GPT-4o mini,GPT-3.5退役!

OpenAI突发新模型&#xff0c;全面取代老去的GPT-3.5——GPT-4o mini&#xff01; 免费用户已可使用GPT-4o mini模型。 GPT-4o mini&#xff0c;能力接近原版GPT-4&#xff0c;价格却要便宜一个数量级&#xff1a; GPT-4o mini:每百万输入tokens&#xff0c;15美分&#xff0…

【Node.js基础03】利用http模块创建Web服务

一&#xff1a;使用步骤 1 加载http模块&#xff0c;并创建Web服务程序 2 利用Web服务程序监听request事件&#xff0c;设置响应头和响应体 3 配置端口号并启动Web服务 4 浏览器请求设置的端口号&#xff0c;进行Web服务程序测试 二&#xff1a;简单应用 const http requir…

基于多线程延迟排序的睡眠排序算法的创新与改进

基于多线程延迟排序的睡眠排序算法的创新与改进 摘要 本文在传统睡眠排序算法的基础上&#xff0c;提出了一种改进方案&#xff0c;旨在优化处理负数和大规模数据集的性能。通过引入线程池管理和数据分段排序技术&#xff0c;改进后的算法在处理大数据集和包含负数的数据集时…

计算机网络入门 -- TCP详解

计算机网络入门 – TCP详解 1.TCP协议 1.1 报文格式 1.32位序号&#xff1a;该条TCP数据携带的起始序号。 2.32位确认序号&#xff1a;期望对方发送数据从那个序号开始发送。 3.4位首部长度&#xff1a;最大为0xF(15)&#xff0c;指的是TCP头部长度。 首部长度 4 位首部长…

谷粒商城实战笔记-37-前端基础-Vue-基本语法插件安装

文章目录 一&#xff0c;v-model1&#xff0c;双向绑定2&#xff0c;vue的双向绑定2.1 html元素上使用指令v-model2.2 model中声明对应属性2.3&#xff0c;验证view绑定modelmodel绑定view 完整代码 二&#xff0c;v-on1&#xff0c;指令简介2&#xff0c;在button按钮中添加v-…

rimraf快速删除node_modules方法

项目中&#xff0c;有时候会遇到下载依赖报错&#xff0c;然后想要删除node_modules再重新下载&#xff0c;但是有时候直接用yarn 或者npm install仍热不行&#xff0c;我们可以尽量用yran&#xff0c;因为npm 可能会自动下一些给一些包升级了&#xff0c;此时因为前面已经下过…

JVM:GraalVM

文章目录 一、介绍1、什么是GraalVM&#xff1a;2、GraalVM版本 二、两种使用模式 一、介绍 1、什么是GraalVM&#xff1a; GraalVM是Oracle官方推出的一款高性能JDK&#xff0c;使用它享受比OpenJDK或者OracleJDK更好的性能。GraalVM的官网地址&#xff1a;https://www.graa…

泛型新理解

1.创建三个类&#xff0c;并写好对应关系 package com.jmj.gulimall.study;public class People { }package com.jmj.gulimall.study;public class Student extends People{ }package com.jmj.gulimall.study;public class Teacher extends People{ }2.解释一下这三个方法 pub…

数据结构(稀疏数组)

简介 稀疏数组是一种数据结构&#xff0c;用于有效地存储和处理那些大多数元素都是零或者重复值的数组。在稀疏数组中&#xff0c;只有非零或非重复的元素会被存储&#xff0c;从而节省内存空间。 案例引入 假如想把下面这张表存入文件&#xff0c;我们会怎么做&#xff1f;…

【LeetCode】翻转二叉树

目录 一、题目二、解法完整代码 一、题目 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1] 示例 2&#xff1a; 输入&#xff1a;root…

php-fpm如何配置max_children参数

前言 略 php-fpm 资源耗尽 php-fpm 的子进程耗尽的时&#xff1a; 会导致 502 出现nginx 出现错误日志 2024/07/18 20:19:10 [crit] 36390#0: *1402471 connect() to unix:/tmp/php-cgi-81.sock failed (2: No such file or directory) while connecting to upstream, cli…

Spring Authorization Server实战

Spring Authorization Server实战 Spring Authorizatin Server Spring Authorizatin Server是一个框架&#xff0c;它提供了OAuth2.1和OpenID Connect 1.0规范以及其它相关规范的实现&#xff0c;它是基于Spring Security构建的 OAuth2.0协议介绍 OAuth是一个开放标准的授权…

使用docker swarm搭建ruoyi集群环境

整体目标 项目背景 领导给到了我一个客户&#xff0c;客户商业模式为成本制作&#xff0c;成本核算。其中涉及到大量涉密数据&#xff0c;且与我们现有产品几乎没有兼容点&#xff08;我们是一套低代码的框架&#xff0c;客户有很多业务二开&#xff09; 测试环境给到了我6台…

大模型学习笔记 - LLM模型架构

LLM 模型架构 LLM 模型架构 1. LLM 核心模型 Transformer2. 详细配置 2.1 归一化方法2.2 归一化模块位置2.3 激活函数2.4 位置编码 2.4.1 绝对位置编码2.4.2 相对位置编码2.4.3 旋转位置编码 RoPE2.4.4 ALiBi位置编码 2.5 注意力机制 2.5.1 完整自注意力机制2.5.2 稀疏注意力机…

ChatGPT实战100例 - (20) 如何玩转影刀RPA

文章目录 ChatGPT实战100例 - (20) 如何玩转影刀RPA背景需求需求分析与流程设计一、需求收集二、流程梳理三、可行性分析流程设计(详细步骤)具体步骤的影刀RPA实现流程图总结AIGC在影刀RPA中的使用总结其他RPA步骤中可能用到AIGC的地方展望总结ChatGPT实战100例 - (20) 如何玩…