如何用单页面框架制作51传奇网页游戏?
摘要:网站用单页面框架做,51传奇网页游戏,wordpress+左侧导航,在线名片设计TSet 官方文档:虚幻引擎中的Set容器 | 虚幻引擎 5.5 文档 | Epic Developer Community (e
网站用单页面框架做,51传奇网页游戏,wordpress+左侧导航,在线名片设计TSet
官方文档#xff1a;虚幻引擎中的Set容器 | 虚幻引擎 5.5 文档 | Epic Developer Community (epicgames.com)
TSet 是通过对元素求值的可覆盖函数#xff0c;使用数据值本身作为键#xff0c;而不是将数据值与独立的键相关联。
默认情况下#xff0c;TSet 不支持重…TSet
官方文档虚幻引擎中的Set容器 | 虚幻引擎 5.5 文档 | Epic Developer Community (epicgames.com)
TSet 是通过对元素求值的可覆盖函数使用数据值本身作为键而不是将数据值与独立的键相关联。
默认情况下TSet 不支持重复的键但使用模板参数可激活此行为。
TSet 是一种快速容器类用于在排序不重要的情况下存储唯一元素。TSet 可以非常快速地添加、查找和删除元素恒定时间。在大多数情况下只需要一种参数——元素类型。但是TSet 可配置各种模板参数来改变其行为使其更全面。除了可指定从 DefaultKeyFuncs 的派生结构体来提供散列功能还可允许集合中的多个键拥有相同的值。它和其它容器类一样可设置自定义内存分配器来存储数据。
和 TArray 一样TSet 是同质容器。TSet 也是值类型支持常规复制、赋值和析构函数操作以及其元素较强的所有权。TSet 被销毁时其元素也将被销毁。键类型也必须是值类型。
TSet 使用散列即如果给出了 KeyFuncs 模板参数该参数会告知集合如何从某个元素确定键如何比较两个键是否相等如何对键进行散列以及是否允许重复键。它们默认只返回对键的引用使用 运算符 对比相等性使用非成员函数 GetTypeHash 进行散列。默认情况下集合中不允许有重复的键。如果您的键类型支持这些函数则可以将其用作集合键无需提供自定义 KeyFuncs。要写入自定义 KeyFuncs可扩展 DefaultKeyFuncs 结构体。
最后TSet 可通过任选分配器控制内存分配行为。标准虚幻引擎4UE4分配器如 FHeapAllocator 和 TInlineAllocator不能用作 TSet 的分配器。实际上TSet 使用集合分配器该分配器可定义集合中使用的散列桶数量以及用于存储元素的标准UE4分配器。
与 TArray 不同的是内存中 TSet 元素的相对排序既不可靠也不稳定对这些元素进行迭代很可能会使它们返回的顺序和它们添加的顺序有所不同。这些元素也不太可能在内存中连续排列。集合中的后台数据结构是稀疏数组(在数组中有空位。从集合中移除元素时稀疏数组中会出现空位)。将新的元素添加到阵列可填补这些空位。
但是即便 TSet 不会打乱元素来填补空位指向集元素的指针仍然可能失效因为如果存储器被填满又添加了新的元素整个存储可能会重新分配。
1.创建和填充集合
创建一个MapActor类并继承于Actor其与TArray创建方法一样就不一一详细介绍
Actor类头文件增添代码:
publicUFUNCTION(BlueprintCallable)void InitSet();
源文件增添代码
void ASetActor::InitSet()
{TSetFString FruitSet;//此处的元素按插入顺序排列但不保证这些元素在内存中实际保留此排序。//如果是新集合可能会保留插入排序但插入和删除的次数越多新元素不出现在末尾的可能性越大。FruitSet.Add(TEXT(Banana));FruitSet.Add(TEXT(Grapefruit));FruitSet.Add(TEXT(Pineapple));// FruitSet [ Banana, Grapefruit, Pineapple ]FruitSet.Add(TEXT(Pear));FruitSet.Add(TEXT(Banana));//此处与上面的键重复因此覆盖了但此处会触发扩容// FruitSet [ Banana, Grapefruit, Pineapple, Pear ]// Note:Only one banana entry.//此处参数直接传递给键类型的构造函数。这可以避免为该值创建临时 FString。//与 TArray 不同的是只能使用单一参数构造函数将元素放到集合中。FruitSet.Emplace(TEXT(Orange));//追加元素用Emplace函数代替Add避免插入集合时创造临时文件// FruitSet [ Banana, Grapefruit, Pineapple, Pear, Orange ]TSetFString FruitSet2;FruitSet2.Emplace(TEXT(Kiwi));FruitSet2.Emplace(TEXT(Melon));FruitSet2.Emplace(TEXT(Mango));FruitSet2.Emplace(TEXT(Orange));FruitSet.Append(FruitSet2);// FruitSet [ Banana, Grapefruit, Pineapple, Pear, Orange, Kiwi, Melon, Mango ]
}
注意元素以及Num的变化从而去理解TSet键的原理 使用数据值本身作为键 2.编辑UPROPERTY TSet
如果用 UPROPERTY 宏和一个可编辑的关键词EditAnywhere、EditDefaultsOnly 或 EditInstanceOnly标记 TSet则可在虚幻编辑器中添加和编辑元素。
Actor类头文件增添代码:
publicUPROPERTY(BlueprintReadWrite,EditAnyWhere,Category SetExample)TSetFString MyFruitSet;
在蓝图可编辑操作
此处为FString但其也可以放结构体
3.迭代
Actor类头文件增添代码:
publicUFUNCTION(BlueprintCallable)void LoopSet();
源文件增添代码
void ASetActor::LoopSet()
{TSetFString FruitSet;FruitSet.Add(TEXT(Banana));FruitSet.Add(TEXT(Grapefruit));FruitSet.Add(TEXT(Pineapple));//依次输出元素for (auto Elem :FruitSet)//此处的auto可换为FString其本质时自动推导类型{FPlatformMisc::LocalPrint(*FString::Printf(TEXT( \%s\\n),*Elem));}//创建迭代器如为CreateConstIterators 函数则为常量迭代器for (auto It FruitSet.CreateIterator(); It; It){//注意后面*(*It)第一个*是把FString类型变成TCHAR第二个是指针因为迭代器It是地址FPlatformMisc::LocalPrint(*FString::Printf(TEXT((%s)\n),*(*It)));}for (auto It FruitSet.CreateConstIterator(); It; It){FPlatformMisc::LocalPrint(*FString::Printf(TEXT((%s)\n),*(*It)));}
}
4.查询
Actor类头文件增添代码:
publicUFUNCTION(BlueprintCallable)void QuerySet();
源文件增添代码
void ASetActor::QuerySet()
{TSetFString FruitSet;bool bHavefalse;FruitSet.Add(TEXT(Banana),bHave);//此处bHave为falseFruitSet.Add(TEXT(Grapefruit));FruitSet.Add(TEXT(Pineapple));FruitSet.Add(TEXT(Banana),bHave);//此处使得bHave为trueint32 Count FruitSet.Num();// Count 3//要确定集合是否包含特定元素可按如下所示调用 Contains 函数bool bHasBanana FruitSet.Contains(TEXT(Banana));bool bHasLemon FruitSet.Contains(TEXT(Lemon));// bHasBanana true// bHasLemon false//使用 FSetElementId 结构体可查找集合中某个键的索引。FSetElementId SetElementIdFruit.Add(TEXT(Water));//FSetElementId为标识符此处SetElementId{Index3}FruitSet[SetElementId]TEXT(Modify);//此处将Index为3的元素进行修改为WaterModify//使用 Find 函数查找一次即可完成这些行为。//如果集合中包含该键Find 将返回指向元素数值的指针。如果映射不包含该键则返回null。对常量集合调用Find返回的指针也将为常量。FString* PtrBanana FruitSet.Find(TEXT(Banana));FString* PtrLemon FruitSet.Find(TEXT(Lemon));// *PtrBanana Banana// PtrLemon nullptr//Array 函数会返回一个 TArray其中填充覆盖即使有元素在内了 TSet 中每个元素的一份副本。因此元素的生成数量将始终等于集合中的元素数量TArrayFString FruitArray FruitSet.Array();//用Array函数转换为TArray数组
} 5.移除
Actor类头文件增添代码:
publicUFUNCTION(BlueprintCallable)void RemoveSet();
源文件增添代码
void ASetActor::RemoveSet()
{TSetFString FruitSet;FruitSet.Reserve(4);FruitSet.Add(TEXT(Banana));FruitSet.Add(TEXT(Grapefruit));FruitSet.Add(TEXT(Pineapple));FruitSet.Add(TEXT(GG));FruitSet.Add(TEXT(HH));FruitSet.Add(TEXT(JJ));//Remove函数有两种使用参数方法FruitSet.Remove(FSetElementId::FromInterger(0));//通过索引移除第一个元素//Remove函数会返回已删除元素的数量。int32 GGNumFruitSet.remove(TEXT(GG));//GGNum1int32 MMNumFruitSet.remove(TEXT(MM));//MMNum0TSetFString FruitSet1FruitSet;FruitSet1.Reset();//将集合中的所有元素移除但内存空间还在TSetFString FruitSet2FruitSet;FruitSet2.Empty(0);//此操作是将元素及其内存空间都删除
}
6.排序运算符Slack
6.1排序
TSet 可以排序。排序后迭代集合会以排序的顺序显示元素但下次修改集合时排序可能会发生变化。由于排序不稳定可能按任何顺序显示集合中支持重复键的等效元素。
Actor类头文件增添代码:
publicUFUNCTION(BlueprintCallable)void SortSet();
源文件增添代码
void ASetActor::SortSet()
{TSetFStringFruitSet{ Orange,Pear, Melon, Grapefruit, Mango, Kiwi};FruitSet.Sort([](const FString A, const FString B) {return A B; // sort by reverse-alphabetical order});// FruitSet [ Pear, Orange, Melon, Mango, Kiwi, Grapefruit ] (order is temporarily guaranteed)//Sort 函数使用指定排序顺序的二进制谓词FruitSet.Sort([](const FString A, const FString B) {return A.Len() B.Len(); // sort strings by length, shortest to longest});// FruitSet [ Pear, Kiwi, Melon, Mango, Orange, Grapefruit ] (order is temporarily guaranteed)
}
6.2运算符
其和 TArray 一样TSet 是常规值类型可通过标准复制构造函数或赋值运算符进行复制。因为集合严格拥有其元素复制集合的操作是深层的所以新集合将拥有其自身的元素副本。
Actor类头文件增添代码:
publicUFUNCTION(BlueprintCallable)void OpeatorSet();
源文件增添代码
void ASetActor::SortSet()
{TSetFStringFruitSet{ Orange,Pear, Melon, Grapefruit, Mango, Kiwi};TSetFString NewSet FruitSet;//在新的进行增删改查NewSet.Add(TEXT(Apple));NewSet.Remove(TEXT(Pear));
}
//在移除目录处也有提及
6.3Slack
其用法与TMap容器大致相似
Actor类头文件增添代码:
publicUFUNCTION(BlueprintCallable)void SlackSet();
源文件增添代码
void ASetActor::SortSet()
{TSetFStringFruitSet{ Orange,Pear, Melon, Grapefruit, Mango, Kiwi};//Reset函数可在不取消任何内存的情况下移除集合中的所有元素从而产生slackFruitSet.Reset();FruitSet.Reserve(10);//在原基础上追加预分配10个内存for (int32 i 0; i 10; i){FruitSet.Add(FString::Printf(TEXT(Fruit%d), i));}
// FruitSet [ Fruit9, Fruit8, Fruit7 ...Fruit2, Fruit1, Fruit0 ]// Remove every other element from the set.for (int32 i 0; i 10; i 2){FruitSet.Remove(FSetElementId::FromInteger(i));}
// FruitSet [Fruit8, invalid, Fruit6, invalid, Fruit4, invalid, Fruit2, invalid, Fruit0, invalid ]//Shrink裁剪元素FruitSet.Shrink();//注意此处数组Max值为10
// FruitSet [Fruit8, invalid, Fruit6, invalid, Fruit4, invalid, Fruit2, invalid, Fruit0 ]//CompactStable函数压缩元素Compact函数则可能改变排序FruitSet.CompactStable();// FruitSet [Fruit8, Fruit6, Fruit4, Fruit2, Fruit0, invalid, invalid, invalid, invalid ]FruitSet.Shrink();// FruitSet [Fruit8, Fruit6, Fruit4, Fruit2, Fruit0 ]
}
