
打开命令行窗口后,将在下面看到类似屏幕截图的内容。 它基本上告诉您文件系统中的位置,仅此而已。

在我的情况下,当前用户名为theodorebendixson1,因此终端已打印出用户根目录的位置。
如果要查看当前目录中的目录和文件,只需键入“ ls”并按回车即可。 当我从根用户目录执行以下操作时,终端会打印出以下内容。

是的,我知道。 太乱了 我可以通过输入“ cd {directory name}”然后按回车键来浏览任何目录。 另请注意,如果要导航到的目录中有空格,则需要将该目录的名称括在引号中。
导航至计划将您的作品保存到“手工制作的英雄”的地方。 我已经将我放在Documents目录中。
要创建一个新目录,只需键入“ mkdir”,然后输入要创建的文件夹的名称。 然后键入“ cd”,然后键入新目录的名称以进入该目录。
实际上,您不需要从终端上设置项目。
我使用Finder设置了我的。 我只是在逐步引导您,以便您了解如何导航到项目目录以运行命令。 我们稍后将创建的构建脚本实际上是从命令行运行的,因此了解如何到达该位置非常重要。
另外,您可以通过键入“ cd ../”并按回车键来向后导航。
我的Handmade Hero文件夹结构如下所示

构建目录将包含构建脚本的输出,该脚本将成为游戏的可执行文件。 手工目录(小写)将包含代码,艺术品,文档以及基本上所有用于制作游戏的内容。
所有代码都将驻留在code目录中,这也是我们将运行负责构建游戏的shell脚本的位置。
该屏幕截图为您提供了一个引人入胜的提示,可以让您深入讨论下一个讨论点,即游戏的入口点。 所有程序都具有系统定义的入口点,即程序运行时操作系统调用的单个函数。
入口点函数的开始标志着程序的开始,当该函数返回时,程序将停止运行。 而已。 结束。
大多数面向消费者的程序都能够继续运行,因为主要功能包含某种循环,当应用程序打开时该循环会持续进行。 通常将其称为“运行循环”或“事件循环”。退出循环时,主功能完成,应用程序或游戏关闭。
在Mac OS上,特殊入口点功能具有以下签名(C)
int main( int argc, const char * argv []){}
如果创建的文件中包含此功能,然后让clang编译器构建该文件,则将制作一个可以在Mac上运行的程序。
打开Xcode并关闭初始弹出屏幕,并提供有关从何开始的建议(我们将从头开始做所有事情,因此不需要项目模板或类似的东西)。
现在转到文件菜单,然后选择新文件。

当您执行此操作时,您将获得一个包含数十亿个不同建议的屏幕。 我们将不使用任何建议的文件,因为其中没有任何文件表示Objective-C ++文件。
向下滚动到标题为“其他”的部分,然后选择“空”选项。 这实际上是创建一个纯简文本文件,您可以对其进行任何扩展(只是迅速指出您可以使用任何文本编辑器执行此操作-Xcode在这方面并不特殊)。

导航到项目文件夹中的代码目录,将文件命名为osx_main.mm,然后单击“创建”。

.mm文件扩展名告诉clang我们正在处理一个Objective-C ++文件,或者某个文件将在某些时候包含Objective-C和C ++代码的某种混合。
此时,您应该会在空白处看到一个带有一些行号的空白窗口,并且在角落处看到了Objective-C ++文件的名称。 您可以花大价钱在上面加上一些注释文本,以解释文件的作用。

您需要在此文件中插入游戏的入口点。 从上方复制并粘贴代码段。

现在,您有了一个程序,clang编译器将为您识别并构建该程序。 不幸的是,它什么也不会做,所以让我们给它一个简单的打印语句。
将以下代码复制到main函数的主体中。
printf(“手工制作的英雄成功完成跑步”);
这是一个简单的打印命令,可在游戏运行时在终端中显示一条消息。
很好,但是要使用print语句,您需要包括标准io库。
将以下内容复制并粘贴到您的主要功能上方。
#include
您的osx_main.mm文件应如下所示

甜! 现在,您已经可以编译一个主文件,并将其转换为在Mac上运行的简单程序。 来做吧。
打开终端,然后导航到手工制作的英雄项目文件夹中的code子目录。 因为它是最简单的,所以我们将从该目录进行第一个构建。
一旦安装了Xcode命令行工具,就应该能够运行clang命令并构建游戏。
在终端中输入以下命令,然后按回车键
铛-o手工osx_main.mm
那么,这是做什么的呢? 简而言之,它会编译osx_main.mm Objective-C ++文件,并将其转换为名为Handmade的可执行文件。 -o编译器选项告诉clang将可执行文件输出到当前目录中名为“ handmade”的文件中。
打开Finder并导航到手工制作的英雄项目文件夹中的代码目录。 您应该会看到一个名为Handmade的UNIX可执行文件。 双击它可以第一次运行您的游戏。

这个程序还没做很多,但是没关系。 您应该看到终端窗口打开,显示一条消息,然后退出。 恭喜! 您已经在Mac上从头开始构建了一个应用。
您可以像刚才一样继续从命令行构建游戏,但是采用这种方法有一些缺点。
首先,随着我们为不同平台添加更多的编译器和选项,您使用的build命令可能会更改。 最好有一种方法可以将所有构建命令和设置存储在一个文件中,您可以在每次构建游戏时都可以简单地运行它。
其次,您不想使用构建工件来破坏代码目录。 最好将构建结果存储在单独的文件夹中,从而在代码,资源和可执行文件之间建立清晰的分隔。
TL; DR-您想要某种构建系统来使您的生活更轻松。
如果您看过Day 1 Handmade Hero视频,您将知道Casey在构建系统时是特立独行的。 他不喜欢人们在构建项目的过程中投入过多的复杂性。 在他看来,构建项目本身就是一件繁琐的事情,可能会使您偏离最终目标-制作人们想要玩的游戏。
Casey不使用Makefile或任何精美的构建工具。 他使用一个简单的Windows批处理文件。
秉承“手工制作英雄”系列的精髓,我们将做与Casey等效的unix,这意味着我们将使用shell脚本 。
Shell脚本只是终端命令的集合,组织在一个文件中,因此您可以一次又一次地运行它。
您可以从Xcode制作Shell脚本。 只需转到File-> New File,像以前一样向下滚动到Other部分,然后选择Shell Script。

同样,系统将提示您输入文件名。 我命名为我的建筑。

这将在您的代码目录中创建一个名为build.sh的外壳脚本文件。 Xcode创建一个带有一些注释的默认模板,以帮助您入门。

在“手工制作的英雄”系列中,Casey首先为可执行文件输出创建目录。 他将其命名为构建目录,并将其放置在代码目录上方的两个文件夹中。
我们已经以这种方式设置了我们的项目文件夹,但是包含此说明也没有什么坏处。 这样,您可以删除构建文件夹,并且每次运行构建脚本时,它只会创建一个新文件夹。
要创建构建文件夹,请将以下命令添加到build.sh文件中
mkdir ../../build
您之前已经看过。 这只是建立目录的终端命令。 每个../代表在浏览文件夹的过程中向后退了一步。
这是使用相对路径完成的。 这意味着终端假定您要从当前所在的目录运行命令。 这与诸如“ theodorebendixson / Documents / Handmade”之类的绝对路径相对,该路径特定于我的系统,因此缺乏在任何计算机上运行的灵活性。
接下来,Casey使用push和popd终端命令使终端导航到构建目录,运行build命令,然后退出构建目录以返回到他来自的目录(在本例中为代码目录)。
如果您熟悉堆栈的概念,那么您就会知道推和弹出意味着什么。 您将构建目录放在堆栈的顶部,在其中进行一些工作,然后将其从堆栈的顶部移开,这意味着导航回到您来自的手工目录/代码目录。
在mkdir命令之后粘贴以下代码行,并确保第二行保持打开状态。 这就是构建命令的去向。
推../../buildpopd
凉。 您已经掌握了基本的设置。 您只需要在这两行之间包含实际的clang编译命令即可。
尽管我们使用的compile命令与我们刚用来构建程序的命令相似,但是由于我们是从build目录而不是code目录进行编译,因此存在一些细微的差异。
将以下命令粘贴在推入和弹出的行之间。
铛-g -o手工../handmade/code/osx_main.mm
让我解释一下区别。 在-o编译器选项之后,第一个对handmade的引用是指游戏可执行文件的名称和位置。 由于pushd命令已将我们导航到build文件夹,因此我们仅使用文件名,因为该文件名将保存在我们当前所在的文件夹中。
第二个手工标记表示clang希望在程序中找到主要入口点的位置。 同样,由于我们位于build文件夹而不是code文件夹中,因此我们需要导航到code文件夹以引用包含main函数的osx_main.mm文件。
您还将注意到,我添加了另一个编译器选项-g。 当使用-g时,您在告诉clang您希望在项目的输出中包括调试符号。 不用说,当您可以进入自己的代码并使用lldb之类的工具对其进行调试时,您作为游戏开发人员的生活将大大简化。
您还可以在build.sh脚本的顶部添加echo语句,以便在运行它时产生一些输出。 我的只是说“建立手工英雄”
您的build.sh现在应该看起来像这样

打开终端并导航到手作/代码目录。 在提示符下运行以下命令。
sh build.sh
您应该看到如下所示的终端输出

如果导航到项目的生成目录,则将看到手工可执行文件以及handmade.dSYM调试符号文件。

现在,您已经有了一个非常基本的构建系统设置。 我们会稍后再进行修改,但这是一个好的开始。
我们很有可能会回来修改它,使其与Xcode一起使用。 目前,我想向您展示调试游戏的最简单的老方法。 我们将从命令行使用lldb。
首先,使用终端导航到构建目录。 从那里,在终端中输入以下命令,然后按回车键。
lldb手工制作
您应该看到以下确认消息

这是在告诉lldb识别出要运行的应用程序,并且找到了相关的调试符号(还记得Handmade.dSYM文件吗?)。 现在您可以设置断点并运行游戏了。
lldb也已启动,这意味着您不再在终端中。 从现在开始输入的命令将被视为lldb命令。
现在是时候添加一个断点了。 在控制台(现在是lldb控制台)中键入以下命令。
断点设置osx_main.mm-第12行
第12行是我们的打印语句,因此调试器应在运行应用程序时就在此处停止。 这是您应该看到的输出。

现在让我们运行游戏,看看调试器是否在我们的断点处停止。 在控制台中输入以下命令,然后按回车键。
流程启动
由于您已经将手工定义为要lldb启动的过程,因此lldb知道启动游戏的主要功能并在您可能设置的任何断点处停止。 在我们的例子中,我们可以期望它停止在osx_main.mm的第12行
这是我运行此命令时在控制台中获得的输出

真好 lldb为我们提供了一些上下文信息,在它停止的地方输出了代码行。
现在我们处于调试器中,让我们做一些探索。 lldb可以显示当前正在运行哪些线程以及从何处调用正在执行的代码。
在lldb中键入以下命令。 它将列出游戏的当前活动执行线程。
线程列表
在我们的例子中,我们只有一个线程,并且它在断点处停止。 lldb输出应如下所示。

知道这很高兴,但我想了解一些更深的知识。 首先我们是如何到达主要功能的? 哪个程序负责调用我们的应用程序?
要找出答案,您需要运行回溯。 在lldb控制台中输入
线程回溯
这将显示所有当前活动的函数调用,也称为堆栈框架。

换句话说,这些是当前在某些时候正在执行的功能。
frame#0代表手工英雄的主要功能,但是frame#1呢? 什么是libdyld.dylib?
第1帧中的libdyld.start函数是调用到我们的主函数中的函数。 这是操作系统获取我们的代码所采用的途径。
libdyld.dylib是一个Mac OS系统库,负责启动应用程序并将程序加载到内存中。 您为Mac OS或iOS编写的每个应用程序都将从该库中调用。
现在,您可以开始查看所有这些如何作为一个内聚单元。 Mac OS运行libdyld.dylib,它将加载您的应用程序依赖的适当的库。 最后,一切准备就绪后,libdyld.dylib会调用应用程序的main函数。
您的应用程序运行了一段时间,完成后,控制权返回到libdyld.dylib,后者在退出自身之前进行了一些清理工作。
而已。 这就是Mac上的应用程序生命周期。
稍后,我们将在调试器中介绍更多内容。 目前,让我们结束调试过程,告诉调试器跳过断点并继续运行,从而使应用程序完成执行。
输入此命令以继续
线程继续
您应该看到与运行应用程序时看到的相同退出消息,而无需进行早期调试。

您可以通过输入以下命令来退出调试器
放弃
现在就这样。 如果您想查看第一天的源代码,只需访问本系列的公共Github存储库。
如果您发现此内容有价值,并且希望看到更多内容,可以在Patreon上进行支持。
任何数量的帮助。
也许您正在尝试打入游戏行业,或者您只是想成为一个更好的程序员。 在本地大学注册高级编程课程需要花费多少钱? 您可以为发布跨平台游戏的Unity许可证支付什么费用?
您几乎可以从那里看到的每个教程都是从一个谜团开始的。 您不知道构建系统如何工作。 您只需要使用它。 您不知道这个或那个框架如何解决您的问题。 您只需要使用它们。
我们在这里做的事情完全不同。 我们没有质疑现有系统的价值,而是质疑我们所看到的并从头开始构建更好的东西。 如果我们不了解它,我们会戳它并刺刺它,直到我们明白为止。
我会在业余时间免费进行100%的操作。 每一项贡献都有助于我微不足道地全职从事这项工作。 如果我能够通过这项工作来支持自己,那将释放出大量的内容,我认为这些内容将使我们所有人都变得更好。
所以这又是那个链接。 在Patreon上支持此内容。 感谢您的阅读,如果您学到了一些有价值的东西,请在下面评论。
如果您跟随YouTube手工英雄系列,您将在第一部视频的结尾。 下一篇文章将介绍第二视频中与Mac OS等效的内容,这意味着我们将设置一个基本的Mac OS运行循环并创建一个可绘制的窗口。
如有任何疑问,请留在下面。 我会尽力回应。 您也可以访问手工制作英雄论坛。 我知道那里有一些Mac OS用户正在研究他们的项目版本。
另外,如果您尚未预购Handmade Hero,我建议您这样做。 通常,YouTube或Internet上没有像这样的任何教育内容,我认为出色的工作值得您的支持。 该系列确实是独一无二的。
祝您好运,祝您开发游戏顺利!