战略游戏

关于塔防游戏的文档。

Choose your operating system:

Windows

macOS

Linux

本示例已停止维护,虚幻引擎4.24后的版本将不再支持此示例。在加载此项目前,请确保你已经安装了正确的引擎版本。 如需了解如何更新项目并用于最新的引擎版本,请参阅 根据Epic最新更改进行升级。

本文档引用了名为 战略游戏(Strategy Game) 的游戏项目示例。你可以按照如下操作找到该示例:

  1. 点击Epic启动程序中的 学习(Learn) 选项卡,然后向下翻到 历史示例(Legacy Samples) 分段。

  2. 点击 战略游戏(Strategy Game) 的缩略图打开项目主页。点击黄色的 免费(Free) 按钮。

  3. 稍作等待后,按钮名称会变成 创建工程(Create Project) 。点击按钮后,启动程序会提示你输入项目名称并选择安装路径。

  4. 点击 创建(Create) 后,你就可以将该项目下载到指定的目录。

塔防(Tower Defense) 示例展示即时战略游戏(RTS)/塔防游戏示例。

特性的完整列表如下:

  • 简单AI逻辑

  • 自动生成的Pawns

  • 环绕式摄像机

  • 建造建筑

  • 主菜单

  • 组合了画布描画和Slate控件的游戏内HUD

  • 游戏内菜单

在塔防游戏中,玩家必须通过建造劲弩、自动弩以及喷火炮塔来防卫酿酒厂,同时还会有我方的士兵Pawn来协助防卫。 如果购买了酿酒厂升级, 这些士兵就会拥有大锤和盾牌。炮塔、士兵以及升级都需要花费金币,可以从金币节点中收集,也可以通过击败敌人来获得。 如果玩家能从5 波敌人的进攻中幸存,包括最终BOSS的攻击,而没有失去全部三条生命,就可以赢得胜利!

AI逻辑和自动生成的Pawn

minion_attack.png

塔防中的AI逻辑是简单的有限自动机(FSM)。两种可能的状态为向敌人基地移动以及攻击敌人,两种状态均为 继承于 StrategyAIAction 的单独类。 状态位于优先数组内,最为重要的操作排在最前面。这个数组被进行迭代,并且会选择最为适合执行的 操作,如果需要执行具有更高优先级的操作,则可以终止当前操作。

敌方Pawn和我方Pawn都根据AI逻辑运行,向对方基地移动,并且如果遇到对方则开始攻击对方的Pawn。玩家无法控制我方Pawn的移动 或行为,但是他们可以购买新的单位以供生成。

同时,我们使用了蓝图为士兵Pawn添加逻辑。友军和敌军都可以装备盾牌;如果你为酿酒厂购买了兵工厂升级,则友军可以获得盾牌, 如果在 关卡蓝图 中调用SpawnHeavyFunction或SpawnEndBossFunction,则敌军的Pawn将会获得盾牌。如果Pawn拥有盾牌,则自动弩射弹将会被销毁并且不会造成伤害。 这个逻辑使用 蓝图接口(Blueprint Interfaces) 来实现。 名称为 Minion (士兵)的蓝图也包含了网络,可以在敌军Pawn被火焰炮塔蓄力击中时令其减速。

建造建筑

在塔防游戏中,有两种建筑类 - StrategyBuilding StrategyBuilding_Brewery 。塔防中所有的炮塔类型以及空白建筑栏都使用 父类为 StrategyBuilding 的蓝图。玩家可以点击任意空白建筑格来显示快捷菜单并选择建造新建筑。在建造建筑时,空白建筑栏会被销毁,同时生成新建筑。

同时还有一个升级建筑的机制。 StrategyBuilding_Brewery 类被用于此例中,因此在酿酒厂基地附近的关联空格中可以建造升级建筑。

再次重申,塔防中的代码会创建基础建筑类。塔防游戏中建筑的所有逻辑和设计都由关卡设计师在蓝图中制作。

酿酒厂

Brewery(酿酒厂) 蓝图具有父类 StrategyBuilding_Brewery ,并且还包含了AIDirector组件。在塔防地图(TowerDefenseMap)中放置了两个酿造厂,一个是敌人 Pawm生成的地方,另一个是我方的酿酒厂,你可以在此处搭建兵工厂并升级铁匠铺,并且可以生成我方的Pawns。在 酿酒厂(Brewery) 蓝图中没有图表逻辑,只有建造属性的 默认设置以及包含AIDirector\触发器盒体以及 静态网格物体 的组件列表。

升级

upgraded_brewery.png

我方酿酒厂有两格升级栏。它们是继承自 StrategyBuilding 类的 蓝图类(Blueprint Classes) 。如果在酿酒厂菜单中选择一项升级, 则升级内容将会占据一格空白栏。你只能购买一项铁匠铺升级和一项兵工厂升级。

购买铁匠铺升级后,建造开始,在 Wall_Smithy 蓝图中触发OnBuildStarted事件。该蓝图还会在建造完成时告知系统升级已经完成。此时,任何我方Pawn都会获得盾牌附着,该盾牌是来自 StrategyAttachment 类中的蓝图。在兵工厂 报告其构建完成之后,指派"shield-attaching"操作的网络 出现于 TowerDefenseMap 关卡蓝图 的PlayerBaseUpgrades折叠图表中。 StrategyAttachment 类包含一个 骨骼网格体组件(SkeletalMeshComponent) ;附加的网格体和附加点在 Attachment_Armorer 蓝图的默认值中进行设置。

兵工厂蓝图包含了使用OnBuildStarted和OnBuildFinished事件设置的相同逻辑。建造兵工厂后,生成的任何我方Pawn都会拥有大锤,也是继承 自 StrategyAttachment 类。在铁匠铺升级报告其建造完成之后,指派"hammer-attaching"操作的网络也出现于 TowerDefenseMap 关卡蓝图 的PlayerBaseUpgrades折叠图表中。

炮塔

空白栏

building_empty_slot.png

空白栏也是具有 StrategyBuilding 父类的蓝图Wall_EmptySlot。在蓝图图表中没有逻辑。这是一个 蓝图类 ,其建造 属性、静态网格体以及作为组件设置的触发器盒体设置默认值。

所有可能的炮塔升级都在建造分段升级部分中Wall_EmptySlot蓝图的默认值部分进行设置。

劲弩

building_arbalest_shooting.png

Wall_arbalest 蓝图包含了劲弩的逻辑,劲弩是一种基本的炮塔类型。劲弩使用中等强度的射弹射击最近距离的敌人,在其默认模式中自动射箭。玩家 也可以手动发射弩,他可以点击弩,然后拖曳至想要发射的方向。鼠标拖曳的距离越长,发射弩的强度就越大。

劲弩的射弹被存储在继承于具有 StrategyProjectile 的蓝图TestProjectile的另一蓝图Projectile_arbalest中。Wall_arbalest蓝图具有一定数量的子网络,都包含在事件图表内。在构造脚本(ConstructionScript)中没有蓝图逻辑。

自动弩

building_auto-arbalest_shooting.png

Wall_arbalest_auto 蓝图包含了自动弩的逻辑。自动弩从墙壁处直线发射射弹,对射弹穿过的每个单位造成 少量伤害。自动弩只有在击中墙壁或敌人的盾牌时才会被销毁。你可以通过点击和拖曳,让自动发射的弩瞄准所需方向; 当你按下鼠标时,自动弩将会持续向瞄准的方向射击,但松开鼠标按钮后将会返回其默认发射位置。

和劲弩一样,这个炮塔发射的射弹弓箭包含于单独的蓝图中。名称为Projectile_arbalest_auto的自动发射的弓箭只有在撞击具有盾牌的敌人Pawn或墙壁时才会被销毁,而且这个操作 是通过 蓝图接口 ,Interface_Auto_Arbalest和Interface_Auto_Projectile的辅助来执行的。

喷火器

building_fire_shooting_normal.png

喷火器并不像其他类型的炮塔那样发射射弹。它对喷火区域中的对所有敌人喷火。玩家可以点击并按住鼠标不放来积攒喷火器的能量; 根据按下的时间不同,释放鼠标后产生的能量可以达到最高三倍的伤害,并减缓受损伤的敌军Pawn的速度。如果玩家积聚喷火器的能量, 随后会需要很短的冷却时间,然后继续开始常规的火焰攻击。

摄像机

塔防的摄像机具有固定的视角,并能根据鼠标滚轮的滑动来缩放视角。摄像机的运算在 StrategyPlayerController 类的 CalcCamera 函数中进行, 你可以在 DefaultGame.ini 中计算常量,例如摄像机最小和最大偏移、角度以及摄像机速度。

我们使用观察者Pawn来创建不具有可见Pawn的玩家。

游戏内HUD

游戏内HUD是通过混合使用画布描画(Canvas drawing)和Slate控件创建的。

StrategyGameHUDcallouts.png

在右上角,游戏计时器为游戏计算热身倒计时,使用类 SStrategySlateHUDWidget 中的函数 GetGameTime 。游戏开始后,倒计时从屏幕上消失, 并显示剩余的生命数(1) 。"剩余生命数"显示的属性在 AStrategyHUD 类的 DrawLives 函数中进行设置;生命值的初始数值 在TowerDefenseMap 关卡蓝图 中的PlayerBaseUpgrades子图表中进行设置。

当前的金币资源显示在屏幕的顶部中心位置(2)。游戏计时器和资源显示都使用 SStrategySlateHUDWidget 中的基础控件进行定义。同一个类 被用于创建所有顶层的控件,但并不默认显示所有控件。

迷你地图位于HUD的左下角(3)。它是从不可见的Slate控件覆层中构建的,该覆层处理输入和实际地图图像,而此图像使用画布来描画。 SStrategyMiniMapWidget 负责在按下按钮或在缩略地图区域按住按钮不放时移动摄像机。

点击建筑空白栏时,会显示 SStrategyActionGrid 菜单。只存在此控件的一个实例;其位置由激活的建筑空白栏决定。计算菜单的 屏幕位置是以 DrawHUD 方式来完成的,它会投射选定的Actor位置到二维坐标。此菜单的动作按钮的外观和事件 在 ShowActionMenu ShowCustomAction 方式的 AStrategyBuilding 类中进行定义。 按钮`控件在 SStrategyButtonWidget 类中进行定义,任意绑定到 动作按钮的额外信息都存储在 FActionButton` 信息结构中。

Pawn和建筑的生命条都使用 DrawActorsHealth 方式在画布上进行描画。每个队伍都有不同的生命条纹理。

health_bar_textures.png

在HUD的右下角位置处,有一个 PauseButton (暂停按钮)(4),它可以切换暂停游戏和游戏中菜单的可视性。

游戏时间用尽或其中一个基地被摧毁后,游戏将会暂停,同时在屏幕中心位置会出现"胜利"或"失败"文本动画。动画会随时间而改变字体大小。 文本使用简单的 STextBlock 控件来创建,具有可视度、字体和文本的代理。

菜单

主菜单

StrategyGameMainMenu1.png

主菜单位于 StrategyMenu 地图内,它会载入主菜单的特定HUD。菜单是基于Slate的, SStrategyMenuWidget`负责主菜单的动画、 布局甚至处理。 SStrategyMenuItem 类继承于游戏内HUD中的 SStrategyButtonWidget ,并且描述了单个菜单选项。每个菜单选项(以及附着于选项的事件) 都在 StrategyMenuHUD` 中进行定义。

如需返回到上一菜单,菜单共享指针的数组都被存储在 MenuHistory 变量中。这个变量如同堆栈,存储之前查看过的菜单,这样在返回时很方便, 同时能移除存储菜单父类的需求,这样菜单可以在多个场合中重新使用。‏

菜单动画使用在 SStrategyMenuWidget::SetupAnimations 中定义的插值曲线。每条曲线都定义了起始时间、持续时间和插值方式,而且可以正反向播放。 如需在特定时间播放动画属性,则使用`GetLerp()`,它会返回在0.0f和1.0f之间的值。‏‎‏

游戏中菜单

StrategyGamePauseMenu.png

当游戏中的菜单为激活状态时,会显示半透明的全屏Slate覆层,并且游戏被暂停。 PauseMenuButtons SStrategySlateHUDWidget 中进行定义。游戏中的暂停菜单有两个按钮: 一个是退出游戏,第二个返回主菜单。 如需退出游戏中菜单,玩家应再次按下右下方的暂停按钮。

关卡蓝图

关卡蓝图 具有生成每波攻击的模块化结构,以及初始化和胜利/失败条件。

敌人生成

使用三个 蓝图宏 来构建每波进攻:可以生成快速敌军(spawn fast)、生成正常敌军(spawn normal)以及生成重型敌军(spawn heavy)。每次生成都使用所需的单位参数和附件,并随后等待 StrategyAIDirector 中的 SpawnMinions 函数触发。宏会等待敌军酿酒厂的 StrategyAIDirector 返回已经生成一波攻击的报告,然后允许在退出子网络的情况下执行。

每个生成的宏需要两个执行输入,一个用于开始宏,一个用于在OnWaveSpawned事件触发后打开 大门 ,并对生成的Pawns数量进行整数输入。
来自类 StrategyAIDirector 的函数被调用,同时对每种类型的Pawn进攻波指定输入。三个函数为 SetDefaultWeapon SetDefaultArmor 以及 SetBuffModifier SetDefaultWeapon SetDefaultArmor 将蓝图作为输入并指派这些蓝图为生成时的新默认武器或默认装甲。举例来说,所有由SpawnFastMacro生成的 敌军Pawn将Attachment_Smithy锤子蓝图作为默认武器,所有由SpawnHeavyMacro生成的敌军Pawn将Attachment_Armorer盾牌蓝图作为其默认装甲。

最后由生成蓝图函数调用的 StrategyAIDirector 函数是 SetBuffModifier ,它具有多个数据输入,包括Pawn的攻击能力、生命值加成、速度和大小。 这些输入都在蓝图中进行显示,所以关卡设计师可以直接创建要生成的敌军Pawn的新类。最后,每个生成的蓝图函数都会设置敌军酿酒厂的 StrategyAIDirector WaveSize 属性。

一共有五波敌人的攻击,每波都组合了不同的敌军Pawn,有快速、普通以及重型敌军。在每波攻击的起始处,显示每波进攻标题(Show Wave Title)节点都会显示波数。然后,调用首波 敌人的生成。在生成后有两种类型的延迟:一个是由延迟节点设置的计时器延迟,一个是由WaitForWaveMacro设置的基于Pawn的延迟。WaitForWaveMacro宏继续检查有多少敌军Pawn仍存活, 并且除非延迟时间过期或所有敌军Pawn均被摧毁,否则不会退出执行宏。在一波攻击的所有生成都完成,并且该波的所有敌军Pawn都被消灭后(或者过了两分钟), 使用 远程事件 节点对下一波进攻调用 自定义事件

输赢条件

在游戏中,你的基地有三条命。如果有一个敌军Pawn到达了我方的酿酒厂,则扣除一条命,所有命都扣除后,游戏失败。如果敌军的首领到达了我方的酿酒厂, 则游戏失败。要赢得游戏,你必须在损失所有三条命前击败所有的五波敌军。该网络同时设置了输赢条件,它们位于 TowerDefenseMap 关卡蓝图 中,并会调用 在类 StrategyGameMode 中设置的函数,该函数来自于 AGameModeBase 类。 StrategyGameMode 类还包含诸如 InitGame 的函数,它会初始化游戏,并且在Actor的预初始化组件 SetGamePaused SetGameDifficulty 被调用前进行调用。

在第五波生成的最终首领被消灭后,使用 远程事件 节点来调用胜利 自定义事件 。该 自定义事件 位于 胜利条件 评论框内,然后触发子网络WaitForWin的执行, 该子网络会检查是否有其它仍存在的敌军Pawn。如果该值为 true ,则在WinningTeam输入被设置为"玩家"的情况下调用 Finish Game 函数。

失败条件 评论框中有两个节点,它们会调用胜利队伍输入设置为"Enemy"的 Finish Game 函数,这会导致玩家游戏失败。第一个节点会在全部三条命都 损失后触发,三条生命会在敌军Pawn到达我方酿酒厂时被扣除。每次敌军Pawn到达我方酿酒厂时都会触发 MultiGate 节点。MultiGate节点的第一个和第二个输出执行引脚都与更新 我方酿酒厂的剩余生命量(NumberOfLives)值的节点相连接,从而每次将值降低1。最后的输出执行引脚将我方酿酒厂的生命值量设为0,并随后触发WinningTeam值为"Enemy"的 Finish Game 函数。敌方首领生成后,BossSpawned 自定义事件 关闭Gate节点,会造成"3条命版本"的MultiGate,并打开另一个GateNode,从而使得第二个 Finish Game 函数的WinningTeam设置为 "Enemy"。这样可以创建开放的网络,如果最终敌方首领到达我方酿酒厂,FinishGame函数会被激活并且游戏失败。

资源节点 - 金币

金币节点为具有父类 StrategyResourceNode 的蓝图。这个类包含公共函数 GetAvailableResources GetInitialResources 、受保护的函数 OnDepleted 、 资源用尽时的报告函数 BlueprintImplementableEvent 、以及设置节点中资源数量的受保护属性 NumResources

金币节点的蓝图包含子网络,从而让节点按照计时器出现和消失。蓝图中的 构造脚本 在蓝图被放置在关卡时设置节点为自动隐藏。 当金币节点出现时,AppearFX粒子特效和声音一起播放。如果由于节点被成功收集而触发了 OnDepleted 事件,则在节点中出现的金币数量被添加到 玩家的总金币池中。播放CollectFX粒子特效和CoinSound,随后节点被再次隐藏。如果玩家未能及时通过点击金币来收藏节点, 则播放FadeFX粒子特效和相应的声音。

欢迎帮助改进虚幻引擎文档!请告诉我们该如何更好地为您服务。
填写问卷调查
取消