Cave:入门指南
Python 工具与编辑器扩展
Lesson 16 of 19 • 10 XP
Keep your place in this quest
Log in or sign up for free to subscribe, follow lesson progress, and access more learning content.
在上一课中,您学习了如何在游戏播放期间使用 Python 控制实体。但在 Cave 中,Python 不仅限于运行中的游戏。您还可以使用它来创建 编辑器工具,帮助您更快地构建游戏。
这尤其有用,因为许多项目都有重复的任务。也许您经常放置敌人、创建检查点、组织文件夹、测试值或检查场景数据。与其每次都手动执行所有操作,不如创建一些小工具来自动化工作流程的部分。您甚至可以创建更高级的编辑器,使您能够实现程序生成的关卡、程序建筑等。
在本课中,您将学习:
- 游戏脚本与编辑器脚本之间的区别。
- 编辑器工具的用途。
- 编辑器选项卡工具的结构。
#editoronly的重要性。- 何时值得创建自定义工具。
您不需要在刚开始时就立即构建工具,但了解这个系统的存在是好的。随着项目的增长,它会变得更加有价值。
游戏脚本与编辑器工具
简单来说:
- 游戏脚本 在游戏播放时运行。
- 编辑器工具 在编辑器内运行,帮助您处理项目。
| 脚本类型 | 运行于 | 示例 |
|---|---|---|
| 游戏脚本 | 播放模式和导出游戏。 | 玩家移动、敌人 AI、门、道具。 |
| 编辑器工具 | Cave 编辑器。 | 关卡助手、批量重命名器、场景检查器、程序生成建设、放置工具。 |
例如,开门脚本是游戏逻辑,因为玩家应该在游戏中体验它。而一个沿走廊放置十个火把的工具是编辑逻辑,因为它帮助您构建关卡,但在导出的游戏中并不需要存在。
编辑器工具的用途
起初,自定义工具可能听起来是大型团队才需要的东西。
但是,独立开发者同样可以受益于小工具,因为它们减少了重复的手动工作。如果您多次执行相同的任务,简单的编辑器脚本可以让项目的工作效率大大提升。
编辑器工具可以帮助处理的事情包括:
- 放置实体组。
- 检查所需组件是否缺失。
- 创建常见场景设置。
- 打印调试信息。
- 在进入播放模式之前测试值。
- 帮助设计师调整游戏数据。
例如,假设您正在构建一个拥有多个敌人营地的第三人称游戏。与其每次都手动创建相同的文件夹结构,您可以创建一个工具,自动添加一个 敌人组、一些出生点和一个触发区域。
仅限编辑器脚本
编辑器脚本通常以这一行开头:
#editoronly
这告诉 Cave 该脚本仅用于编辑器。
这很重要,因为编辑器工具可能使用仅在编辑器内有意义的 API 或行为。您通常不希望关卡设计助手或调试面板成为最终游戏运行时的一部分。
这也很重要,以指示 Cave 哪些脚本在游戏启动时运行,哪些脚本要忽略。默认情况下,它会运行每个脚本,因此如果您希望某个脚本被忽略,则应将该评论作为第一行包含在内。
因此,如果您创建了一个仅用于帮助您在 Cave 编辑器内工作的脚本,请将其设为仅限编辑器。
编辑器选项卡工具
创建工具的一种常见方式是使用 编辑器选项卡。

编辑器选项卡是一个自定义面板,出现在 Cave 编辑器内。它具有 draw() 方法,而 Cave 会在选项卡可见时调用该方法,以便工具可以绘制按钮、文本、属性和其他控件。
一个非常简单的编辑器选项卡看起来像这样:
#editoronly
import cave
class ExampleTab(cave.ui.DebugTab):
def __init__(self):
super().__init__()
self.counter = 0
def draw(self):
cave.ui.text("这是一个示例工具。")
cave.ui.separator()
self.counter = cave.ui.prop("计数器", self.counter)
if cave.ui.buttonDark("增加计数器 +1"):
self.counter += 1
print("计数器增加 +1")
这是您添加编辑器选项卡时的默认代码。如果点击以在属性选项卡中打开它,然后转到编辑器工具选项卡,您会看到示例选项卡类作为调试选项卡出现。然后,您只需注册或重新加载选项卡,它将在 UI 中可用:

这个示例很简单,但它已经展示了基本思想:
cave.ui.DebugTab创建一个自定义编辑器选项卡。draw()定义选项卡显示的内容。cave.ui.text()绘制文本。cave.ui.prop()绘制可编辑的属性。cave.ui.buttonDark()创建一个按钮。print()用于向控制台发送信息。
这就是创建 Cave 编辑器自定义工具的简单方法。您可以使用相同的结构稍后构建实际工具。
draw() 方法的含义
draw() 方法与游戏组件中的 start() 不同。
它在工具可见时会重复调用,因为编辑器 UI 需要被绘制和更新。这意味着 draw() 中的代码应该描述工具的当前界面。
例如:
def draw(self):
cave.ui.text("关卡助手:")
if cave.ui.buttonDark("创建敌人组"):
print("创建敌人组被点击")
按钮每次选项卡更新时都会被绘制,但 if 中的代码只有在用户点击按钮时才会运行。
这种模式在编辑器工具中非常常见。
一个实用的工具想法
假设您正在构建一个关卡,您经常需要相同的基本文件夹:
环境敌人游戏触发器照明音频调试助手
您可以创建一个带有 创建关卡文件夹 按钮的编辑器工具。当点击时,它可以在当前场景中创建这些文件夹实体。请记住:场景图中的文件夹只是没有附加组件的实体。
这听起来很小,但像这样的简单工具可以让大型项目更容易保持组织。它们还帮助您遵循自己的项目约定,而不必手动记住每一步。
编辑器组件
有时,您希望将游戏逻辑与编辑器逻辑混合。例如,您可能想要将一个组件附加到实体,该组件还运行编辑器逻辑,例如,显示调试信息或一个表示敌人移动或攻击范围的调试球。在这种情况下,您将使用 cave.EditorComponent,而不是 cave.Component。
这在实体需要特殊的编辑器行为时非常有用,但这种行为不应成为实际游戏的一部分。
例如:
- 一个出生点可以在编辑器中绘制辅助信息。
- 一个触发体积可以暴露调试控制。
- 一个关卡标记可以验证其是否已正确配置。
重要的思路是,编辑器脚本用于制作游戏的工作流程。游戏脚本则用于游戏本身。
重要提示: 在这种情况下,行为与常规组件稍有不同,因为作为编辑器组件,它将具有一个编辑器更新方法,该方法将在编辑器运行而游戏不运行的每一帧被调用。但,最重要的区别是,这个组件实际上将被注册并初始化,并与实体一起启动,无论其是否处于播放模式。因此,如果您在这个组件的启动方法中放置逻辑,它将在播放模式之外被调用。
这可能潜在地危险,例如:如果您在编辑器组件的开始方法中放置一个逻辑,以获取场景中的所有实体并删除它们,那么您的游戏将在编辑器中以破坏性(无法撤销)方式完全删除。这不是一个故障,不是一个错误,这是设计如此工作的方式。因此请注意。
如果您希望以更安全的方式做到这一点,您可以使用 Python 代码组件,因为它确实具有编辑器更新方法,并且写入此编辑器更新不会影响编辑器中的开始和结束更新是否被调用(不会)。查看 Cave 创建的初始项目中的敌人,因为它使用 Python 代码组件在敌人周围绘制一个调试球,指示它可以游荡的半径。这是学习更多知识的好方法。
何时应该构建工具?
不要为每个小动作创建自定义工具。
当它解决真实的工作流程问题时,构建一个工具,例如:
- 您多次重复同一任务。
- 一个设置容易被遗忘。
- 一个场景需要验证。
- 设计师需要一个更清晰的界面来更改值。
- 原型需要快速调试按钮。
对于初学者来说,最好是先手动构建游戏对象。然后,一旦理解了步骤,您可以自动化无聊的部分。
您应该记住的内容
Cave 中的 Python 可同时用于游戏和编辑工具。
游戏脚本控制游戏运行时发生的事情。编辑器脚本帮助您在 Cave 编辑器中构建、检查、调试或组织项目。
您不需要编辑器工具来制作第一个游戏,但当您的项目开始增长时,它们是强大的。今天节省五分钟的小工具,可能在以后节省几个小时。