96. UE5 GAS RPG 实现闪电链技能(一)

news2024/12/23 2:36:15

闪电链有一个施法的过程,就是在按键按下的过程,会在按下的过程一直持续造成伤害,一直等到条件不满足(技能键位抬起,蓝量不足,被眩晕)时,将结束技能,并退出技能状态。
所以,首先我们将实现技能的持续释放状态。

增加技能持续施法动画

首先,我们在角色蓝图里增加一个变量,用来记录当前是否处于持续施法状态
在这里插入图片描述
在动画蓝图动画更新事件回调里获取此变量,并将此存储在动画蓝图中,以备后用
在这里插入图片描述
我们接下来,修改状态机,将持续施法动画加入,切换通过变量进行判断切换。
在这里插入图片描述
接下来,我们在战斗接口中增加一个函数,用于在蓝图中继承并修改。
BlueprintImplementableEvent 这个函数应该在蓝图中实现,而不是在 C++ 中实现。
BlueprintNativeEvent 允许你在 C++ 中提供一个默认实现,同时也允许在蓝图中覆盖这个实现。
CombatInterface.h

	UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
	void SetInShockLoop(bool bInLoop);

在角色蓝图里,我们实现此函数,通过传入的值设置变量
在这里插入图片描述
接下来,我们创建一个新的技能类,基于我们的自定义的技能基类,不知道的小伙伴可以查看之前的文章,或者在文章底部加群了解。
设置技能的输入标签。
在这里插入图片描述
为了方便测试,我们将技能直接添加到初始中,不需要激活即可拥有此技能。然后我们运行就可以右键释放此技能。
在这里插入图片描述
然后,我们在技能蓝图里添加一些测试逻辑,用于测试,此逻辑监听了对应激活技能按键的鼠标抬起和鼠标按下。在鼠标按下时,我们将变量设置为true,在鼠标抬起时,我们将变量设置为false。函数将会修改玩家角色身上的变量,动画蓝图跟着更新。
Test Already Pressed 如果设置,不但会监听后续触发,如果当前已经触发了鼠标的按下或者抬起,也将会触发后续事件。
在这里插入图片描述

绑定技能按键按下事件

我们接下来,要实现对技能按键的抬起和按下事件的触发,刚好回顾一下我们之前是如何绑定的技能输入。
我们在玩家控制器内,覆写了SetupInputComponent函数,这个函数是在设置了自定义输入组件是触发,我们通过输入组件对增强输入组件进行绑定输入回调。
在这里插入图片描述
你可以在项目设置的输入中修改它的默认类
在这里插入图片描述
在输入组件里,我们增加了一个绑定函数,可以绑定技能键位的按下抬起和按住事件,数据设置对应了输入和输入标签,方便我们后续通过输入标签进行和技能匹配激活。
在这里插入图片描述
我们在玩家控制器里,输入回调中,可以获取到输入标签,首先处理移动的问题,如果当前输入操作没有造成移动,我们将事件传递给ASC,在ASC中对技能进行相关处理。
在这里插入图片描述
技能在实例化时,我们会将技能的输入标签存储到动态标签中,方便你在技能面板对技能的输入标签进行修改。
在这里插入图片描述
我们接着修改ASC自定义的相关输入处理,我们将通过标签对技能进行匹配,如果匹配到了对应的技能实例,将触发在技能实例上设置的按下和抬起事件。

void URPGAbilitySystemComponent::AbilityInputTagPressed(const FGameplayTag& InputTag)
{
	if(!InputTag.IsValid()) return;

	for(auto AbilitySpec : GetActivatableAbilities())
	{
		if(AbilitySpec.DynamicAbilityTags.HasTagExact(InputTag))
		{
			AbilitySpecInputPressed(AbilitySpec);
		}
	}
}

void URPGAbilitySystemComponent::AbilityInputTagHold(const FGameplayTag& InputTag)
{
	if(!InputTag.IsValid()) return;

	for(auto AbilitySpec : GetActivatableAbilities())
	{
		if(AbilitySpec.DynamicAbilityTags.HasTagExact(InputTag))
		{
			AbilitySpecInputPressed(AbilitySpec);
			if(!AbilitySpec.IsActive())
			{
				TryActivateAbility(AbilitySpec.Handle);
			}
		}
	}
}

void URPGAbilitySystemComponent::AbilityInputTagReleased(const FGameplayTag& InputTag)
{
	if(!InputTag.IsValid()) return;

	for(auto AbilitySpec : GetActivatableAbilities())
	{
		if(AbilitySpec.DynamicAbilityTags.HasTagExact(InputTag) && AbilitySpec.IsActive())
		{
			AbilitySpecInputReleased(AbilitySpec);
		}
	}
}

最后,我们在自定义技能类里覆写技能基类的抬起和按下事件,ASC调用时,会触发这两个函数

	virtual void InputPressed(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo) override;
	virtual void InputReleased(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo) override;

接下来就是对函数实现,如果技能未激活,我们将无法触发按下事件,通过ASC来广播事件,这样在蓝图中对应的事件将会触发。

void URPGGameplayAbility::InputPressed(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo)
{
	Super::InputPressed(Handle, ActorInfo, ActivationInfo);
	//通过句柄获取技能实例
	FGameplayAbilitySpec* AbilitySpec = ActorInfo->AbilitySystemComponent->FindAbilitySpecFromHandle(Handle);
	//技能实例在激活状态,触发输入事件
	if(AbilitySpec->IsActive())
	{
		//将按下事件复制到服务器和所有相关的客户端
		ActorInfo->AbilitySystemComponent->InvokeReplicatedEvent(EAbilityGenericReplicatedEvent::InputPressed, Handle, ActivationInfo.GetActivationPredictionKey());
	}
}

void URPGGameplayAbility::InputReleased(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo)
{
	Super::InputReleased(Handle, ActorInfo, ActivationInfo);

	//将抬起事件复制到服务器和所有相关的客户端
	ActorInfo->AbilitySystemComponent->InvokeReplicatedEvent(EAbilityGenericReplicatedEvent::InputReleased, Handle, ActivationInfo.GetActivationPredictionKey());
}

接下来就是运行测试,查看当前是否正确打印,以及是否正确播放对象的动画
在这里插入图片描述

添加技能C++类

为了方便实现后续功能,我们创建一个闪电链使用的c++基类
在这里插入图片描述
然后修改我们之前创建的技能蓝图的父类
在这里插入图片描述
接着,我们在类里面增加一些代码,我们增加一个存储鼠标命中拾取的一些相关信息内容和当前玩家控制器,并增加一些保护性的变量,方便后续使用。

UCLASS()
class RPG_API URPGBeamSpell : public URPGDamageGameplayAbility
{
	GENERATED_BODY()

public:
	/**
	 * 将鼠标拾取命中信息存储
	 * @param HitResult 在技能中通过TargetDataUnderMouse的task获取到的结果
	 */
	UFUNCTION(BlueprintCallable)
	void StoreMouseDataInfo(const FHitResult& HitResult);

	/**
	 * 设置拥有当前技能的玩家控制器
	 */
	UFUNCTION(BlueprintCallable)
	void StoreOwnerVariables();

protected:

	UPROPERTY(BlueprintReadWrite, Category="Beam")
	FVector MouseHitLocation; //鼠标拾取位置

	UPROPERTY(BlueprintReadWrite, Category="Beam")
	TObjectPtr<AActor> MouseHitActor; //鼠标拾取的对象

	UPROPERTY(BlueprintReadWrite, Category="Beam")
	TObjectPtr<APlayerController> OwnerPlayerController; //拥有当前技能的玩家控制器
};

在函数实现这里,我们技能需要后续的拾取到内容才可进行,所以,如果没有拾取到,将取消技能激活,如果拾取到,则将拾取到的位置和actor存储。

void URPGBeamSpell::StoreMouseDataInfo(const FHitResult& HitResult)
{
	//判断当前是否拾取到内容
	if(HitResult.bBlockingHit)
	{
		MouseHitLocation = HitResult.ImpactPoint;
		MouseHitActor = HitResult.GetActor();
	}
	else
	{
		//取消技能
		CancelAbility(CurrentSpecHandle, CurrentActorInfo, CurrentActivationInfo, true);
	}
}

void URPGBeamSpell::StoreOwnerVariables()
{
	if(CurrentActorInfo)
	{
		OwnerPlayerController = CurrentActorInfo->PlayerController.Get();
		OwnerCharacter = Cast<ACharacter>(CurrentActorInfo->AvatarActor);
	}
}

接着,我们编译打开技能,并通过之前写的task来获取攻击距离,然后将拾取信息存储,以及保存玩家控制器。
在这里插入图片描述
接下来,我们实现在技能触发时,隐藏鼠标光标,并在对于技能触发按键抬起时,结束技能。
在这里插入图片描述
在技能触发时,我们需要一个抬手的动作,并在播放动作时,让角色转向到目标,这个使用的蒙太奇配置我们可以设置到角色蓝图上,角色配置项里,这里为了方便,直接在技能上设置。
在这里插入图片描述
然后我们找到对应的动画,创建蒙太奇。
在这里插入图片描述
并使用motion Wrapping来实现对角色向目标选择,记得动画要设置根运动。
在这里插入图片描述
接着设置对应的配置项。
在这里插入图片描述
接下来,我们要设置蒙太奇播放结束后,开始攻击,我们需要通知,在标签管理器增加一个闪电链的蒙太奇通知标签
在这里插入图片描述
在动画结束时添加一个动画通知,用于通知蒙太奇结束,开始攻击目标
在这里插入图片描述
设置我们之前设置的标签
在这里插入图片描述
由于混合时,motion wrapping不起作用,我们将混入和混出时间减少
在这里插入图片描述
将蒙太奇设置给变量
在这里插入图片描述
接着,在技能激活后,我们调用战斗接口的需要朝向的目标位置,并播放蒙太奇
在这里插入图片描述
由于整个技能需要战斗接口,如果当前拥有者没有继承战斗接口,那么就没有必要执行后续逻辑
在这里插入图片描述
我们将监听标签事件,通过标签对应,触发持续施法的动画。并在持续施法时,我们将禁止角色移动。
在这里插入图片描述
在鼠标抬起时,也就是技能结束之前,我们关闭持续施法动画,并将移动状态修改为行走,移动组件便可以恢复移动。
在这里插入图片描述
接下来,运行查看效果。
在这里插入图片描述

处理多个技能不能共同触发的问题

正常游戏进行中,玩家角色在释放一个技能时,是无法释放另一个技能。所以,我们需要在技能蓝图里,通过设置Activation Owned Tags来在技能激活时,给玩家角色设置技能应用标签。
在这里插入图片描述
然后,技能激活时,将在角色身上应用对应的标签,我们在控制器里,对标签进行判断,如果角色身上拥有此标签,那将无法触发对应的操作。首先我们在代码中,添加对应的阻止事件触发的标签

	//阻止输入相关事件触发
	FGameplayTag Player_Block_InputPressed; //阻挡键位按下输入
	FGameplayTag Player_Block_InputHold; //阻挡键位悬停输入
	FGameplayTag Player_Block_InputReleased; //阻挡键位抬起输入
	FGameplayTag Player_Block_CursorTrace; //阻挡鼠标拾取事件

然后注册

	/*
	 * 阻止相关鼠标事件的触发标签
	*/
	GameplayTags.Player_Block_InputPressed = UGameplayTagsManager::Get()
		.AddNativeGameplayTag(
			FName("Player.Block.InputPressed"),
			FString("阻挡键位按下输入")
			);
	GameplayTags.Player_Block_InputHold = UGameplayTagsManager::Get()
		.AddNativeGameplayTag(
			FName("Player.Block.InputHold"),
			FString("阻挡键位悬停输入")
			);
	GameplayTags.Player_Block_InputReleased = UGameplayTagsManager::Get()
		.AddNativeGameplayTag(
			FName("Player.Block.InputReleased"),
			FString("阻挡键位抬起输入")
			);
	GameplayTags.Player_Block_CursorTrace = UGameplayTagsManager::Get()
		.AddNativeGameplayTag(
			FName("Player.Block.CursorTrace"),
			FString("阻挡鼠标拾取事件")
			);

首先,我们阻止鼠标拾取,因为这个比较耗性能,每一帧都在拾取,如果事件被阻挡,我们将缓存的数据重置,并将已经高亮的角色取消高亮。

void ARPGPlayerController::CursorTrace()
{
	//判断当前事件是否被阻挡,如果事件被阻挡,则清除相关内容
	if(GetASC() && GetASC()->HasMatchingGameplayTag(FRPGGameplayTags::Get().Player_Block_CursorTrace))
	{
		if(ThisActor) ThisActor->UnHighlightActor();
		if(LastActor) LastActor->UnHighlightActor();
		ThisActor = nullptr; 
		LastActor = nullptr;
		return;
	}
	
	GetHitResultUnderCursor(ECC_Visibility, false, CursorHit); //获取可视的鼠标命中结果
	if(!CursorHit.bBlockingHit) return; //如果未命中直接返回

	LastActor = ThisActor;
	ThisActor = Cast<IEnemyInterface>(CursorHit.GetActor());

	if(ThisActor != LastActor)
	{
		if(ThisActor) ThisActor->HighlightActor();
		if(LastActor) LastActor->UnHighlightActor();
	}
	
}

然后就输按键的按下,长按,抬起事件的取消

void ARPGPlayerController::AbilityInputTagPressed(const FGameplayTag InputTag)
{
	//处理判断按下事件是否被阻挡
	if(GetASC() && GetASC()->HasMatchingGameplayTag(FRPGGameplayTags::Get().Player_Block_InputPressed))
	{
		return;
	}
void ARPGPlayerController::AbilityInputTagReleased(const FGameplayTag InputTag)
{
	//处理判断抬起事件是否被阻挡
	if(GetASC() && GetASC()->HasMatchingGameplayTag(FRPGGameplayTags::Get().Player_Block_InputReleased))
	{
		return;
	}
void ARPGPlayerController::AbilityInputTagHold(const FGameplayTag InputTag)
{
	//通过标签阻止悬停事件的触发
	if(GetASC() && GetASC()->HasMatchingGameplayTag(FRPGGameplayTags::Get().Player_Block_InputHold))
	{
		return;
	}

移动事件我们也可以阻止,因为移动事件是通过长按触发的

void ARPGPlayerController::Move(const FInputActionValue& InputActionValue)
{
	//方向控制,如果阻止了按住事件,将不再执行
	if(GetASC() && GetASC()->HasMatchingGameplayTag(FRPGGameplayTags::Get().Player_Block_InputHold))
	{
		return;
	}

接着,编译,我们打开UE,在技能将对应的事件阻挡,即可实现对应事件的阻挡。
在这里插入图片描述

创建释放音效

在释放闪电链时,我们需要对应的表现效果,所以,我们要创建GameplayCue蓝图,来实现在每个客户端上进行效果表现。
我们打开标签管理器,添加一个触发闪电链的标签。
在这里插入图片描述
接下来,我们创建一个GameplayCueNotify_Static类型的蓝图,这种蓝图调用不会生成Actor实例,所以也没有生命周期管理,它适合那种一次性的生效和粒子特效使用。
在这里插入图片描述
我们在类默认值这里设置触发标签
在这里插入图片描述
覆写OnExecute节点
在这里插入图片描述
在节点内,我们设置播放一个音效,在对应的角色位置触发即可
在这里插入图片描述
在技能里,我们在播放蒙太奇动画之前调用播放GameplayCue,设置对应标签,和目标以及配置
在这里插入图片描述
接下来,我们创建一个GameplayCueNotify_Actor蓝图,用来实现闪电链的特效表现,因为它需要目标的位置进行更新,需要在场景中生成Actor,表现效果能够持续一段时间,相应的,性能也会有更多的消耗。
在这里插入图片描述
打开GameplayCueNotify_Actor蓝图,你会发现和GameplayCueNotify_Static不同,因为GameplayCueNotify_Actor是继承AActor类的,我们可以进行更新它在场景中的表现。
在这里插入图片描述
它也可以通过标签激活,我们在GameplayCue标签下添加一个子标签,用于激活此蓝图生成实例
在这里插入图片描述
并设置到当前蓝图配置的类默认值里
在这里插入图片描述
接着我们将移除时自动销毁打开
在这里插入图片描述
循环的GameplayCue记得在技能结束时,将其移除。
在这里插入图片描述
接着,我们要覆写while Active它和On Active区别在于可以持续调用激活更新内容,On Active只能激活一次后,无法修改。
在这里插入图片描述
我们在持续激活里,通过配置项,从配置项里获取鼠标拾取位置以及附着的组件生成Niagara系统,并设置为变量,在销毁时,将粒子系统销毁掉,并将鼠标拾取位置传递给Niagara系统。
在这里插入图片描述
在被移除时,对粒子系统进行销毁
在这里插入图片描述

我们可以打开Niagara粒子系统,查看为闪电链开始和结束的参数,这个Niagara系统可以在底部加群获取一下。
在这里插入图片描述
在粒子系统默认值里,显示为这样
在这里插入图片描述
接下来,我们需要在技能里调用此GameplayCue,我们需要首先获取到角色的武器组件,从武器组件的对应位置发射闪电,所以大家要注意命名是否在GameplayCue里设置正确。
我们在战斗接口里增加一个获取武器组件的函数

	/**
	 * 获取角色使用的武器指针
	 * @return 武器骨骼网格体组件
	 */
	UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
	USkeletalMeshComponent* GetWeapon();

在角色基类里覆写一下

virtual USkeletalMeshComponent* GetWeapon_Implementation() override;

直接返回武器引用

USkeletalMeshComponent* ARPGCharacter::GetWeapon_Implementation()
{
	return Weapon;
}

接着回到闪电链技能蓝图里,我们在触发蒙太奇事件,开始技能循环播放时,通过函数获取骨骼组件,并将鼠标拾取位置传入,注意这里使用的生成GameplayCue的节点是AddGameplayCue On Actor(Looping)循环的。
在这里插入图片描述
由于它是循环的,所以在技能结束时,不会自动销毁,我们在技能结束前的处理中,移除Niagara System
在这里插入图片描述
接下来,就是运行测试效果
在这里插入图片描述

一些优化

为了提高系统查询对应的GameplayCue的效率,我们可以将GameplayCue的文件放入到统一的文件夹内
在这里插入图片描述
将文件移入到文件夹
在这里插入图片描述
我们可以在DefaultGame.ini通过手动指定目录,来提高检索速度,并且可以设置多行,系统查找时,会优先在这些文件夹内查询
在这里插入图片描述

提高信息同步数量

系统默认的信息同步数量为2,这个数量稍微有些偏低,我们可以通过设置来提高此数量
我们可以通过搜索MaxRPCPerNetUpdate,找到GameplayCueManager来查看
在这里插入图片描述
找到对应的函数
在这里插入图片描述
打上断点,在GameplayCue同步是,我们能够查看到同步数量,默认为2
在这里插入图片描述
我们在DefaultEngine文件里,增加修改,将每次复制的数量提高到10,这个不需要太高,每次同步10个基本上差不多,可以根据项目需要修改。
在这里插入图片描述
接着运行查看每次复制的数量是否更新为了10
在这里插入图片描述

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

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

相关文章

以太坊客户端Geth的介绍与搭建

一、以太坊客户端 1.介绍 以太坊客户端是指用于连接、交互和参与以太坊区块链网络的软件。以太坊客户端允许用户执行各种操作&#xff0c;如发送交易、挖矿、部署智能合约、同步区块链数据等。 2.功能 区块链同步&#xff1a;客户端会下载并验证以太坊区块链的所有区块&…

7. 无线网络安全

7. 无线网络安全 (1) 无线网络面临的安全威胁 无线网络由于其开放性和无线传输的特性,面临着多种安全威胁,主要包括: 窃听:攻击者可以截获无线电信号并解析出数据,甚至在加密通信中收集加密信息用于以后的分析。 通信阻断:通过DoS攻击或其他干扰手段阻断通信,使设备间无…

TFT-LCD显示屏(1.8寸 STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 3.工作原理&#xff1a;TFT-LCD色彩空间 三、程序设计 main.c文件 lcd.h文件 lcd.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 TFT-LCD&#xff0c;全称Thin Film Transistor Liquid Crystal Display&a…

gitlab修改访问端口

目录 1.找到gitlab.rb文件&#xff0c;一般在/etc/gitlab/路径下 2.打开配置文件&#xff0c;加上代码 3.重新配置 4.重启gitlab 1.找到gitlab.rb文件&#xff0c;一般在/etc/gitlab/路径下 2.打开配置文件&#xff0c;加上代码 打开文件 sudo vi gitlab.rb 加上默认端口配…

苹果AI手机遇阻,国产手机找到超车机遇

行至九月&#xff0c;2024年&#xff0c;这个所谓AI手机的元年&#xff0c;已经走过近三个季度了。 市场最为期待的AI手机机型也基本都发布了。9月20日&#xff0c;首款搭载Apple Intelligence功能的苹果新品iPhone16正式发售。或许是为了进一步扩大销售&#xff0c;今年天猫A…

【JAVA开源】基于Vue和SpringBoot的甘肃非物质文化网站

本文项目编号 T 042 &#xff0c;文末自助获取源码 \color{red}{T042&#xff0c;文末自助获取源码} T042&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

计算机网络-小型综合网络的搭建涉及到无线路由交换安全

目录 1 拓扑架构 2 做项目的思路 3 做配置 3.1先做核心交换 3.2 防火墙的配置 4 ac 和ap 的配置 4.1 ac上配置安全的东西 5.1 测试​编辑 1 拓扑架构 要求看上面的图 2 做项目的思路 这张网很明显是一个小综合&#xff0c;设计到我们的无线交换&#xff0c;路由…

统信服务器操作系统【SSH登录常见问题】解决方案

方案适用于统信服务器操作系统D/E/A版。 文章目录 前言问题及解决方案问题一问题现象问题原因问题方案问题二问题现象问题原因问题方案问题三问题原因问题方案问题四问题现象问题原因问题方案问题五问题现象问题原因问题方案问题六问题现象问题原因问题方案前言 介绍日常使用s…

语音识别控制(软件、硬件)

1. 环境 python版本&#xff1a;3.11.9 2. 完整代码 import sqlite3 import time import wave # 使用wave库可读、写wav类型的音频文件 from funasr import AutoModel import sounddevice as sd import numpy as np from modelscope import pipeline, Tasks from pypinyin …

软件著作权登记所需要的材料

软件著作权登记所需材料全面解析 在当今数字化时代&#xff0c;软件著作权作为保护软件开发者智力劳动成果的重要法律手段&#xff0c;其登记过程显得尤为重要。 一、软件著作权登记申请表 首先&#xff0c;软件著作权登记需要提交的最基本材料是《软件著作权登记申请表》。这份…

深度优先搜索算法及其matlab程序详解

#################本文为学习《图论算法及其MATLAB实现》的学习笔记################# 深度优先搜索算法(DepthFirst Search),简记DFS算法,是图论中的首要算法,其思想方法渗透到图论中的许多算法之中,尤其是DFS算法在求生成树、割点、块和平面图嵌入算法中起着极为关键的作用。…

写文档-画UML图-编程的秘密武器:Kimi智能助手

在快速发展的软件开发领域&#xff0c;如何高效地编写需求分析文档、软件设计文档以及代码&#xff0c;成为每位程序员和架构师面临的重要挑战。今天&#xff0c;我要向大家介绍一款强大的工具——Kimi智能助手&#xff0c;它将帮助你提升工作效率&#xff0c;优化开发流程。 …

【图灵完备 Turing Complete】游戏经验攻略分享 Part.5 编程

编程部分的话&#xff0c;第一关会让你输入机器码&#xff0c;这一章节还是比较简单的&#xff0c;因为操作码是固定给出的&#xff0c;只需要根据题意去编写&#xff0c;完成这章目的是为了解锁下面的关卡。 输入&#xff0c;移动COPY之后进行运算&#xff0c;然后输出。 激光…

18937 阿克曼(Ackmann)函数

### 思路 1. **递归定义**&#xff1a;根据阿克曼函数的定义&#xff0c;使用递归来计算函数值。 2. **递归终止条件**&#xff1a; - 当 m 0 时&#xff0c;返回 n 1&#xfffd;&#xfffd; - 当 m > 0 且 n 0 时&#xff0c;返回 ackermann(m - 1, 1)。 - 当…

基于单片机的粮仓环境检测系统设计

本设计主要由处理模块、温湿度检测模块、数据显示模块、声光报警模块和按钮的输入模块组成。采用了AT89C52作为主要的控制单元&#xff0c;利用DHT11温湿度传感器&#xff0c;对粮食仓库中的温度和湿度等展开检测&#xff0c;并在LCD1602液晶显示器中进行实时显示。同时&#x…

C++之GradeBook类

主文件 #include <iostream> #include "GradeBook.h"using namespace std;int main() {GradeBook myGradeBook; // 创建一个对象cout << "请输入课程名称:" ;string courseName;cin >> courseName;cout << "请输入学生人数&…

iOS常见锁及应用(笔记版)

什么是锁&#xff1f; 在程序中&#xff0c;当多个任务&#xff08;或线程&#xff09;同时访问同一个资源时&#xff0c;比如多个操作同时修改一份数据&#xff0c;可能会导致数据不一致。这时候&#xff0c;我们需要“锁”来确保同一时间只有一个任务能够操作这个数据&#…

vue打包exe之electron-quick-start的npm install 报错

vue打包exe之electron-quick-start的npm install 报错 1、github地址2、问题3、解决4、其他(打包exe)参考 1、github地址 https://github.com/electron/electron-quick-start2、问题 我使用的pnpm install正常安装&#xff0c;执行npm start提示错误 3、解决 在package.js…

Python之一些列表的练习题

1.比较和对比字符串、列表和元组。例如&#xff0c;它们可以容纳哪类内容以及在数据结构上可以做哪些操作。 1. 内容类型:- 字符串: 只能包含字符(文本)。- 列表: 可以包含任意类型的数据,如数字、字符串、其他列表等。- 元组: 可以包含任意类型的数据,与列表类似。3. 操作:(1…

Kaggle-狗种类的识别(Pytorch框架)基本图像识别流程

狗类别实现过程 一. 将数据集按标签分类&#xff0c;将标签转换为数字表示&#xff0c;并制作数据集 二. 搭建网络框架&#xff0c;inception&#xff0c;或者ResNet 三. 选择优化函数&#xff0c;训练模型 数据集制作 首先分析数据集&#xff0c;题中已经很明确告诉有120 种…