嗨翻-C--第四版-一-

353 阅读1小时+

嗨翻 C# 第四版(一)

原文:zh.annas-archive.org/md5/aa741d4f28e1a4c90ce956b8c4755b7e

译者:飞龙

协议:CC BY-NC-SA 4.0

第一章:简介:如何使用本书

图片

这本书适合谁?

如果你能对所有以下问题回答“是”:

  1. 你想学习C#(并在学习过程中掌握一些游戏开发和 Unity 的知识)吗?

  2. 你喜欢摆弄吗?你是通过实践学习,而不仅仅是阅读学习吗?

  3. 你更喜欢有趣和刺激的对话,而不是干燥枯燥学术化的演讲吗?

这本书适合你。

谁应该避免阅读这本书?

如果你对以下任何一个问题回答“是”:

  1. 你更对理论感兴趣还是实践?

  2. 做项目和编写代码的想法让你感到无聊并有点焦躁吗?

  3. 害怕尝试不同的东西吗?你认为像开发这样严肃的主题需要一直很严肃吗?

你可能会考虑先尝试另一本书。

图片

我们知道你在想什么。

“这怎么可能是一本严肃的 C#编程书?”

“这些图形是怎么回事?”

“我真的可以通过这种方式学习吗?”

我们知道你的大脑在想什么。

你的大脑渴望新奇。它总是在搜索、扫描,等待一些不寻常的东西。它就是这样建立的,并且帮助你保持生机。

那么你的大脑会怎么处理所有例行、普通、正常的事情?它尽可能地阻止它们干扰大脑的真正工作——记录重要的事情。它不会费力保存无聊的事情;它们永远无法通过“这显然不重要”的过滤器。

你的大脑如何知道什么是重要的?假设你出去远足一天,老虎突然跳到你面前。你的头脑和身体会发生什么?

神经元发射。情绪高涨。化学物质激增

这就是你的大脑如何知道……

图片

这一定很重要!不要忘记它!

但想象一下,你在家里,或者在图书馆。这是一个安全、温暖、没有老虎的地方。你正在学习。为考试做准备。或者尝试学习一些你的老板认为会花费一周,最多十天的技术主题。

只有一个问题。你的大脑试图帮你一把。它试图确保这显然不重要的内容不会占用稀缺的资源。这些资源最好用来存储真正重要的东西。比如老虎。比如火灾的危险。比如你绝不应该在 Facebook 页面上发布那些“派对”照片。

而且没有简单的方法告诉你的大脑,“嘿,大脑,非常感谢你,但无论这本书有多无聊,我现在情绪上的震动有多少,我真的让你保留这些内容。”

图片图片

元认知:思考思维

如果你真的想学习,并且希望更快更深入地学习,请注意你的注意力如何分配。思考你的思维方式。学习你的学习方式。

大多数人在成长过程中并没有接受关于元认知或学习理论的课程。我们期望学习,但很少我们如何学习。

但我们假设如果你拿着这本书,你真的想学习如何在 C#中构建程序。而且你可能不想花很多时间在上面。如果你想要运用你在这本书中读到的内容,你需要记住你读到的内容。而为此,你必须理解它。为了从这本书,或任何书籍或学习经历中获得最大的收益,要对你的大脑负责。你的大脑对内容的反应。

窍门在于让你的大脑把你正在学习的新材料视为非常重要。对你的健康至关重要。和老虎一样重要。否则,你将面临一个持续战斗的局面,你的大脑会尽其所能防止新内容留下来。

图片

那么,你究竟如何让大脑把 C#看待得像饥饿的老虎呢?

有慢慢来的,单调乏味的方式,还有更快、更有效的方式。慢的方式是关于纯粹的重复。你显然知道,即使是最枯燥的话题,只要你不停地把同样的东西敲打到你的大脑里,你也学习和记住。通过足够的重复,你的大脑会说:“这并不感觉重要,但他们一遍又一遍地看着同样的东西,所以我想这一定很重要。”

更快的方法是进行任何增加大脑活动的活动,特别是不同类型的大脑活动。上一页的内容是解决方案的重要组成部分,它们都被证明能帮助你的大脑更好地运作。例如,研究表明,将文字置于它们所描述的图片中(而不是放在页面的其他位置,如标题或正文中)会让你的大脑试图理解文字和图片之间的关系,这会导致更多的神经元兴奋。更多的神经元兴奋 = 更多大脑注意到这是值得关注的事物,并有可能记录下来。

会话风格有助于人们更多关注,因为人们认为自己在进行对话,因为他们期望跟随并保持他们的一端。令人惊讶的是,你的大脑并不一定在乎这个“对话”是你和一本书之间的!另一方面,如果写作风格是正式和枯燥的,你的大脑会感知到与你在一个被动参与者的房间里上课时的感觉是一样的。没必要保持清醒。

但图片和会话风格只是开始。

这是我们所做的事情

我们使用了图片,因为你的大脑更适合视觉而不是文本。对于你的大脑来说,一张图片确实价值千言万语。当文本和图片共同工作时,我们将文本嵌入到图片中,因为你的大脑在文本在其所指的事物内部时更有效地工作,而不是在标题或文本中埋藏起来。

图片

我们使用了冗余性,以不同的方式和不同的媒体类型重复相同的内容,并涉及多种感官,以增加内容编码到大脑的多个区域的机会。

我们以意想不到的方式使用概念和图片,因为你的大脑更适合新奇感,并且我们使用带有一些情感内容的图片和想法,因为你的大脑更容易注意到情绪的生物化学。引发你感受到某种情感的事物更容易被记住,即使这种感觉只是一点幽默惊讶兴趣

我们采用了个性化的、对话式的风格,因为你的大脑在认为你在进行对话而不是 passively listening to a presentation 时更容易集中注意力。即使在阅读时,你的大脑也会如此。

图片

我们包含了数十种活动,因为你的大脑更容易通过事情而不是阅读事情来学习和记忆更多内容。我们制作了难度适中但可行的纸上谜题和编程练习,因为大多数人更喜欢这样。

我们使用了 多种学习风格,因为可能更喜欢逐步的步骤,而其他人则希望先了解整体大局,还有人只是想看一个例子。但不论你的学习偏好如何,每个人都会因为以多种方式呈现相同内容而受益。

图片

我们包含了适合你大脑两侧的内容,因为你能够激活更多的大脑部位,学习和记忆的可能性更高,也能够保持更长时间的专注。因为经常激活一侧大脑意味着另一侧有机会休息,你在学习中可以更有效率更长时间。

并且我们包含了故事和练习,呈现多种观点,因为你的大脑在被迫做出评估和判断时更容易进行深入学习。

图片

我们包括了挑战,带有练习题,并提出了问题,这些问题并不总是有直接的答案,因为你的大脑被调整为在努力做某事时学习和记住。想想看——你不能仅仅通过在健身房看别人来使你的身体保持良好状态。但我们尽力确保当你努力工作时,你在做正确的事情。确保你不会因为难以理解的例子、难以解析的术语或过于简洁的文本而消耗额外的神经元。

我们使用了人物。在故事中、例子中、图片中等,因为,嗯,因为你是一个人。你的大脑对人物的关注比对事物的关注更多。

图片* *# 这里是你可以做的事情来驯服你的大脑

所以,我们做好了自己的部分。剩下的就看你了。这些技巧是一个起点;倾听你的大脑,找出对你有效和无效的东西。尝试新的事物。

图片

注意

把这个剪下来贴在你的冰箱上。

  1. 放慢速度。你理解得越多,需要记忆的就越少。

    不要只是阅读。停下来思考。当书问你一个问题时,不要直接跳到答案。想象有人真的在*问这个问题。你迫使大脑深入思考的程度越深,学习和记忆的机会就越大。

做练习题。写下你自己的笔记。

我们把它们放进去了,但如果我们替你做了,那就像是让别人帮你做锻炼一样。不要只是*看*练习题。**用铅笔写**。有足够的证据表明,在学习过程中进行体育活动可以增加学习效果。

**阅读“没有愚蠢问题”的部分。**

这意味着所有这些。它们不是可选的侧边栏——***它们是核心内容的一部分!***不要跳过它们。

+   **把这个作为你上床前最后阅读的东西。或者至少是最后的挑战性任务。**

学习的一部分(特别是长期记忆的转移)发生在你放下书后。你的大脑需要自己的时间进行更多的加工。如果在这段加工时间内添加了新内容,你刚学到的一些东西可能会丢失。

+   **喝水。大量喝水。**

你的大脑在液体中的环境中效果最佳。脱水(在你感到口渴之前可能会发生)会降低认知功能。

+   **大声谈论它。**

说话会激活大脑的不同部分。如果你试图理解某事,或增加以后记忆的机会,大声说出来。更好的是,试着向别人大声解释。你会更快地学习,并可能会发现你在阅读时未曾意识到的想法。

+   **倾听你的大脑。**

注意你的大脑是否开始超负荷。如果发现自己开始浅尝辄止或者忘记刚读的内容,那么是休息时间了。一旦超过某个点,通过试图塞更多内容来学得更快,并可能会损害学习过程。

+   **感受一下。**

你的大脑需要知道这*很重要*。参与故事情节。为照片编写你自己的标题。对一句糟糕的笑话嘟囔,*总比一无所获好*。

** **多写代码!**

只有一种方法可以*真正*学会 C#,那就是**大量编写代码**。这正是本书的贯穿始终。编码是一种技能,要想掌握好它,就必须多加练习。每章都有练习题让你解决问题,千万不要只是跳过它们——很多学习过程都发生在解决问题时。如果卡住了,不要害怕**偷看解决方案**!我们每个练习都附上了解答,是有原因的:有时候小问题会让你卡住。但在查看解答之前,请尝试自己解决问题。确保在继续本书的下一部分之前,问题已经解决并且运行正常。

**# 自述

这是一次学习经历,而不是一本参考书。我们有意删除了所有可能妨碍你学习的内容。第一次阅读时,你需要从头开始,因为本书假设你已经看过并学习了某些内容。

这些活动是 必不可少 的。

这些谜题和活动不是附加内容;它们是本书核心内容的一部分。其中一些是为了帮助记忆,一些是为了理解,还有一些是为了帮助你应用所学的知识。不要跳过书面问题。 游泳谜题是唯一不必做的事情,但它们有助于让你的大脑思考复杂的逻辑谜题——而且绝对是加快学习过程的好方法。

图片

冗余是有意而重要的。

Head First 系列书籍的一个显著区别在于,我们希望你真正理解它。我们希望你完成本书时记住所学的东西。大多数参考书没有保持和回忆作为目标,但本书关注学习,因此你会看到一些相同的概念多次出现。

图片

做所有的练习!

我们写作本书时做出的一个重要假设是你想学习如何使用 C#进行编程。因此,我们知道你想马上动手,并且直接进入代码。我们通过在每章节中加入练习机会,为你提供了很多锻炼技能的机会。我们标记了一些为“动手来吧!”—当你看到这样的标记时,意味着我们将带领你完成解决特定问题的所有步骤。但当你看到带有跑鞋标志的练习时,这意味着我们留下了很大一部分问题让你自己解决,同时我们也提供了我们想到的解决方案。不要害怕查看解决方案——这不是作弊!但如果你首先尝试解决问题,你会学到更多。

我们还包括了本书中所有练习解决方案的源代码。你可以在我们的 GitHub 页面找到全部内容:github.com/head-first-csharp/fourth-edition

图片

“脑力挑战”问题没有答案。

对于其中一些问题,没有正确答案;对于其他问题,你决定你的答案是否正确是学习过程的一部分。在一些“脑力挑战”问题中,你会找到一些提示,指导你朝正确的方向前进。

图片

我们的目标是 C# 8.0、Visual Studio 2019 和 Visual Studio 2019 for Mac。

本书旨在帮助你学习 C#。微软的开发和维护 C#语言的团队发布了语言的更新版本。C# 8.0 是本书生产期间的当前版本。我们也非常依赖 Visual Studio,微软的集成开发环境(IDE),作为学习、教学和探索 C#的工具。本书中的截图是使用生产时可用的Visual Studio 2019 及其 Mac 版最新版本进行的。我们在#开始使用 C#构建项目中提供了安装 Visual Studio 的说明,以及在Visual Studio for Mac 学习指南附录中提供了安装 Visual Studio for Mac 的说明。

我们正处于即将发布的 C# 9.0 的前夕。它带来了一些很棒的新功能!本书核心学习的 C#特性将保持不变,因此你可以在未来的 C#版本中使用本书。微软维护 Visual Studio 和 Visual Studio for Mac 的团队定期发布更新,极少情况下这些更改会影响本书中的截图。

本书中的 Unity 实验室部分针对Unity 2020.1,这是本书生产期间可用的最新版本。我们在第一个 Unity 实验室中提供了安装 Unity 的说明。

技术审查团队

图片

丽莎·凯尔纳

图片

林赛·比达

图片

Tatiana Mac

图片

Ashley Godbold

虽然没有图片(但同样了不起的是)来自第三版和第二版的审稿人:Rebeca Dunn-Krahn、Chris Burrows、Johnny Halife 和 David Sterling。

第一版的作者还包括:Jay Hilyard、Daniel Kinnaer、Aayam Singh、Theodore Casser、Andy Parker、Peter Ritchie、Krishna Pala、Bill Meitelski、Wayne Bradney、Dave Murdoch,特别是 Bridgette Julie Landers。

特别感谢我们的优秀读者们——特别是 Alan Ouellette、Jeff Counts、Terry Graham、Sergei Kulagin、Willian Piva 和 Greg Combow——他们在阅读我们的书时发现了问题,并且感谢 Mohawk College 的 Joe Varrasso 教授早早采纳了我们的书作为他的课程教材。

非常感谢大家!!

“如果我看得更远,那是因为我站在巨人的肩膀上。” – 艾萨克·牛顿

您正在阅读的这本书几乎没有任何错误,这要归功于我们杰出的技术审稿团队——这些善良的巨人们借给了我们他们的肩膀。对审阅团队:我们对你们所做的工作感激不尽。非常感谢!

Lindsey Bieda 是一名居住在宾夕法尼亚州匹兹堡的软件工程师。她拥有的键盘可能比任何人都多。在她不编码时,她喜欢与她的猫 Dash 一起玩耍和喝茶。她的项目和碎碎念可以在 rarlindseysmash.com 找到。

Tatiana Mac 是一位独立的美国工程师,直接与组织合作,建立清晰而一致的产品和设计系统。她相信无障碍、性能和包容的三位一体可以在数字和物理社交景观中共同改善。当她关注伦理时,她认为技术人员可以解构排斥性系统,支持面向社区的包容系统。

注意

在这件事上我们完全同意 Tatiana 的观点!

Ashley Godbold 是一位程序员、游戏设计师、作家、艺术家、数学家、教师和妈妈。她全职担任大型零售商的软件工程教练,并经营一家小型独立游戏工作室 Mouse Potato Games。她是 Unity 认证讲师,教授计算机科学、数学和游戏开发课程。她著有《掌握 Unity 2D 游戏开发(第二版)》和《掌握 Unity UI 开发》,并创作了名为《Unity 2D 游戏编程》和《入门 Unity 2D 游戏开发》的视频课程。

我们还特别要感谢 Lisa Kellner ——这已经是她为我们审阅的第 12 本书了。非常感谢你!

我们还要特别感谢Joe AlbahariJon Skeet,因为他们在第一版的技术指导和仔细周到的审查方面给予了不可思议的支持,这确实为我们多年来与这本书取得的成功打下了基础。我们从您的建议中受益匪浅——事实上,比当时我们意识到的要多得多。

致谢

我们的编辑:

首先和最重要的是,我们要感谢我们了不起的编辑Nicole Taché,感谢你为这本书所做的一切。你为我们完成这本书出版作出了巨大贡献,并给出了大量宝贵的反馈。非常感谢你!

Nicole Taché

图像

O’Reilly 团队:

Katherine Tozer

图像

我们想要感谢 O’Reilly 的许多人,希望我们没有遗漏任何人。首先、最后,也永远如此,我们要感谢Mary Treseler,她从最初就与我们一同在 O’Reilly 的旅程中。特别感谢制作编辑Katherine Tozer,索引员Joanne Sprott,以及Rachel Head的锐利校对——他们所有人都帮助我们在创纪录的时间内将这本书从生产到印刷。衷心感谢Amanda QuinnOlivia MacDonaldMelissa Duffield,因为他们在推动整个项目进展中起到了关键作用。还要向我们在 O’Reilly 的其他朋友大声致敬:Andy OramJeff BleielMike Hendrickson,当然还有Tim O’Reilly。如果你现在正在阅读这本书,那么你可以感谢业内最佳的宣传团队:Marsee HenonKathryn Barrett,以及 Sebastopol 的其他出色人士。

我们还要向一些我们喜爱的 O’Reilly 作者们表示敬意:

  • Dr. Paris Buttfield-AddisonJon ManningTim Nugent,他们的书Unity Game Development Cookbook简直令人惊叹。我们急切期待来自 Paris 和 Jon 的Head First Swift

  • Joseph AlbahariEric Johannsen,他们撰写了不可或缺的C# 8.0 in a Nutshell

最后...

非常感谢Cathy Vice(Indie Gamer Chick 的知名人物),因为她在我们的书中使用了关于癫痫的惊人文章,在癫痫倡导方面做出了很大贡献。同时也要感谢 Patricia Aas,因为她在我们的 Code Kata 附录中使用了她关于学习 C# 作为第二语言的出色视频,并且对如何帮助高级学习者使用这本书给出了宝贵的反馈。

Jon Galloway

图像

谢谢我们的朋友们在微软的帮助非常大,在这本书中,你们的支持简直令人惊叹。我们非常感激来自 Visual Studio for Mac 团队的多米尼克·纳霍斯(恭喜有宝宝!),乔丹·马蒂森,和约翰·米勒,以及对于启动我们整个合作关系起到关键作用的科迪·拜尔。感谢大卫·斯特林对第三版的精彩审阅,以及伊莫·兰德沃斯帮助我们确定本版需要覆盖的主题。特别感谢马兹·托尔格森,C#语言的项目经理,在过去几年里给予我们的所有精彩指导和建议。你们都太棒了。

我们特别感谢为整本书提供了大量精彩 Blazor 项目代码的乔恩·加洛维。乔恩是.NET 社区团队的高级项目经理。他共同撰写了几本关于.NET 的书籍,帮助组织了.NET 社区直播,还共同主持了Herding Code播客节目。非常感谢你!

O’Reilly 在线学习

Images

40 多年来,O’Reilly Media 一直致力于为公司提供技术和商业培训、知识和洞察力,帮助它们取得成功。

我们独特的专家和创新者网络通过书籍、文章和我们的在线学习平台分享他们的知识和专业知识。O’Reilly 的在线学习平台提供即时访问的实时培训课程、深入学习路径、交互式编码环境,以及来自 O’Reilly 和 200 多家其他出版商的大量文本和视频。更多信息,请访问oreilly.com

第二章:用 C#开始构建:快速构建一些伟大的东西……

图片

想立即构建出色的应用程序吗?

使用 C#,你拥有一个现代编程语言和一个有价值的工具在你的指尖。而且有了Visual Studio,你拥有一个令人惊叹的开发环境,具有高度直观的功能,使编码变得尽可能简单。Visual Studio 不仅是一个编写代码的好工具,它还是一个探索 C#的非常有价值的学习工具。听起来吸引人吗?翻页吧,让我们开始编码吧。

为什么你应该学习 C#

C#是一种简单、现代的语言,让你可以做很多令人惊讶的事情。当你学习 C#时,你不仅仅是在学习一门语言。C#为你打开了整个.NET 世界,这是一个非常强大的开源平台,可以构建各种应用程序。

Visual Studio 是你进入 C#的门户

如果你还没有安装 Visual Studio 2019,现在就是时候了。访问visualstudio.microsoft.com下载 Visual Studio Community 版。(如果已经安装,请运行 Visual Studio Installer 更新已安装的选项。)

注意

确保你正在安装 Visual Studio,而不是安装 Visual Studio Code。

Visual Studio Code 是一个了不起的开源跨平台代码编辑器,但它没有像 Visual Studio 那样专门针对.NET 开发。这就是为什么我们可以在本书中始终使用 Visual Studio 作为学习和探索的工具。

如果你在 Windows 上……

确保选中安装支持.NET Core 跨平台开发和.NET 桌面开发的选项。但不要勾选使用 Unity 进行游戏开发选项——稍后在本书中你将会进行 Unity 的 3D 游戏开发,但你需要单独安装 Unity。

图片

如果你在 Mac 上……

下载并运行 Visual Studio for Mac 安装程序。确保勾选.NET Core 目标。

图片

注意

你也可以在 Windows 上进行 ASP.NET 项目!只需在安装 Visual Studio 时确保勾选“ASP.NET 和 Web 开发”选项。

本书中大多数项目都是.NET Core 控制台应用程序,在 Windows 和 Mac 上都可以运行。一些章节有特定项目——比如本章后面的动物匹配游戏——这些是 Windows 桌面项目。对于这些项目,请使用 ASP.NET Core Blazor 项目附录。它提供了一个完整替代的#start_building_with_chash_build_somethin,以及其他 WPF 项目的 ASP.NET Core Blazor 版本。

Visual Studio 是一个编写代码和探索 C#的工具

你可以使用记事本或其他文本编辑器编写你的 C#代码,但有更好的选择。一个集成开发环境(IDE)——简称集成开发环境——是一个文本编辑器、视觉设计工具、文件管理器、调试器……它就像是一个多功能工具,可以满足你编写代码的所有需求。

这些只是 Visual Studio 帮助您完成的一些事情:

  1. 快速构建应用程序。 C# 语言灵活且易学,Visual Studio IDE 通过自动完成大量手动工作,使其更容易。以下是 Visual Studio 为您做的一些事情:

    • 管理您所有的项目文件

    • 使得编辑项目代码变得更加容易

    • 管理项目的图形、音频、图标和其他资源

    • 通过逐行调试来帮助你调试代码

      图片

  2. 设计一个外观出色的用户界面。 Visual Studio IDE 中的可视化设计器是其中一个最易于使用的设计工具。它为您做了很多工作,以至于您会发现为您的程序创建用户界面是开发 C# 应用程序中最令人满意的部分之一。您可以构建完整功能的专业程序,而无需花费数小时调整用户界面(除非您愿意)。

  3. 构建视觉上令人惊叹的程序。 当您结合 C# 和 XAML,用于设计 WPF 桌面应用程序用户界面的视觉标记语言时,您正在使用最有效的工具之一来创建视觉程序…… 您将使用它来构建看起来既好看又能正常运行的软件。

    注意

    如果您使用的是 Visual Studio for Mac,您将构建相同外观的应用程序,但是不是使用 XAML,而是通过将 C# 与 HTML 结合使用。

    注意

    Visual Studio 是一个令人惊叹的开发环境,但我们也将把它作为一个学习工具来探索 C#。

    注意

    任何 WPF 的用户界面(或UI)都是使用 XAML 构建的(XAML 代表可扩展应用标记语言)。Visual Studio 让使用 XAML 变得非常容易。

  4. 学习和探索 C# 和 .NET。 Visual Studio 是一个世界级的开发工具,但幸运的是,它也是一个很棒的学习工具。我们将使用 IDE 探索 C#,这让我们快速掌握重要的编程概念*。

    注意

    在本书中我们经常将 Visual Studio 简称为“IDE”。

在 Visual Studio 中创建您的第一个项目

学习 C# 最好的方法是开始编写代码,所以我们将使用 Visual Studio 创建一个新项目……并立即开始编写代码!

  1. 创建一个新的控制台应用程序 (.NET Core) 项目。

    启动 Visual Studio 2019。当它首次启动时,会显示一个“创建新项目”的窗口,其中有几个不同的选项。选择创建一个新项目。如果您关闭了该窗口也不必担心——您可以通过选择“文件”>>“新建”>>“项目”来随时再次打开它。

    图片

    点击控制台应用程序 (.NET Core)项目类型,然后点击下一步按钮。

    图片

    将项目命名为MyFirstConsoleApp,然后点击创建按钮。

    图片

    注意

    如果您使用的是Visual Studio for Mac,本项目的代码——以及本书中的所有.NET Core 控制台应用程序项目——都将是相同的,但一些 IDE 功能将会有所不同。请参阅 Visual Studio for Mac 学习指南 附录,以获取本章的 Mac 版本。

  2. 查看您的新应用程序的代码。

    当 Visual Studio 创建一个新项目时,它会为您提供一个可以构建的起点。一旦完成为应用程序创建新文件,它应该会打开一个名为Program.cs的文件,并显示以下代码:

    图片

  3. 运行你的新应用。

    Visual Studio 为您创建的应用程序已经准备就绪。在 Visual Studio IDE 的顶部找到带有绿色三角形和您的应用程序名称的按钮,然后单击它:

    图片

  4. 查看您程序的输出。

    当您运行程序时,Microsoft Visual Studio 调试控制台窗口将弹出并显示程序的输出:

    图片

学习一门语言的最佳方式是大量编写代码,所以你将在本书中构建许多程序。其中许多将是.NET Core 控制台应用项目,所以让我们仔细看看你刚刚做了什么。

窗口顶部是程序的输出

Hello World!

然后有一个换行,接着是一些额外的文字:

C:\*path-to-your-project-folder*\MyFirstConsoleApp\MyFirstConsoleApp\bin\Debug\
netcoreapp3.1\MyFirstConsoleApp.exe (process *####*) exited with code 0.
To automatically close the console when debugging stops, enable Tools->
Options->Debugging->Automatically close the console when debugging stops.
Press any key to close this window . . .

您将在每个调试控制台窗口的底部看到相同的消息。您的程序打印了一行文本(**Hello World!**),然后退出。Visual Studio 会保持输出窗口打开,直到您按键关闭它,以便在窗口消失之前查看输出。

按下一个键来关闭窗口。然后再次运行您的程序。这是您在整本书中构建的所有.NET Core 控制台应用程序的运行方式。

让我们来构建一个游戏!

您已经构建了您的第一个 C#应用程序,这太棒了!现在您已经做到了,让我们构建一些稍微复杂的东西。我们将构建一个动物匹配游戏,玩家将看到一个包含 16 只动物的网格,并需要点击成对的动物使它们消失。

图片

注意

WPF 项目的 Mac 版本使用 ASP.NET Core。您也可以在 Windows 上构建 ASP.NET Core 项目。

您的动物匹配游戏是一个 WPF 应用程序。

如果您只需要输入和输出文本,控制台应用非常适合。如果您想要一个显示在窗口中的可视应用程序,则需要使用不同的技术。这就是为什么您的动物匹配游戏将是一个WPF 应用。WPF(或 Windows Presentation Foundation)允许您创建可以在任何 Windows 版本上运行的桌面应用程序。本书的大多数章节将包含一个 WPF 应用程序。这个项目的目标是介绍 WPF,并为您提供构建视觉上令人惊叹的桌面应用程序以及控制台应用程序的工具。

完成这个项目时,你将更加熟悉在本书中学习和探索 C#所依赖的工具。

这是您将构建游戏的方式

本章的其余部分将引导您逐步构建动物匹配游戏,您将分阶段完成:

  1. 首先,您将在 Visual Studio 中创建一个新的桌面应用程序项目。

  2. 然后您将使用 XAML 来构建窗口。

  3. 你将编写 C# 代码,向窗口添加随机动物表情符号。

  4. 游戏需要让用户点击一对表情符号以进行匹配。

  5. 最后,通过添加计时器使游戏变得更加刺激。

注意

这个项目可能需要 15 分钟到一小时不等,具体取决于您的输入速度。我们在不感到匆忙的情况下学得更好,所以请给自己充足的时间。

图片

注意

请注意在整本书中散布的“游戏设计……及以上”元素。我们将使用游戏设计原则作为学习和探索重要编程概念和想法的方法,这些概念和想法适用于任何类型的项目,而不仅仅是视频游戏。

在 Visual Studio 中创建一个 WPF 项目

继续启动 Visual Studio 2019 的新实例并创建一个新项目:

注意

我们已经完成了您在本章开头创建的控制台应用程序项目,因此可以随时关闭该 Visual Studio 实例。

图片

我们将构建我们的游戏作为一个使用 WPF 的桌面应用程序,因此**选择 WPF 应用程序(.NET Core)**并点击“下一步”:

图片

Visual Studio 将要求你配置你的项目。将项目名称设为 MatchGame(如果愿意,也可以更改位置以创建项目):

图片图片

点击“创建”按钮。Visual Studio 将创建一个名为 MatchGame 的新项目。

Visual Studio 为您创建了一个项目文件夹,其中包含许多文件

一旦您创建了新项目,Visual Studio 就会添加一个名为 MatchGame 的新文件夹,并填充所有项目所需的文件和文件夹。您将对其中的两个文件 MainWindow.xamlMainWindow.xaml.cs 进行更改。

图片

如果您在此项目中遇到任何问题,请访问我们的 GitHub 页面并查找指向视频演示的链接:github.com/head-first-csharp/fourth-edition

调整您的 IDE 以匹配下面的屏幕截图。首先,通过在“解决方案资源管理器”窗口中双击打开 MainWindow.xaml,然后从“视图”菜单中选择 工具箱错误列表 窗口。您实际上可以根据它们的名称和常识来了解许多这些窗口和文件的用途!花点时间并填写每个空白处——试着填写有关 Visual Studio IDE 的每个部分的说明。我们已经开始了一个示例来帮助您入手。看看您是否能对其他部分进行合理猜测。

图片

图片 磨尖你的铅笔解决方案

我们已经填写了关于 Visual Studio C# IDE 不同部分的注解。你可能写下了一些不同的东西,但希望你能够理解每个窗口和 IDE 部分的基本用途。如果你的答案与我们略有不同,不要担心!你将有很多机会练习使用 IDE。

还有一个快速提醒:我们将在本书中——包括本页——交替使用“Visual Studio”和“IDE”这两个术语。

图片图片

使用 XAML 设计你的窗口

现在 Visual Studio 已经为你创建了一个 WPF 项目,是时候开始使用XAML了。

XAML 代表可扩展应用程序标记语言,这是一种非常灵活的标记语言,C#开发人员用来设计用户界面。你将使用两种不同类型的代码构建应用程序。首先,你将使用 XAML 设计用户界面(UI)。然后,你将添加 C#代码来使游戏运行。

如果你曾经使用 HTML 设计网页,那么你会发现 XAML 有很多相似之处。这里是一个在 XAML 中布局小窗口的快速示例:

图片

当 WPF 渲染(或在屏幕上绘制)这个窗口时,它看起来像这样。它绘制了一个窗口,有两个可见的控件,一个显示文本的 TextBlock 控件和一个用户可以点击的 Button 控件。它们使用不可见的 StackPanel 控件布局,导致它们在彼此之上渲染。看一下窗口截图中的控件,然后回到 XAML,找到TextBlockButton标签。

图片

设计你的游戏窗口

你需要一个具有图形用户界面的应用程序,用来使游戏运行,还需要一个可执行文件来运行。听起来工作量很大,但是在本章的其余部分,你将完成所有这些,并且最终,你将能够熟练使用 Visual Studio 设计出漂亮的 WPF 应用程序。

这是我们将要创建的应用程序窗口的布局:

图片

使用 XAML 属性设置窗口大小和标题

让我们开始为你的动物配对游戏构建用户界面。你要做的第一件事是让窗口变窄并更改其标题。你还将熟悉 Visual Studio 的 XAML 设计器,这是一个用于为应用程序设计出漂亮用户界面的强大工具。

  1. 选择主窗口。

    双击解决方案资源管理器中的MainWindow.xaml

    图片

    一旦这样做,Visual Studio 将在 XAML 设计器中打开它。

    图片

  2. 改变窗口的大小。

    将鼠标移到 XAML 编辑器,并点击 XAML 代码的前八行中的任意位置。一旦你这样做,你应该看到窗口的属性显示在属性窗口中。

    展开布局部分,将宽度更改为 400。设计窗格中的窗口会立即变窄。仔细看 XAML 代码 —— 现在宽度属性是 400。

    图片

  3. 更改窗口标题。

    Window 标签的末尾找到这行 XAML 代码:

    Title="MainWindow" Height="450" Width="400">
    

    并将标题更改为 查找所有匹配的动物,使其看起来像这样:

    Title="Find all of the matching animals" Height="450" Width="400">
    

    您将在属性窗口的常见部分看到更改 —— 更重要的是,窗口的标题栏现在显示新文本。

当您修改 XAML 标记中的属性时,更改会立即显示在属性窗口中。当您使用属性窗口修改 UI 时,IDE 会更新 XAML。

图片

向 XAML 网格添加行和列

或许看起来你的主窗口是空的,但是仔细看看 XAML 底部。注意到有一个带有 <Grid> 的行,后面是一个带有 </Grid> 的行?你的窗口实际上有一个 grid —— 只是因为它没有任何行或列而看不见。让我们继续添加一行。

将鼠标移动到设计器窗口的左侧。当光标上出现加号时,点击鼠标以添加一行。

注意

你的 WPF 应用程序的 UI 是由按钮、标签和复选框等控件构建的。网格是一种特殊的控件 —— 被称为容器 —— 它可以包含其他控件。它使用行和列来定义布局。

图片

您将看到一个数字后跟一个星号,并且窗口上出现了一条水平线。您刚刚在网格中添加了一行!现在添加行和列:

  • 重复四次以添加总共五行。

  • 将鼠标悬停在窗口顶部并点击以添加四列。您的窗口应该看起来像下面的屏幕截图(但您的数字可能不同 —— 没关系)。

图片

注意

这些“注意事项”元素提醒您关于重要但通常令人困惑的事项,可能会使您出错或减慢速度。

使行和列大小相等

当我们的游戏显示玩家要匹配的动物时,我们希望它们均匀间隔。每个动物都将包含在网格中的单元格中,而网格将根据窗口的大小自动调整大小,因此我们需要所有行和列的大小相同。幸运的是,XAML 让我们非常容易调整行和列的大小。单击 XAML 编辑器中的第一个 RowDefinition 标签,以在属性窗口中显示其属性:

图片

转到属性窗口,并点击右侧的方形到 Height 属性,然后从弹出菜单中选择重置。等等,等一下!当您这样做时,设计师中的行消失了。好吧,实际上,它并没有完全消失——它只是变得非常窄。继续为所有行重置 Height 属性。然后为所有列重置 Width 属性。您的网格现在应该有四个大小相等的列和五个大小相等的行。

图片图片

将一个 TextBlock 控件添加到您的网格中

WPF 应用程序使用TextBlock 控件来显示文本,我们将使用它们来显示要查找和匹配的动物。让我们在窗口中添加一个。

在工具箱中展开 Common WPF Controls 部分,将一个 TextBlock 拖放到第二列第二行的单元格中。IDE 将在Grid开始和结束标签之间添加一个TextBlock标记:

<TextBlock Text="*TextBlock*"
   HorizontalAlignment="*Left*" VerticalAlignment="*Center*"
   Margin="*560,0,0,0*" TextWrapping="*Wrap*" />

这个 TextBlock 的 XAML 具有五个属性:

  • Text 告诉 TextBlock 在窗口中显示什么文本。

  • HorizontalAlignment 将文本左对齐、右对齐或居中。

  • VerticalAlignment 将其对齐到其框的顶部、中部或底部。

  • Margin 设置其与其容器顶部、侧面或底部的偏移量。

  • TextWrapping 告诉它是否添加换行符以包装文本。

图片

你的属性可能以不同的顺序排列,并且 Margin 属性将具有不同的数字,因为它们取决于您在单元格中拖动的位置。所有这些属性都可以使用 IDE 的属性窗口进行修改或重置。

我们希望每个动物都居中。单击设计师中的标签,然后转到属性窗口并单击图片来展开布局部分。点击水平和垂直对齐属性的中心,然后使用窗口右侧的方形重置 Margin 属性

图片

我们还希望动物更大,因此在属性窗口中展开 Text 部分并将字体大小更改为36 px。然后转到 Common 部分,并将 Text 属性更改为?以显示问号。

图片

点击属性窗口顶部的搜索框,然后键入单词wrap以查找匹配的属性。使用窗口右侧的方形来重置 TextWrapping 属性。

图片图片

注意

您将在整本书中看到许多这样的练习。它们为您提供了锻炼编码技能的机会。并且查看解决方案总是可以的!

图片

现在,您可以开始为您的游戏编写代码了。

您已经完成了设计主窗口的工作——至少足够使您的游戏的下一部分开始运行。现在是时候添加 C#代码使您的游戏运行了。

图片

生成一个方法来设置游戏

现在用户界面已经设置好了,是时候开始为游戏编写代码了。您将通过生成一个方法(就像您之前看到的 Main 方法一样),然后向其中添加代码。

  1. 在编辑器中打开 MainWindow.xaml.cs。

    在解决方案资源管理器中单击 MainWindow.xaml 旁边的三角形 图片 ,然后双击 MainWindow.xaml.cs 以在 IDE 的代码编辑器中打开它。您会注意到该文件中已经有了一些代码。Visual Studio 将帮助您向其中添加一个方法。

    图片

  2. 生成一个名为 SetUpGame 的方法。

    找到您打开的代码的这一部分:

    注意

    如果您还不完全明白方法是什么,没关系。

    注意

    图片图片

    每当您看到灯泡图标时,它都在告诉您选择的代码有一个快速操作可用,这意味着 Visual Studio 可以为您自动化任务。您可以单击灯泡图标,或按 Alt+Enter 或 Ctrl+.(句号)来查看可用的快速操作。

  3. 尝试运行您的代码。

    点击 IDE 顶部的按钮启动程序,就像您之前在控制台应用程序中做的那样。

    图片

    哎呀,出了些问题。它没有显示窗口,而是抛出了一个异常

    图片

    看起来似乎有些东西出了问题,但这实际上正是我们预期会发生的!IDE 暂停了您的程序,并突出显示了最近运行的代码行。仔细看看它:

    throw new NotImplementedException();
    

    IDE 生成的方法确实告诉 C#抛出了一个异常。仔细看看异常消息:

    System.NotImplementedException: 'The method or operation is not implemented.'
    

    实际上这是有道理的,因为你需要实现这个方法,这是 IDE 生成的。如果你忘记实现它,异常会提醒你还有工作要做。如果你生成了很多方法,这种提醒就非常有用!

    在工具栏中点击方形的停止调试按钮 图片 (或者从调试菜单中选择停止调试(F5))以停止程序,这样您就可以完成实现 SetUpGame 方法的工作。

注意

当您使用 IDE 运行应用程序时,停止调试按钮会立即退出它。

完成您的 SetUpGame 方法

您将 SetUpGame 方法放在 public MainWindow() 方法中,因为该方法中的所有内容将在应用程序启动时立即调用。

注意

这是一个特殊的方法,称为构造函数,您将在 #encapsulation_keep_your_privateshellippr 中学习更多关于它的工作原理。

  1. 开始向 SetUpGame 方法添加代码。

    您的 SetUpGame 方法将获取八对动物表情字符,并将它们随机分配给 TextBlock 控件,以便玩家进行匹配。因此,您的方法首先需要这些表情符号的列表,IDE 将帮助您编写相关代码。选择 IDE 添加的 throw 语句,并将其删除。然后将光标放在该语句的位置,输入 List。IDE 将弹出一个以List开头的一堆关键字的 IntelliSense 窗口:

    图片

    从 IntelliSense 弹出窗口中选择 List。然后输入 <str —— 将会弹出另一个匹配关键字的 IntelliSense 窗口:

    图片

    选择 string。完成代码行的输入,但暂时不要按 Enter 键

    图片

  2. 向您的列表添加值。

    您的 C# 语句还没有完成。确保光标放在行末的 ) 后面,然后键入开括号 { —— IDE 将为您添加闭括号,并将光标放在两个括号之间。按 Enter 键 —— IDE 将自动为您添加换行:

    图片

  3. 完成您的方法。

    现在添加方法的其余部分 —— 要小心处理句点、括号和大括号:

    图片

    红色波浪线下的 mainGrid 表示 IDE 指出存在错误:因为在代码中找不到这个名称的任何东西,您的程序将无法构建。返回 XAML 编辑器,点击 <Grid> 标签,然后转到属性窗口,在名称框中输入 mainGrid

    检查 XAML —— 您将在网格顶部看到 <Grid x:Name="mainGrid">。现在您的代码中不应该有任何错误。如果有错误,请仔细检查每一行 —— 很容易漏掉一些细节。

    注意

    如果在运行游戏时出现异常,请确保 animalEmoji 列表中确实有 8 对表情符号,并且在您的 XAML 中有 16 个 <TextBlock ... /> 标签。

运行您的程序

点击 IDE 工具栏中的 图片 按钮以启动程序。一个窗口将弹出,显示您的八对动物在随机位置上的状态:

图片

当您的程序正在运行时,IDE 进入调试模式:开始按钮被灰色的“继续”按钮取代,工具栏中出现调试控制 图片,其中包括暂停、停止和重新启动程序的按钮。

通过点击窗口右上角的 X 按钮或调试控件中的方形停止按钮来停止程序运行。多次运行程序 —— 动物将每次都被重新排列。

图片图片

注意

您已为下一步骤做好了准备。

当你构建一个新的游戏时,你不仅仅是在写代码。你也在运行一个项目。一个非常有效的运行项目的方式是逐步构建它,沿途检查确保事情朝着正确的方向发展。这样你就有很多机会改变方向。

注意

这里有另一个纸笔练习。做完它们绝对是值得的,因为它们会帮助你更快地掌握重要的 C# 概念。

图片

注意

提高你的代码理解能力将使你成为一名更好的开发者。

纸笔练习是不可选的。它们让你的大脑以不同的方式吸收信息。但它们做的更重要的事情是给了你犯错误的机会。犯错误是学习的一部分,我们都犯了很多错误(甚至你可能在这本书中找到一两个错别字!)。没有人一开始就写出完美的代码——真正优秀的程序员总是假设他们今天写的代码明天可能需要改变。事实上,在本书的后面你会学到关于重构的内容,即在编写代码之后改进它的编程技术。

注意

我们将添加类似这样的项目总结,快速概述你迄今为止见过的许多想法和工具。

将你的新项目添加到源代码控制

在这本书中,你将会构建很多不同的项目。如果有一种简单的方式来备份它们并在任何地方访问它们,那将会多么棒!如果你犯了一个错误——如果你能够轻松地回滚到代码的早期版本,那不是非常方便吗?那么,你真是幸运!这正是 源代码控制 所做的事情:它为你提供了一种简单的方式来备份你所有的代码,并跟踪你所做的每一个更改。Visual Studio 让你可以轻松地将你的项目添加到源代码控制中。

Git 是一种流行的版本控制系统,Visual Studio 将会把你的源代码发布到任何一个 Git 仓库(或 repo)。我们认为 GitHub 是使用最简单的 Git 提供商之一。你需要一个 GitHub 账号来向其推送代码,所以如果你还没有账号,请立即访问 github.com 创建一个。

在 IDE 底部的状态栏中找到 添加到源代码控制

图片

点击它——Visual Studio 将提示你将代码添加到 Git 中:

图片

点击 Git。 Visual Studio 可能会提示你输入你的姓名和电子邮件地址。然后它应该在状态栏中显示如下内容:

图片

现在你的代码已经在源代码控制下。现在将鼠标悬停在 图片 上:

图片

IDE 告诉你有两个 提交 —— 或者说是你的代码的保存版本 —— 没有被推送到电脑外的位置。

当你将项目添加到源代码控制时,IDE 会在与 Solution Explorer 相同的面板中打开 Team Explorer 窗口。(如果看不到,请从“视图”菜单中选择。)Team Explorer 帮助你管理源代码控制。你将使用它来发布你的项目到 远程存储库

当你有本地更改时,你将使用 Team Explorer 将它们推送到远程存储库。为此,请在 Team Explorer 窗口中点击 发布到 GitHub 按钮。

图片

注意

Git 是一个开源的版本控制系统。像 GitHub 这样的多个第三方服务提供了 Git 服务(例如为代码提供存储空间和访问权限)。你可以访问 git-scm.com 了解更多关于 Git 的信息。

图片

注意

前往 github.com/head-first-csharp/fourth-edition 查看和下载本项目以及本书中所有其他项目的完整代码。

图片

下一个构建游戏的步骤是处理鼠标点击

现在游戏显示了供玩家点击的动物,我们需要添加使游戏运行的代码。玩家将按对点击动物。玩家首先点击的动物消失。如果玩家点击的第二个动物与第一个匹配,则第二个动物也消失。如果不匹配,则第一个动物重新出现。我们将通过添加一个 事件处理程序 来实现所有这些功能,这只是当应用程序中发生某些操作(如鼠标点击、双击、窗口调整大小等)时调用的方法的名称。

图片

使你的 TextBlocks 响应鼠标点击

你的 SetUpGame 方法会更改 TextBlocks 以显示动物表情符号,这样你就看到了你的代码如何修改应用程序中的控件。现在你需要编写反向操作的代码,即你的控件需要调用你的代码,而 IDE 可以帮助你。

返回到 XAML 编辑器窗口,点击第一个 **TextBlock** 标签 —— 这将导致 IDE 在设计器中选择它,以便你可以编辑其属性。然后转到属性窗口并点击事件处理程序按钮 (图片)。事件处理程序 是当应用程序发生特定事件时调用的方法。这些事件包括按键、拖放、窗口调整大小,当然还有鼠标移动和点击。滚动属性窗口并查看 TextBlock 可为其添加事件处理程序的不同事件名称。在名为 MouseDown 的事件右侧的框内双击。

图片

IDE 在 MouseDown 框中填写了一个方法名 TextBlock_MouseDown,并且 TextBlock 的 XAML 现在有了 MouseDown 属性:

<TextBlock Text="?" FontSize="36" HorizontalAlignment="Center" 
      VerticalAlignment="Center" MouseDown="TextBlock_MouseDown"/>

你可能没有注意到,因为 IDE 还向代码后台添加了一个新方法——即与 XAML 代码结合的代码——并立即切换到 C# 编辑器显示它。你可以通过在 XAML 编辑器中右键点击 TextBlock_MouseDown 并选择“查看代码”来随时跳转回去。这是它添加的方法:

图片

每当玩家点击 TextBlock 时,应用程序将自动调用 TextBlock_MouseDown 方法。现在我们只需要为其添加代码。然后我们需要连接所有其他 TextBlock,以便它们也调用它。

注意

事件处理程序是应用程序响应鼠标点击、键盘按键或窗口调整等事件时调用的方法。

添加 TextBlock_MouseDown 代码

现在你已经阅读了 TextBlock_MouseDown 的代码,是时候将其添加到你的程序中了。接下来要做的是:

  1. 在 IDE 为你添加的 TextBlock_MouseDown 方法的第一行之前,添加前两行代码,分别是 lastTextBlockClickedfindingMatch,确保将它们放在 SetUpGame 结束的右花括号和 IDE 刚刚添加的新代码之间。

  2. 填写 TextBlock_MouseDown 的代码。在等号(=)和双等号(==)之间要特别小心——这是你将在下一章中学到的一个重要区别。

在 IDE 中看起来是这样的:

图片

让其余的 TextBlock 调用同一个 MouseDown 事件处理程序

目前只有第一个 TextBlock 的 MouseDown 事件与事件处理程序关联。让我们也将其他 15 个 TextBlock 与它关联起来。你可以通过在设计器中选择每个文本块并在 MouseDown 旁边输入 TextBlock_MouseDown 来完成。我们已经知道这只是向 XAML 代码添加一个属性,所以让我们采取一种捷径。

  1. 选择 XAML 编辑器中的最后 15 个 TextBlock。

    转到 XAML 编辑器,在第二个 TextBlock 标签的左侧点击,然后向下拖动到 TextBlocks 的末尾,位于闭合 </``**Grid**``> 标签的上方。现在应该已选择了最后 15 个 TextBlock(但不包括第一个)。

  2. 使用快速替换添加 MouseDown 事件处理程序。

    从编辑菜单选择“查找和替换 >> 快速替换”。搜索 /> 并替换为 MouseDown="``*TextBlock_MouseDown*``"/>——确保在 MouseDown 前有一个空格,并且搜索范围是 选择,这样只会向选定的 TextBlock 添加属性。

    图片

  3. 对所有选定的 15 个 TextBlock 运行替换。

    点击“全部替换”按钮(图片)以向 TextBlocks 添加 MouseDown 属性——它应告诉你已替换了 15 处。仔细检查 XAML 代码,确保它们每个都有一个与第一个 TextBlock 中完全匹配的 MouseDown 属性。

    确保方法在 C# 编辑器中现在显示 16 个引用(选择“从构建菜单中构建解决方案”以更新它)。如果看到 17 个引用,则意外地将事件处理程序附加到了 Grid 上。绝对不要这样做——如果这样做,当您单击动物时会出现异常。

运行您的程序。现在,您可以点击动物对使它们消失。您点击的第一个动物将消失。如果您点击其匹配项,该项也将消失。如果点击一个不匹配的动物,则第一个动物将再次出现。当所有动物都消失时,请重新启动或关闭程序。

注意

当您看到脑力元素时,请花一分钟真正思考它所问的问题。

图片

通过添加一个计时器来完成游戏

如果玩家可以尝试打败他们的最佳时间,我们的动物匹配游戏将更加令人兴奋。我们将添加一个 计时器,它通过反复调用方法在固定时间间隔后“tick”。

图片

图片

计时器“tick”每次间隔调用方法。您将使用一个计时器,该计时器在玩家开始游戏时开始,并在匹配到最后一个动物时结束。

向您的游戏代码中添加一个计时器

  1. MainWindow.xaml.cs 文件的顶部附近找到 namespace 关键字,并在其下直接添加以下代码行:using System.Windows.Threading;

     namespace MatchGame
     {
        using System.Windows.Threading;
    
    注意

    添加这个!

  2. 找到 *public partial class MainWindow* 并在左花括号 **{** 后立即添加以下代码:

    public partial class MainWindow : Window
    {
        DispatcherTimer timer = new DispatcherTimer();
        int tenthsOfSecondsElapsed;
        int matchesFound;
    
    注意

    您将添加这三行代码来创建一个新的计时器,并添加两个字段来跟踪经过的时间和玩家找到的匹配数。

  3. 我们需要告诉我们的计时器多频繁“tick”,以及调用什么方法。在调用 SetUpGame 方法的行的开头点击,将编辑器的光标移动到那里。按 Enter 键,然后在下面屏幕截图中以 **timer.** 开头的两行代码:

    图片

  4. 按 Tab 键。IDE 将完成代码行并添加 Timer_Tick 方法:

    图片

  5. Timer_Tick 方法将更新一个跨越整个网格底部行的 TextBlock。以下是设置方法:

    • 将一个 TextBlock 拖放到左下方的正方形中。

    • 使用 Properties 窗口顶部的 Name box 为其命名为 **timeTextBlock.**

    • 重设其 margins,将其 居中 在单元格中,并将 FontSize 属性设置为 36px,Text 属性设置为“已经过时间”(就像您对其他控件所做的一样)。

    • 找到 ColumnSpan 属性并将其设置为 4。

    • 添加名为 TimeTextBlock_MouseDown 的 MouseDown 事件处理程序

      图片

    下面是 XAML 的外观,请仔细比较它与 IDE 中的代码:

    <TextBlock x:Name="*timeTextBlock* "Text="*Elapsed time*" FontSize="*36*"
        HorizontalAlignment="*Center*" VerticalAlignment="*Center*"
        Grid.Row="*4*" Grid.ColumnSpan="*4*" MouseDown="*TimeTextBlock_MouseDown*"/>
    
  6. 当你添加了 MouseDown 事件处理程序时,Visual Studio 在代码后台创建了一个名为 TimeTextBlock_MouseDown 的方法,就像其他的 TextBlock 一样。将以下代码添加到其中:

    private void TimeTextBlock_MouseDown(object sender, MouseButtonEventArgs e)
    {
        if (matchesFound == 8)
        {
            SetUpGame();
        }
    }
    
    注意

    如果已经找到了所有 8 对匹配项,这将重置游戏(否则不执行任何操作,因为游戏仍在运行)。

  7. 现在你已经拥有完成 Timer_Tick 方法所需的一切内容,该方法会更新新的 TextBlock,显示经过的时间,并在玩家找到所有匹配项后停止计时器:

    private void Timer_Tick(object sender, EventArgs e)
    {
        tenthsOfSecondsElapsed++;
        timeTextBlock.Text = (tenthsOfSecondsElapsed / 10F).ToString("0.0s");
        if (matchesFound == 8)
        {
            timer.Stop();
            timeTextBlock.Text = timeTextBlock.Text + " - Play again?";
        }
    }
    

    但这里有些不对劲。 运行你的代码……哎呀!你得到了一个异常

    我们即将修复这个问题,但首先要仔细查看 IDE 中的错误消息和突出显示的行。

    你能猜到是什么导致了这个错误吗?

图片

使用调试器来解决异常。

你可能之前听过“bug”这个词。你可能曾经在过去对你的朋友说过这样的话:“那个游戏真的很有 bug,有很多故障。”每个 bug 都有一个解释——你程序中的每件事都有原因——但并不是每个 bug 都容易追踪。

理解 bug 是修复 bug 的第一步。 幸运的是,Visual Studio 调试器是一个很好的工具。(这就是为什么它被称为调试器:它是帮助你摆脱 bug 的工具!)

  1. 重新启动你的游戏几次。

    首先要注意的是,你的程序总是抛出相同类型和相同消息的异常:

    图片

    如果将异常窗口移开,你会发现它总是停在同一行上:

    图片

    这个异常是可复现的:你可以可靠地使程序抛出完全相同的异常,并且你已经非常清楚问题所在。

  2. 在抛出异常的那一行添加断点。

    再次运行你的程序,使其在异常处中断。在停止它之前,从调试菜单中选择切换断点(F9)。一旦你这样做,该行将被标记为红色,并且左边的边距旁边将出现一个红点。现在再次停止你的应用程序 —— 突出显示和点仍将存在:

    图片

    你刚刚在该行上设置了断点。 现在每次执行该行代码时,你的程序都会中断。现在试一下。再次运行你的应用程序。程序将在该行处中断,但这次不会抛出异常。按继续。它再次在该行上中断。再次按继续。它又中断了。继续进行,直到看到异常。现在停止你的应用程序。

  3. 收集证据,以便找出问题的原因。

    当你运行应用程序时,是否在 Locals 窗口中注意到任何有趣的内容?重新启动它,并且非常注意 animalEmoji 变量。第一次应用程序中断时,你应该在 Locals 窗口中看到这个:

    图片

    按下继续。看起来计数从 16 减少到 15:

    图片

    应用程序将随机从animalEmoji列表中添加表情符号到 TextBlocks 中,然后从列表中移除它们,因此其计数每次应减少 1。一切顺利,直到animalEmoji列表为空(所以 Count 为 0),然后你会收到异常。所以这是一个证据!另一个证据是这发生在**foreach 循环**中。最后一个证据是这一切都是在我们向窗口添加一个新的 TextBlock 之后开始的

    是时候戴上你的福尔摩斯帽子了。你能找出是什么导致了异常吗?

  4. 找出实际导致错误的原因。

    你的程序崩溃的原因是它试图从animalEmoji列表中获取下一个表情符号,但列表为空,这导致它抛出 ArgumentOutOfRange 异常。是什么导致它耗尽了要添加的表情符号?

    在你最近做出最新更改之前,你的程序运行正常。然后你添加了一个 TextBlock…然后它停止工作了。就在遍历所有 TextBlock 的循环中。一个线索…非常非常有趣。

    图片

    因此,当你运行你的应用程序时,对于窗口中的每个 TextBlock,它都会在这一行中断。所以在前 16 个 TextBlock 中,一切都很顺利,因为集合中有足够的表情符号:

    图片

    但现在窗口底部有一个新的 TextBlock,它第 17 次崩溃了——由于**animalEmoji**集合中只有 16 个表情符号,现在它是空的:

    图片

    所以在你做出更改之前,你有 16 个 TextBlock 和一个包含 16 个表情符号的列表,所以刚好有足够的表情符号添加到每个 TextBlock 中。现在你有 17 个 TextBlock,但仍然只有 16 个表情符号,所以你的程序耗尽了要添加的表情符号…然后它抛出异常。

  5. 修复这个 bug。

    由于异常是因为在遍历 TextBlocks 的循环中我们正在耗尽 emoji,我们可以通过跳过我们刚刚添加的 TextBlock 来修复它。我们可以通过检查 TextBlock 的名称来做到这一点,并跳过显示时间的那个。再次切换以移除断点,或者从调试菜单中选择删除所有断点(Ctrl+Shift+F9)

    图片

添加剩余的代码并完成游戏

你还需要做一件事。你的 TimeTextBlock_MouseDown 方法检查 matchesFound 字段,但这个字段从未在任何地方设置过。因此,在 foreach 循环的右大括号后立即在 SetUpGame 方法中添加这三行代码:

             animalEmoji.RemoveAt(index);
          }
       }
       timer.Start();
       tenthsOfSecondsElapsed = 0;
       matchesFound = 0;
   }
注意

在 SetUpGame 方法的最后添加这三行代码,以启动计时器并重置字段。

然后在 TextBlock_MouseDown 的 if/else 的中间块中添加这个语句:

else if (textBlock.Text == lastTextBlockClicked.Text)
{
    matchesFound++;
    textBlock.Visibility = Visibility.Hidden;
    findingMatch = false;
}
注意

添加这行代码,每当玩家成功找到一对匹配项时,将 matchesFound 增加一。

现在你的游戏有一个计时器,当玩家完成匹配动物时停止计时,游戏结束时可以点击它再玩一次。你已经在 C#中构建了你的第一个游戏。恭喜!

图片

注意

github.com/head-first-csharp/fourth-edition 查看和下载本项目及本书中所有其他项目的完整代码。

在源代码控制中更新你的代码

现在你的游戏已经启动运行,现在是把你的更改推送到 Git 的绝佳时机,而 Visual Studio 使这一切变得非常简单。你只需要暂存你的提交,输入提交消息,然后同步到远程仓库。

图片

  1. 从提交下拉菜单中选择 提交已暂存项并同步(就在提交消息框的下面)。同步可能需要几秒钟时间,然后你会在 Team Explorer 窗口看到成功消息。

    图片

图片

每当你有一个大项目时,将其分解成更小的部分总是一个好主意。

你可以培养的最有用的编程技能之一是能够看待一个庞大而困难的问题,并将其分解为更小、更容易的问题。

在一个大项目开始时很容易感到不知所措,并想:“哇,这个项目真的好大啊!”但如果你能找到一个小片段可以开始工作,那么你就能够着手了。一旦完成了这个片段,你可以继续下一个小片段,然后是另一个,再然后是另一个。随着你构建每个片段,你会在项目进展中学到更多。

更好的条件语句……

你的游戏非常不错!但每个游戏——事实上,几乎每个程序——都可以改进。这里有一些我们认为可以使游戏变得更好的想法:

  • 添加不同种类的动物,这样每次显示的都不一样。

  • 记录玩家的最佳时间,以便他们可以尝试超越它。

  • 让计时器倒计时而不是计时上升,这样玩家就有限定的时间。

注意

我们是认真的——花几分钟时间去做这件事。退后一步,思考一下你刚刚完成的项目,这是将学到的经验教训牢固地印在你的大脑中的好方法。

注意

只是一个快速提醒:在本书中,我们会经常将 Visual Studio 称为“IDE”。

图片

第三章:深入 C#:语句、类和代码

图片

你不只是一个 IDE 用户。你是一个开发者**。**

使用 IDE 可以完成大量工作,但它的能力有限。Visual Studio 是有史以来最先进的软件开发工具之一,但强大的集成开发环境仅仅是一个开始。现在是时候深入研究 C# 代码了:它的结构是怎样的,它如何工作,以及如何掌控它……因为你可以让你的应用程序做任何事情,没有限制。

(顺便说一句,无论你喜欢哪种键盘,你都可以成为真正的开发者。唯一需要做的就是编写代码!)

让我们仔细查看控制台应用程序的文件。

在上一章中,你创建了一个名为 MyFirstConsoleApp 的新 .NET Core 控制台应用程序项目。这样做时,Visual Studio 创建了两个文件夹和三个文件。

图片

让我们仔细看看它创建的 Program.cs 文件。在 Visual Studio 中打开它:

图片

  • 文件顶部是一个 **using 指令**。在所有的 C# 代码文件中,你都会看到类似这样的 using 行。

  • using 指令之后就是 namespace 关键字。你的代码位于 MyFirstConsoleApp 命名空间中。紧接着是一个左花括号 **{**,文件的末尾是右花括号 **}**。在这些花括号之间的所有内容都属于这个命名空间。

  • 在命名空间内部是一个。你的程序有一个名为 Program 的类。在类声明之后是一个左花括号,与文件倒数第二行的右花括号成对出现。

  • 在你的类内部是一个名为 Main 的方法——同样是一对括号及其内容。

  • 你的方法只有一个语句Console.WriteLine("Hello World!");

一个语句执行一个单一动作。

每个方法都由像你的 Console.WriteLine 语句那样的语句组成。当程序调用一个方法时,它会依次执行每个语句,直到语句用完或者遇到一个 **return** 语句时结束,程序的执行会恢复到最初调用该方法的语句之后。

两个类可以在同一个命名空间(和文件)中。

看看 PetFiler2 程序的这两个 C# 代码文件。它们包含三个类:Dog 类、Cat 类和 Fish 类。由于它们都在同一个 PetFiler2 命名空间中,所以在 Dog.Bark 方法中可以调用 Cat.Meow 和 Fish.Swim 而无需添加 using 指令

图片

一个类也可以跨多个文件,但在声明时需要使用 partial 关键字。不管不同的命名空间和类如何分布在文件中,它们在运行时的行为都是相同的。

图片图片

IDE 帮助你正确构建代码。

很久以前,程序员们不得不使用简单的文本编辑器,如 Windows 记事本或 macOS TextEdit 来编辑他们的代码。事实上,一些他们的功能当时可能是尖端的(比如搜索和替换,或者记事本的 Ctrl+G 用于“转到行号”)。我们不得不使用许多复杂的命令行应用程序来构建、运行、调试和部署我们的代码。

多年来,微软(以及许多其他公司和许多个人开发者)找到了如何添加*许多*有用功能,如错误高亮显示、智能感知、所见即所得的点击拖放窗口 UI 编辑、自动生成代码等等。

经过多年的发展,Visual Studio 现在是有史以来最先进的代码编辑工具之一。幸运的是,它也是一个学习和探索 C#和应用开发的绝佳工具

语句是你的应用程序的构建块

你的应用由类组成,这些类包含方法,方法包含语句。所以,如果我们想要构建能做很多事情的应用程序,我们将需要一些不同类型的语句来使它们运行。你已经看到了一种类型的语句:

   Console.WriteLine("Hello World!");

这是一个调用方法的语句,具体来说是 Console.WriteLine 方法,它将一行文本打印到控制台。我们还将在本章和整本书中使用几种其他类型的语句。例如:

图片我们使用变量和变量声明让我们的应用存储和处理数据。
图片许多程序使用数学,所以我们使用数学运算符来加法、减法、乘法、除法等等。
图片条件语句让我们的代码在选择选项时执行一个代码块或另一个代码块。
图片循环让我们的代码重复执行相同的块,直到满足条件为止。

你的程序使用变量来处理数据

每个程序,无论大小,都与数据一起工作。有时数据是文档的形式,或者是视频游戏中的图像,或者是社交媒体更新,但它们都只是数据。这就是变量的用武之地。变量是程序用来存储数据的工具。

图片

声明你的变量

每当你声明一个变量时,你告诉你的程序它的*类型和它的名称*。一旦 C#知道你的变量类型,如果你尝试做一些毫无意义的事情,比如从48353中减去"Fido",它将生成错误并阻止你的程序构建。以下是声明变量的方式:

图片

每当你的程序需要处理数字、文本、真/假值或任何其他类型的数据时,你将使用变量来跟踪它们。

变量是可变的

一个变量在程序运行时会在不同的时间点等于不同的值。换句话说,变量的值变化。(这就是为什么“变量”是个好名字的原因。)这非常重要,因为这个想法是你将写的每个程序的核心。假设你的程序将变量myHeight设置为 63:

 int myHeight = 63;

在代码中出现myHeight时,C#将把它替换为它的值 63。然后,稍后,如果你将其值更改为 12:

 myHeight = 12;

C#将从那时起用 12 替换myHeight(直到再次设置)——但变量仍然称为myHeight

在使用变量之前,你需要为它们赋值。

尝试在你的新控制台应用程序的“Hello World”语句下方输入这些语句:

 string z;
 string message = "The answer is " + z;

快点!

现在就试试看。你会收到一个错误,IDE 将拒绝构建你的代码。这是因为它检查每个变量,确保在使用之前你已经为它赋了值。确保你不会忘记为变量赋值的最简单方法是将声明变量和赋值的语句结合起来:

图片

几个有用的类型

每个变量都有一个类型,告诉 C#它可以保存什么类型的数据。我们将详细讨论 C#中许多不同的类型,暂时我们将集中讨论三种最流行的类型。int保存整数(或整数),string保存文本,bool保存布尔值true/false。

注意

变量,名词。

一个很可能改变的元素或特征。如果气象学家不必考虑那么多变量,预测天气会容易得多。

如果你写了一个使用未赋值的变量的代码,你的代码将无法构建。通过将变量声明和赋值合并为一个语句,可以轻松避免此错误。

注意

一旦为变量赋了一个值,该值可以更改。因此,在声明变量时赋予一个初始值没有任何不利之处。

生成一个新的方法来处理变量

在上一章中,你学到了 Visual Studio 将为你生成代码。当你编写代码时,这是非常有用的,它也是一个非常宝贵的学习工具。让我们在你学到的基础上进一步学习并仔细看看生成方法。

快点!

  1. 在你的新的 MyFirstConsoleApp 项目中添加一个方法。

    打开上一章创建的控制台应用程序项目。IDE 创建了一个只有一个语句的 Main 方法:

    Console.WriteLine("Hello World!");
    

    替换这个语句来调用一个方法:

    OperatorExamples();
    
  2. 让 Visual Studio 告诉你哪里出错了。

    一旦你完成替换语句,Visual Studio 会在你的方法调用下绘制一条红色波浪线。将鼠标悬停在其上。IDE 将显示一个弹出窗口:

    图片

    Visual Studio 告诉您两件事情:有一个问题——您正在尝试调用一个不存在的方法(这将阻止您的代码构建)——以及它有一个潜在的修复方法。

  3. 生成 OperatorExamples 方法

    Windows 上,弹出窗口告诉您按下 Alt+Enter 或 Ctrl+. 来查看潜在的修复方法。在 macOS 上,它有一个 “显示潜在修复” 的链接——按 Option+Return 来查看潜在修复方法。所以,请继续按下其中任何一个键组合(或点击弹出窗口左侧的下拉菜单)。

    图像

    这个 IDE 提供了一个解决方案:它会在您的程序类中生成一个名为 OperatorExamples 的方法。点击“预览更改”显示一个窗口,其中包含 IDE 的潜在修复方案——添加一个新方法。然后点击“应用”将该方法添加到您的代码中。

添加使用运算符的代码到您的方法中

一旦您在变量中存储了一些数据,您可以做什么?如果它是一个数字,您可能想要添加或乘以它。如果它是一个字符串,您可能想要将它与其他字符串一起连接。这就是运算符发挥作用的地方。这里是您的新 OperatorExamples 方法的方法体。将此代码添加到您的程序,并阅读 **注释** 以了解它使用的运算符。

图像

private static void OperatorExamples()
{
  // This statement declares a variable and sets it to 3
  int width = 3;

  // The ++ operator increments a variable (adds 1 to it)
  width++;

  // Declare two more int variables to hold numbers and
  // use the + and * operators to add and multiply values
  int height = 2 + 4;
  int area = width * height;
  Console.WriteLine(area);

  // The next two statements declare string variables
  // and use + to concatenate them (join them together)
  string result = "The area";
  result = result + " is " + area;
  Console.WriteLine(result);

  // A Boolean variable is either true or false
  bool truthValue = true;
  Console.WriteLine(truthValue);
}
注意

字符串变量用于保存文本。当您使用 + 运算符连接字符串时,它们会被合并在一起,所以添加 “abc” + “def” 的结果是一个字符串 “abcdef” 。当您像这样连接字符串时,它被称为串联。

使用调试器观察您的变量变化

当您之前运行程序时,它是在 调试器 中执行的——这是一个非常有用的工具,用于理解您的程序如何工作。您可以使用 断点 在程序执行到达某些语句时暂停,并添加 监视 来查看变量的值。让我们使用调试器来看看您的代码运行情况。我们将使用调试器的这三个特性,您将在工具栏中找到:

图像

如果您进入一个您不期望的状态,只需使用重新启动按钮 (图像) 重新启动调试器。

就这样!

  1. 添加断点并运行您的程序。

    将鼠标光标放在您添加到程序 Main 方法中的方法调用上,并从调试菜单中选择 切换断点 (F9)。现在该行应该看起来像这样:

    图像

    注意

    Mac 上的调试快捷键是 Step Over (图像), Step In (图像), 和 Step Out (图像)。屏幕看起来可能有点不同,但调试器的操作方式完全相同,就像您在 Mac 学习指南 的 #start_building_with_chash_build_somethin 中看到的那样。

    然后按下 图像 按钮在调试器中运行程序,就像您之前所做的那样。

  2. 进入该方法。

    调试器在调用 OperatorExamples 方法的语句处停止。

    图片

    **按下 Step Into (F11) ——调试器会跳进方法,然后在执行第一条语句之前停下来。

  3. 检查 width 变量的值。

    当你 逐步执行代码 时,调试器在执行每条语句后会暂停。这使你有机会检查变量的值。将鼠标悬停在 width 变量上。

    图片

    IDE 显示一个弹出窗口,显示变量的当前值 ——目前为 0。现在 按下 Step Over (F10) ——执行跳过注释到第一个语句,该语句现在已突出显示。我们希望执行它,所以 再次按下 Step Over (F10)。再次悬停在 width 上。现在它的值为 3。

  4. Locals 窗口显示变量的值。

    你声明的变量是 局部 的,即它们只存在于该方法内部,并且只能被方法中的语句使用。当 Visual Studio 调试时,在底部的 IDE 中的 Locals 窗口显示它们的值。

    图片

  5. 为 height 变量添加 Watch。

    调试器的一个非常有用的功能是 Watch 窗口,通常与底部的 Locals 窗口在同一面板中。当你将鼠标悬停在变量上时,可以通过右键单击弹出窗口中的变量名称并选择添加 Watch 来添加 Watch。将鼠标悬停在 height 变量上,然后右键单击并选择 Add Watch 菜单。

    图片

    现在你可以在 Watch 窗口中看到 height 变量。

    图片

    调试器是 Visual Studio 中最重要的功能之一,它是理解程序运行方式的强大工具。

  6. 逐步执行方法的其余部分。

    逐步执行 OperatorExamples 中的每个语句。当你逐步执行方法时,注意 Locals 或 Watch 窗口,并观察值随着变化而变化。在 Windows 上,在 Console.WriteLine 语句之前和之后按下 Alt+Tab 切换到调试控制台查看输出。在 macOS 上,你会在终端窗口中看到输出,所以不需要切换窗口。

使用运算符处理变量

一旦你有了变量中的数据,你要怎么处理它?嗯,大多数时候你会希望你的代码根据这些值执行某些操作。这就是 等式运算符关系运算符逻辑运算符 变得重要的地方:

等式运算符

== 运算符比较两个值,如果它们相等则返回 true。

!= 运算符与 == 非常类似,不同之处在于比较的两个值不相等时返回 true。

关系运算符

使用 > 和 < 比较数字,查看一个变量中的数字是大于还是小于另一个变量中的数字。

你还可以使用>=来检查一个值是否大于或等于另一个,使用<=来检查它是否小于或等于另一个。

逻辑运算符

你可以使用&&运算符进行和||运算符进行将个别条件测试组合成一个长测试。

这里是如何检查i是否等于 3或者j是否小于 5 的方式:(i == 3) || (j < 5)

注意

使用运算符比较两个 int 变量

你可以通过使用比较运算符来检查变量的值进行简单测试。这是如何比较两个 int 变量 x 和 y 的方式:

 x < y (less than)
 x > y (greater than)
 x == y (equals - and yes, with two equals signs)

这些是你最常使用的。

“if”语句做出决策

使用**if** 语句告诉你的程序只有当你设置的条件(或不是)为真时才执行某些操作。if语句测试条件并在测试通过时执行代码。许多if语句检查两个事物是否相等。这时你使用==运算符。这与单等号(=)运算符不同,后者用于设置值。

图片图片

如果/否则语句在条件不为真时也会执行某些操作。

**if/else** 语句就像它听起来的那样:如果条件为真,则执行一件事情否则执行另一件事情。一个if/else语句是一个if语句,后面跟着**else** 关键字,然后是第二组要执行的语句。如果测试为真,则程序执行第一组大括号之间的语句。否则,它执行第二组大括号之间的语句。

图片

循环一遍又一遍地执行一个操作

这里有大多数程序(尤其是 游戏!)的一个奇特之处:它们几乎总是涉及重复执行某些操作。这就是循环的用途——它告诉你的程序在某个条件为真或假时继续执行某一组语句。

图片

while 循环在条件为真时不断地执行循环语句

while 循环中,只要括号内的条件为真,大括号内的所有语句都会执行。

while (x > 5)
{
  // Statements between these brackets will
  // only run if x is greater than 5, then
  // will keep looping as long as x > 5
}

do/while 循环运行语句,然后检查条件

do/while 循环与 while 循环几乎一样,只有一个区别。while 循环首先进行测试,然后仅在测试为真时运行其语句。do/while 循环先运行语句,然后进行测试。因此,如果需要确保循环至少运行一次,do/while 循环是一个不错的选择。

do
{
  // Statements between these brackets will run
  // once, then keep looping as long as x > 5
} while (x > 5);

for 循环在每次循环后运行一个语句。

for 循环在每次执行循环后运行一个语句。

图片

注意

for 语句的各个部分称为 初始化器 **(int i = 0),条件测试 (i < 8),和 迭代器 (i = i + 2)。每次通过一个 for 循环(或任何循环)都称为 迭代。

条件测试始终在每次迭代开始时运行,并且迭代器始终在迭代结束时运行。

注意

当你使用 for 片段时,按 Tab 键可以在 i 和 length 之间切换。如果你改变变量 i 的名称,片段会自动更改另外两次出现的名称。

注意

当我们给你提供纸和笔的练习时,通常会在下一页给出答案。

使用代码片段来帮助编写循环

这样做!

你将在本书中编写大量的循环,Visual Studio 可以通过片段或简单的代码模板来帮助提高效率。让我们使用片段向你的 OperatorExamples 方法中添加一些循环。

如果你的代码仍在运行,请从调试菜单中选择停止调试(Shift+F5)(或者点击工具栏上的停止按钮 Images)。然后找到Console.WriteLine(area);这一行,在分号后面点击,然后按几次 Enter 添加额外的空格。现在开始你的片段。输入 **while** 并按两次 Tab 键。IDE 会向你的代码添加一个 while 循环的模板,条件测试被突出显示:

Images

输入**area < 50** ——IDE 将用文本替换true。按 Enter 完成片段。然后在括号之间添加两个语句:

    while (area < 50)
    {
           height++;
           area = width * height;

    }
注意

IDE 提示:括号

如果你的括号不匹配,你的程序将无法构建,这会导致令人沮丧的错误。幸运的是,IDE 可以帮助解决这个问题!将光标放在括号上,IDE 会突出显示其匹配项。

接下来,使用**do/while** 循环片段在你刚刚添加的 while 循环后立即添加另一个循环。输入**do** 并按两次 Tab 键。IDE 会添加此片段:

Images

输入area > 25并按 Enter 完成片段。然后在括号之间添加两个语句:

    do
    {
        width--;
        area = width * height;

    } while (area > 25);

现在,使用调试器真正了解这些循环的工作方式:

  1. 点击循环体上方的一行,并从调试菜单中选择切换断点(F9)以添加断点。然后运行你的代码,按下F5跳转到新的断点。

  2. 使用**逐步执行(F10)**来逐步执行这两个循环。观察局部窗口中heightwidtharea值的变化。

  3. 停止程序,然后将 while 循环测试更改为**area < 20**,以使两个循环的条件都为假。再次调试程序。while 先检查条件并跳过循环,但 do/while 会执行一次后再检查条件。

一些关于 C#代码有用的事项

  • 不要忘记,你所有的语句都需要以分号结束。

    name = "Joe";
    
  • 通过在代码行前加两个斜杠来为你的代码添加注释。

    // this text is ignored
    
  • 使用 // 来开始和结束包含换行符的注释。

    /* this comment
     * spans multiple lines */
    
  • 变量是由类型后跟名称声明的。

    int weight;
    // the variable's type is int and its name is weight
    
  • 大多数时候,额外的空白是可以接受的。

    So this:      int      j      =            1234       ;
    Is exactly the same as this: int j = 1234;
    
  • If/else, while, do, and for are all about testing conditions.

    到目前为止,我们看到的每个循环只要条件为真就会继续运行。

    图片

然后你的循环就会永远运行下去。

每次程序运行条件测试时,结果要么是**true**,要么是**false**。如果是**true**,那么程序将再次通过循环。每个循环都应该有一些代码,如果运行足够多次,应该会导致条件测试最终返回**false**。如果没有,那么循环将一直运行,直到您关闭程序或关闭计算机!

注意

有时这被称为无限循环,在编写代码时肯定会有使用它的时候。

图片

当然!每个程序都有其自身的机制。

在软件设计的每个层次都存在着机制。在视频游戏的背景下讨论和理解它们会更容易。我们将利用这一点来帮助您更深入地理解机制,这对于设计和构建任何类型的项目都是非常有价值的。

这里有一个例子。游戏的机制决定了游戏的难易程度。使 Pac Man 更快或鬼魂更慢,游戏会变得更容易。这并不一定使游戏变得更好或更糟——只是不同而已。猜猜?同样的想法也适用于您如何设计您的类!您可以将您如何设计方法和字段看作是类的机制。关于如何将代码分解为方法或何时使用字段的选择会使它们更易于使用或更难以使用。

控件驱动您的用户界面的机制

在上一章中,您使用了 TextBlock 和 Grid 控件来构建一个游戏。但是有很多不同的控件可以使用,您选择使用哪些控件会真正改变您的应用程序。听起来奇怪吗?实际上与我们在游戏设计中做选择的方式非常相似。如果您设计一个需要随机数生成器的桌面游戏,您可以选择使用骰子、旋转器或卡片。如果您设计一个平台游戏,您可以选择让您的玩家跳跃、双重跳跃、墙壁跳跃或飞行(或在不同时间做不同的事情)。对于应用程序也是如此:如果您设计一个需要用户输入数字的应用程序,您可以从不同的控件中选择让他们这样做——而这种选择会影响用户体验应用程序的方式

图片

  • 文本框允许用户输入任何想要的文本。但我们需要一种方法来确保他们只输入数字,而不是任意文本。

    图片

  • 单选按钮允许您限制用户的选择。如果需要,您可以将其用于数字,并且可以选择如何布局它们。

    图片

  • 此页面上的其他控件可以用于其他类型的数据,但滑块专门用于选择数字。电话号码也只是数字而已,所以*从技术上讲*,你可以使用滑块来选择电话号码。你觉得这是个好选择吗?

    图片

  • 列表框为用户提供了从项目列表中选择的方式。如果列表很长,它会显示滚动条,以便用户更容易找到项目。

    图片

  • 组合框结合了列表框和文本框的行为。它看起来像一个普通的文本框,但当用户点击它时,会在其下弹出一个列表框。

    图片

注意

控件是常见的用户界面(UI)组件,是您的 UI 的构建块。您所做的有关使用哪些控件的选择会改变应用程序的机制。

注意

我们可以借鉴视频游戏中的机制概念来了解我们的选择,这样我们可以为任何我们自己的应用程序做出出色的选择——不仅仅是游戏。

图片

本章的其余部分包含了一个为 Windows 构建 WPF 桌面应用程序的项目。前往 Visual Studio for Mac 学习指南获取相应的 macOS 项目。

创建一个 WPF 应用程序以实验控件

如果你填写了网页上的表单,你就会看到我们刚才展示的这些控件(即使你不知道它们的官方名称)。现在让我们创建一个 WPF 应用程序来练习使用这些控件。这个应用程序非常简单——它唯一的功能就是让用户选择一个数字,并显示所选择的数字。

一定要这样做!

图片图片

“早存,多存。”

这是一个旧说法,来自视频游戏没有自动保存功能的时代,当时您必须将这些东西插入计算机以备份项目……但这仍然是个好建议!Visual Studio 使得将项目添加到源代码控制并保持更新变得轻松——所以您始终可以回顾您所取得的所有进展。

图片

向您的应用程序添加一个 TextBox 控件

TextBox 控件为用户提供了一个输入文本的框,所以让我们将其添加到您的应用程序中。但我们不只是想要一个没有标签的 TextBox,所以我们首先会添加一个Label 控件(它与 TextBlock 很相似,但专门用于为其他控件添加标签)。

  1. 从工具箱拖动一个 Label 到网格的左上角单元格。

    这与你在 #start_building_with_chash_build_somethin 中向你的动物匹配游戏添加 TextBlock 控件的方法完全相同,只是这次你要用 Label 控件来做。无论你把它拖到单元格的哪个位置,只要它在左上角的单元格里就行了。

  2. 设置 Label 的文本大小和内容。

    当选中标签控件时,转到属性窗口,展开文本部分,并将字体大小设置为**18px**。然后展开常规部分,并将内容设置为文本输入一个数字

    图片图片

  3. 将标签拖到单元格的左上角。

    在设计师中单击标签并将其拖动到左上角。当距左侧或顶部单元格墙壁 10 像素时,您将看到灰色条出现,并且它将捕捉到 10 像素的边距。

    现在,您窗口的 XAML 应包含一个标签控件:

    <Label Content="*Enter a number*" FontSize="*18*" Margin="*10,10,0,0*" HorizontalAlignment="*Left*" VerticalAlignment="*Top*"/>
    

    图片

  4. 将一个文本框拖到网格的左上角单元格中。

    您的应用程序将拥有一个文本框,位于标签的正下方,以便用户可以输入数字。将其拖动到左侧并放置在标签的下方 - 相同的灰色条将出现以使其在标签的下方具有 10 像素的左边距。将其名称设置为**numberTextBox**,字体大小设置为**18px**,文本设置为**0**

    图片

    现在运行您的应用程序。糟糕!出了点问题 — 它抛出了一个异常。

    图片

    查看 IDE 底部。它有一个自动窗口,显示您定义的任何变量。

    所以到底发生了什么 — 更重要的是,我们如何修复它?

注意

将 XAML 中的 TextBlock 标签移动到文本框上方,使 TextBlock 首先初始化。

添加 C#代码来更新 TextBlock

在#start_building_with_chash_build_somethin 中,您添加了事件处理程序 — 当某个事件触发时调用的方法(有时我们称事件为触发激发)— 来处理动物匹配游戏中的鼠标点击。现在我们将向代码后台添加一个事件处理程序,每当用户在文本框中输入文本并将该文本复制到您添加到小练习中的右上角单元格中的 TextBlock 时调用。

注意

当您双击文本框控件时,IDE 会添加一个处理 TextChanged 事件的事件处理程序,每当用户更改其文本时调用此事件处理程序。双击其他类型的控件可能会添加其他事件处理程序 — 而在某些情况下(例如 TextBlock),则根本不会添加任何事件处理程序。

  1. 双击文本框控件以添加方法。

    双击文本框后,IDE 会自动添加一个 C#事件处理方法,连接到其 TextChanged 事件。它会生成一个空方法,并赋予一个名称,该名称由控件名称(numberTextBox)后跟下划线和所处理事件的名称组成 — numberTextBox_TextChanged

    private void numberTextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
    
    }
    
  2. 添加代码到新的 TextChanged 事件处理程序中。

    任何时候用户在文本框中输入文本,我们希望应用程序将其复制到你添加到网格右上角单元格中的文本块中。因为你给文本块命名为 number,并且你还给文本框命名为 numberTextBox,你只需要一行代码来复制其内容:

    private void numberTextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        number.Text = numberTextBox.Text;
    }
    
    注意

    这行代码将文本块中的文本设置为与文本框中的文本相同,任何时候用户改变文本框中的文本,它都会被调用。

  3. 运行你的应用程序并尝试文本框。

    使用“开始调试”按钮(或从调试菜单中选择“开始调试(F5)”)启动你的应用程序,就像你在 #start_building_with_chash_build_somethin 中做动物匹配游戏一样。(如果运行时工具出现,你可以像在 #start_building_with_chash_build_somethin 中那样禁用它们。)在文本框中输入任何数字,它都会被复制。

    图片

    但是有些问题 —— 你可以输入任何文本到文本框中,而不仅仅是数字!

    图片

添加一个只允许数字输入的事件处理程序

当你在 #start_building_with_chash_build_somethin 中给你的文本块添加了鼠标按下事件时,你使用了属性窗口右上角的按钮在属性和事件之间切换。现在你会做同样的事情,但这次你会使用预览文本输入事件只接受由数字组成的输入,并拒绝任何不是数字的输入。

如果你的应用程序当前正在运行,请停止它。然后进入设计器,点击文本框选择它,切换到属性窗口以显示其事件。向下滚动并双击预览文本输入旁边的框,让 IDE 生成一个事件处理程序方法。

图片图片

你的新事件处理程序方法将有一个语句:

private void numberTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
    e.Handled = !int.TryParse(e.Text, out int result);
}
注意

你会在书后面详细了解 int.TryParse,现在只需按照这里显示的方式输入代码。

这是这个事件处理程序的工作原理:

  1. 当用户输入文本到文本框中时,事件处理程序会被调用,但在文本框更新之前。

  2. 它使用了一个特殊的方法叫做 int.TryParse 来检查用户输入的文本是否为数字。

  3. 如果用户输入了一个数字,它会将 e.Handled 设置为 true,这告诉 WPF 忽略该输入。

在运行代码之前,请回到 XAML 标签查看文本框:

 <TextBox x:Name="*numberTextBox*" FontSize="*18*" Margin="*10,49,0,0*" Text="*0*" Width="*120*"
          HorizontalAlignment="*Left*" TextWrapping="*Wrap*" VerticalAlignment="*Top*"
          TextChanged="*numberTextBox_TextChanged*"
          PreviewTextInput="***numberTextBox_PreviewTextInput***"/>

现在它连接了两个事件处理程序:文本更改事件连接到一个名为 numberTextBox_TextChanged 的事件处理程序方法,紧接着下面的预览文本输入事件连接到一个名为 numberTextBox_PreviewTextInput 的方法。

在网格的底部行添加滑块

让我们在底部行添加两个滑块,然后连接它们的事件处理程序以更新右上角的文本块。

  1. 向你的应用程序添加一个滑块。

    从工具箱中拖动一个滑块到右下角的单元格中。将其拖动到单元格的左上角,并使用灰色条形调整其左侧和顶部边距为 10。

    图片图片

    使用属性窗口的常用部分将 AutoToolTipPlacement 设置为**TopLeft**,将 Maximum 设置为**5**,将 Minimum 设置为**1**。给它命名为**smallSlider**。然后双击滑块,添加这个事件处理程序:

    private void smallSlider_ValueChanged(
            object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        number.Text = smallSlider.Value.ToString("0");
    }
    
    注意

    Slider 控件的值是带有小数点的分数。这个“0”将其转换为整数。

  2. 添加一个荒谬的滑块以选择电话号码。

    有句老话说:“只是因为一个想法很糟糕,也许还很愚蠢,并不意味着你不应该去做它。” 所以让我们做一些有点愚蠢的事情:添加一个滑块以选择电话号码。

    图片图片

    将另一个滑块拖入底行。使用属性窗口的布局部分重置其宽度,将其 ColumnSpan 设置为**2**,将所有边距设置为**10**,将其垂直对齐设置为**Center**,水平对齐设置为**Stretch**。然后使用常用部分将 AutoToolTipPlacement 设置为**TopLeft**,Minimum 设置为**1111111111**,Maximum 设置为**9999999999**,Value 设置为**7183876962**。给它命名为**bigSlider**。然后双击它,添加这个 ValueChanged 事件处理程序:

    图片

添加 C#代码以使其余控件工作

你希望应用程序中的每个控件都执行相同的操作:更新右上角单元格中的 TextBlock,以显示所选数字。因此,当你选中单选按钮或从 ListBox 或 ComboBox 中选择项目时,TextBlock 会更新为你选择的值。

  1. 为第一个 RadioButton 控件添加一个 Checked 事件处理程序。

    双击第一个 RadioButton。IDE 将添加一个名为 RadioButton_Checked 的新事件处理程序方法(因为你从未给控件命名,它只是使用控件类型生成方法)。添加以下代码行:

    private void RadioButton_Checked(
            object sender, RoutedEventArgs e)
    {
        if (sender is RadioButton radioButton) {
        number.Text = radioButton.Content.ToString();
        }
    }
    
  2. 使其他 RadioButton 使用相同的事件处理程序。

    仔细查看你刚修改的 RadioButton 的 XAML。IDE 添加了属性Checked="RadioButton_Checked" ——这与其他事件处理程序的连接方式完全相同。将此属性复制到其他 RadioButton 标签,使它们都具有相同的 Checked 属性——现在它们都连接到同一个 Checked 事件处理程序。你可以使用属性窗口中的事件视图来检查每个 RadioButton 是否正确连接。

    图片

  3. 使 ListBox 更新右上角单元格中的 TextBlock。

    在你进行练习时,你将 ListBox 命名为myListBox。现在,你将添加一个事件处理程序,每当用户选择项目时都会触发该处理程序,并使用该名称获取用户选择的数字。

    双击 ListBox 下方的空白处,使 IDE 添加一个 SelectionChanged 事件的事件处理程序方法。在其中添加以下语句:

    注意

    确保您点击列表项下方的空白处。如果您点击一个项目,它将为该项目添加一个事件处理程序,而不是为整个 ListBox 添加。

    private void myListBox_SelectionChanged(
            object sender, SelectionChangedEventArgs e)
    {
      if (myListBox.SelectedItem is ListBoxItem listBoxItem) {
          number.Text = listBoxItem.Content.ToString();
      }
    }
    
  4. 使只读组合框更新 TextBlock。

    双击只读 ComboBox 以使 Visual Studio 添加一个 SelectionChanged 事件的事件处理程序,每当在 ComboBox 中选择一个新项目时,该事件都会触发。这里的代码——与 ListBox 的代码非常相似:

    private void readOnlyComboBox_SelectionChanged(
            object sender, SelectionChangedEventArgs e)
    {
        if (readOnlyComboBox.SelectedItem is ListBoxItem listBoxItem)
            number.Text = listBoxItem.Content.ToString();
    }
    
    注意

    您还可以使用属性窗口添加 SelectionChanged 事件。如果您意外地这样做了,您可以点击“撤销”(但确保您在两个文件中都这样做)。

  5. 使可编辑的组合框更新 TextBlock。

    可编辑的组合框类似于 ComboBox 和 TextBox 的混合体。您可以从列表中选择项目,但也可以输入自己的文本。因为它像一个 TextBox 一样工作,我们可以添加一个 PreviewTextInput 事件处理程序,以确保用户只能输入数字,就像我们对 TextBox 做的那样。事实上,您可以重用您已经为 TextBox 添加的相同事件处理程序

    转到可编辑 ComboBox 的 XAML,在闭合角标 **>** 前面放置光标,开始输入 PreviewTextInput。 IntelliSense 窗口将弹出以帮助您完成事件名称。然后 添加一个等号—一旦您这样做,IDE 将提示您选择一个新的事件处理程序或选择您已添加的一个。选择现有的事件处理程序。

    图片

    之前的事件处理程序使用列表项来更新 TextBlock。但用户可以在可编辑的 ComboBox 中输入任何文本,所以这次您将添加一种不同类型的事件处理程序

    再次编辑 XAML,在 ComboBox 下方添加一个新的标签。这次,输入 **TextBoxBase**。—一旦你输入句点,自动完成将会给出建议。选择 TextBoxBase.TextChanged 并输入一个等号。现在从下拉菜单中选择 <新事件处理程序>。

    图片

    IDE 将在代码后台添加一个新的事件处理程序。这是它的代码:

    private void editableComboBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        if (sender is ComboBox comboBox)
            number.Text = comboBox.Text;
    }
    

    现在运行你的程序。所有控件都应该工作。干得好!

图片

控件为您的用户提供了灵活性,使事情变得更加简单。

在构建应用程序的用户界面(UI)时,你需要做出很多选择:使用哪些控件,每个控件放置在哪里,如何处理它们的输入。选择一个控件而不是另一个会向用户传达关于如何使用你的应用程序的*隐含*信息。例如,当你看到一组单选按钮时,你知道你需要从一个有限的选择集中选择一个,而可编辑的组合框则告诉你几乎没有限制的选择。因此,不要把 UI 设计看作是做出“对”或“错”的选择。相反,把它看作是让用户尽可能轻松使用你的途径。

第四章:Unity 实验室#1:探索 C#与 Unity

欢迎来到您的第一个Head First C# Unity Lab。编写代码是一种技能,就像任何其他技能一样,通过练习和实验来提高。Unity 将是一个非常有价值的工具。

Unity 是一个跨平台的游戏开发工具,您可以用它制作专业质量的游戏、模拟等。同时,这也是一个学习 C#工具和理念的有趣而令人满足的方式,这本书中您将会学到这些。我们设计了这些简短而有针对性的实验室,以巩固您刚刚学到的概念和技术,帮助您磨练 C#技能。

这些实验室是可选的,但是它们是宝贵的练习——即使您不打算使用 C#来制作游戏

在这个第一个实验室中,您将开始使用 Unity,并对 Unity 编辑器有所了解,并开始创建和操作 3D 形状。

Unity 是一个强大的游戏设计工具

欢迎来到 Unity 的世界,这是一个完整的系统,用于设计专业质量的游戏——包括二维(2D)和三维(3D)游戏,以及模拟、工具和项目。Unity 包括许多强大的功能,包括...

跨平台游戏引擎

游戏引擎负责显示图形,追踪 2D 或 3D 角色,检测它们的碰撞,使它们表现得像真实世界的物体,并且还有许多其他功能。Unity 将为您在本书中构建的 3D 游戏完成所有这些工作。

Images

强大的 2D 和 3D 场景编辑器

您将在 Unity 编辑器中花费大量时间。它让您可以编辑充满 2D 或 3D 对象的关卡,并提供工具,用于为您的游戏设计完整的世界。Unity 游戏使用 C#来定义其行为,并且 Unity 编辑器与 Visual Studio 集成,为您提供无缝的游戏开发环境。

注意

虽然这些 Unity 实验室将集中在 Unity 中的 C#开发上,但如果您是视觉艺术家或设计师,Unity 编辑器还具有许多专为您设计的艺术友好型工具。在这里查看它们:unity3d.com/unity/features/editor/art-and-design

Images

游戏创作生态系统

除了作为一个强大的游戏创建工具之外,Unity 还具有一个生态系统,帮助您构建和学习。Unity 的学习页面(unity.com/learn)提供宝贵的自学资源,而 Unity 论坛(forum.unity.com)则帮助您与其他游戏设计师联系并提问。Unity 资源商店(assetstore.unity.com)提供免费和付费的资源,如角色、形状和特效,可以用于您的 Unity 项目中。

我们的 Unity 实验室将集中于使用 Unity 作为探索 C#的工具,并通过您在本书中学到的 C#工具和理念进行实践。

Head First C# Unity 实验室专注于以开发者为中心的学习路径。这些实验室的目标是帮助您快速掌握 Unity,采用与*Head First C#*全书一脉相承的大脑友好、及时学习方法,让您能够有针对性地、有效地练习 C# 的思想和技术

下载 Unity Hub

Unity Hub 是一个帮助您管理 Unity 项目和 Unity 安装的应用程序,也是创建新 Unity 项目的起点。首先从 store.unity.com/download 下载 Unity Hub,然后安装并运行它。

图片

Unity Hub 允许您在同一台计算机上安装多个版本的 Unity,因此您应该安装与我们用来构建这些实验室的相同版本。点击官方发布版本,安装以Unity 2020.1开头的最新版本——这是我们在这些实验室中使用的版本。安装完成后,请确保它已设置为首选版本。

Unity 安装程序可能会提示您安装不同版本的 Visual Studio。您也可以在同一台计算机上安装多个版本的 Visual Studio,但如果您已经安装了一个版本的 Visual Studio,Unity 安装程序就不需要再添加另一个版本了。

您可以在此处详细了解如何在 Windows、macOS 和 Linux 上安装 Unity Hub:docs.unity3d.com/2020.1/Documentation/Manual/GettingStartedInstallingHub.html

注意

Unity Hub 可让您在同一台计算机上安装多个 Unity 版本。因此,即使有更新版本的 Unity 可用,您也可以使用 Unity Hub 安装我们在 Unity 实验室中使用的版本。

使用 Unity Hub 创建新项目

在 Unity Hub 中的项目页面上单击 图片 按钮以创建新的 Unity 项目。命名为Unity Lab 1,确保选择了 3D 模板,并检查是否将其创建在一个合理的位置(通常是您的主目录下的 Unity Projects 文件夹)。

图片

单击“创建项目”以创建包含 Unity 项目的新文件夹。创建新项目时,Unity 会生成许多文件(就像 Visual Studio 为您创建新项目时所做的那样)。Unity 可能需要一两分钟来创建您的新项目的所有文件。

将 Visual Studio 设为 Unity 脚本编辑器

Unity 编辑器与 Visual Studio IDE 配合得非常紧密,使得编辑和调试游戏代码变得非常简单。因此,我们首先要确保 Unity 已经与 Visual Studio 连接好。从“编辑”菜单中选择“首选项”(或者在 Mac 上从 Unity 菜单中选择),打开 Unity 首选项窗口。在左侧点击“外部工具”,在“外部脚本编辑器”窗口中选择 Visual Studio

在某些旧版本的 Unity 中,您可能会看到一个 Editor Attaching 复选框 —— 如果有,请确保它被选中(这样可以让您在 IDE 中调试 Unity 代码)。

图片

好了!您已经准备好开始构建您的第一个 Unity 项目了。

您可以使用 Visual Studio 来调试 Unity 游戏中的代码。只需在 Unity 的偏好设置中选择 Visual Studio 作为外部脚本编辑器。

掌控 Unity 布局

Unity 编辑器就像是您 Unity 项目中除了 C# 以外的所有部分的 IDE。您将使用它来处理场景、编辑 3D 形状、创建材质等等。就像在 Visual Studio 中一样,Unity 编辑器中的窗口和面板可以以许多不同的布局重新排列。

找到窗口顶部附近的 Scene 选项卡。单击选项卡并拖动它以分离窗口:

图片

尝试将其停靠在其他面板内或旁边,然后将其拖动到编辑器中间使其成为浮动窗口。

选择 Wide 布局以与我们的截图匹配

我们选择了 Wide 布局,因为它在这些实验室的截图中表现良好。找到布局下拉菜单,选择 Wide,这样您的 Unity 编辑器看起来就像我们的一样。

图片

注意

Scene 视图是您创建的世界的主要交互视图。您将用它来定位 3D 形状、摄像机、灯光以及游戏中的所有其他对象。

这是 Wide 布局下您的 Unity 编辑器应该呈现的样子:

图片

您的场景是一个 3D 环境

一旦您启动编辑器,您就在编辑一个 场景。您可以将场景视为 Unity 游戏中的关卡。在 Unity 中的每个游戏由一个或多个场景组成。每个场景都包含一个独立的 3D 环境,具有自己的灯光、形状和其他 3D 对象。创建项目时,Unity 添加了一个名为 SampleScene 的场景,并将其存储在名为 **SampleScene.unity** 的文件中。

通过从菜单中选择 GameObject >> 3D Object >> Sphere,向您的场景添加一个球体:

图片

在您的场景窗口中将会出现一个球体。您在场景窗口看到的一切都是从 Scene 视图相机 的视角显示的,它“看”着场景并捕捉其所见。

图片

Unity 游戏由 GameObject 构建

当您向场景添加一个球体时,您创建了一个新的 GameObject。GameObject 是 Unity 中的基本概念。在您的 Unity 游戏中,每个物品、形状、角色、光线、摄像机和特效都是 GameObject。游戏中使用的任何场景、角色和道具都由 GameObject 表示。

在这些 Unity 实验室中,您将使用不同类型的 GameObject 构建游戏,包括:

图片

GameObject 是 Unity 中的基本对象,组件是它们行为的基本构建块。检视器窗口显示了您场景中每个 GameObject 及其组件的详细信息。

每个 GameObject 包含一些组件,提供其形状、设置其位置,并赋予其所有行为。例如:

  • Transform components确定 GameObject 的位置和旋转。

  • Material components改变 GameObject 的渲染方式——或者说改变 Unity 绘制 GameObject 的方式——通过改变颜色、反射、光滑度等。

  • Script components使用 C#脚本确定 GameObject 的行为。

注意

渲染,动词。

以艺术方式代表或描绘。

*米开朗基罗渲染他最喜欢的模型时比他的其他任何图纸都更详细。

使用 Move Gizmo 移动你的游戏对象

Unity 编辑器顶部的工具栏允许你选择 Transform 工具。如果未选择 Move 工具,请按下其按钮进行选择。

Images

Move 工具允许你使用Move Gizmo在 3D 空间中移动 GameObject。你应该看到红色、绿色和蓝色的箭头以及一个立方体出现在窗口中间。这就是 Move Gizmo,你可以用它来移动选定的对象在场景中。

Images

将鼠标光标移到 Move Gizmo 中心的立方体上——注意,当你将鼠标光标移动到立方体上时,立方体的每个面都会亮起?点击左上角的面并拖动球体。你在移动球体在 X-Y 平面上。

注意

当你点击 Move Gizmo 中间的立方体的左上角面时,它的 X 和 Y 箭头会亮起,你可以在场景中的 X-Y 平面上拖动你的球体。

Images

在场景中移动你的球体,感受 Move Gizmo 的工作原理。点击并拖动每个箭头,分别沿每个平面拖动。尝试点击 Scene Gizmo 中的立方体的每个面,以在所有三个平面上移动它。注意随着球体远离你(或者说场景相机),它变小,靠近时变大。

Move Gizmo 允许你沿着场景中的任意轴或平面移动游戏对象。

Inspector 显示了你的 GameObject 的组件

当你在 3D 空间中移动你的球体时,请注意Inspector 窗口,如果你使用宽布局,则在 Unity 编辑器的右侧。浏览 Inspector 窗口——你会看到你的球体有四个标记为 Transform、Sphere(Mesh Filter)、Mesh Renderer 和 Sphere Collider 的组件。

每个 GameObject 都有一组组件,提供其行为的基本构建块,并且每个 GameObject 都有一个Transform 组件,驱动其位置、旋转和缩放。

当你使用 Move Gizmo 在 X-Y 平面上拖动球体时,你可以看到 Transform 组件中位置行的 X 和 Y 数字发生变化。

注意

如果你不小心取消选择了一个游戏对象,只需再次点击它。如果它在场景中不可见,你可以在层次结构窗口中选择它,该窗口显示场景中的所有游戏对象。当你将布局重置为宽时,层次结构窗口位于 Unity 编辑器的左下角。

Images

尝试点击移动 Gizmo 立方体的其他两个面,然后拖动来在 X-Z 和 Y-Z 平面上移动球体。接着点击红色、绿色和蓝色箭头,沿着 X、Y 或 Z 轴拖动球体。当你移动球体时,你会看到 Transform 组件中的 X、Y 和 Z 值发生变化。

现在按住Shift 键将 Gizmo 中间的立方体转换为正方体。点击并拖动该正方体,在与场景视图相平行的平面上移动球体。

一旦你完成了对 Move Gizmo 的实验,使用球体的 Transform 组件上下文菜单将组件重置为其默认值。点击 Transform 面板顶部的上下文菜单按钮 (Images),然后从菜单中选择重置。

Images

位置将重置为[0, 0, 0]。

你可以在 Unity 手册中了解更多关于工具及其如何用于定位游戏对象的信息。点击帮助 >> Unity 手册并搜索“定位游戏对象”页面。

经常保存你的场景!使用文件 >> 保存或 Ctrl+S / ImagesS 来立即保存当前场景。

将材质添加到你的球体游戏对象中。

Unity 使用材质来提供颜色、图案、纹理和其他视觉效果。你的球体现在看起来相当无聊,因为它只有默认材质,这导致 3D 对象呈现为普通的米白色。让我们让它看起来像一个台球。

  1. 选择球体。

    当球体被选中时,你可以在检视器窗口中看到它的材质作为一个组件:

    Images

    我们将通过添加一个纹理来使你的球体更有趣——这只是一个简单的图像文件,包裹在一个 3D 形状周围,就像你在橡胶片上打印了这张图片并将其拉伸到你的物体上一样。

  2. 前往我们在 GitHub 上的台球纹理页面。

    github.com/head-first-csharp/fourth-edition并点击Billiard Ball Textures链接浏览一个完整的台球纹理文件夹。

  3. 下载 8 球的纹理。

    点击文件8 Ball Texture.png查看 8 球的纹理。这是一个普通的 1200 × 600 PNG 图像文件,你可以在你喜爱的图像查看器中打开。

    Images

    将文件下载到计算机上的一个文件夹中。

    (你可能需要右键点击下载按钮来保存文件,或者点击下载以打开并保存它,这取决于你的浏览器。)

  4. 将 8 球纹理图像导入到你的 Unity 项目中。

    在项目窗口中的 Assets 文件夹上右键,选择“导入新资源...”并导入纹理文件。当你点击项目窗口中的 Assets 文件夹时,现在应该能看到它。

    图片

  5. 将纹理添加到你的球体。

    现在你只需拿这个纹理并“包裹”在你的球体上。点击项目窗口中的 8 号球纹理以选中它。一旦选中,将其拖动到你的球体上。

    图片

现在你的球体看起来像一个 8 号球。检视器显示 8 号球游戏对象。现在它有一个新的材质组件:

图片图片

Unity 是真正“掌握”C#的好方法。

编程是一种技能,你写 C#代码的练习越多,编码能力就会越好。这就是为什么我们在整本书中专门设计了 Unity 实验室,来帮助你练习 C#技能,并巩固每章节所学的 C#工具和概念。随着你写更多的 C#代码,你会变得越来越好,这是成为优秀 C#开发者的一种非常有效的方式。神经科学告诉我们,当我们进行实验时,我们学习得更有效,所以我们设计这些 Unity 实验室时提供了许多实验选项,并建议你如何发挥创造力并继续进行每个实验。

但是,Unity 给了我们更重要的机会,帮助理解重要的 C#概念和技术。当你学习一门新的编程语言时,看到它如何在许多不同的平台和技术上运行是非常有帮助的。这就是为什么我们在主章节材料中同时包括了控制台应用和 WPF 应用,有些情况下甚至让你使用两种技术构建相同的项目。加入 Unity,让你获得第三种视角,这真的能加速你对 C#的理解。

旋转你的球体

在工具栏中点击“旋转工具”。你可以使用 Q、W、E、R、T 和 Y 键快速切换变换工具——按 E 和 W 切换旋转工具和移动工具。

图片

  1. 点击球体。Unity 将显示一个带有红、蓝和绿圆圈的线框球体旋转操作器。点击红圈并拖动它以绕 X 轴旋转球体。

    图片

  2. 点击并拖动绿色和蓝色圆圈以绕 Y 轴和 Z 轴旋转。外部的白色圆圈使球体沿着从场景视图摄像机出来的轴旋转。观察检视器窗口中的旋转数值变化。

    图片

  3. 打开检视器窗口中变换面板的上下文菜单。点击“重置”,就像之前一样操作。这将把变换组件中的所有内容重置为默认值——在这种情况下,将把你的球体旋转恢复为[0, 0, 0]。

    图片

    现在使用 文件 >> 保存 或 Ctrl+S / 图片S 来保存场景。早保存,经常保存!

使用 Hand 工具和 Scene Gizmo 移动 Scene 视图相机。

使用鼠标滚轮或轨迹板上的滚动功能进行缩放,并在 Move 和 Rotate Gizmos 之间切换。注意到球体的大小变化,但 Gizmos 不变。编辑器中的 Scene 窗口显示虚拟相机视图,并且滚动功能缩放该相机。

按 Q 键选择Hand 工具,或从工具栏中选择它。你的光标将变成手型。

图片

注意

按住 Alt 键(Mac 上为 Option 键)并拖动,Hand 工具将变成眼睛并围绕窗口中心旋转视图。

Hand 工具通过改变场景相机的位置和旋转来在场景周围移动。选择 Hand 工具后,你可以在场景中的任何地方点击以进行平移。

图片

当选择 Hand 工具时,你可以通过点击和拖动平移场景相机,并且你可以通过按住Alt(或 Option)并拖动旋转它。使用鼠标滚轮进行缩放。按住右键允许你使用 W-A-S-D 键在场景中飞行

当你旋转场景相机时,注意 Scene 窗口右上角的Scene Gizmo。Scene Gizmo 总是显示相机的方向 —— 在使用 Hand 工具移动 Scene 视图相机时,检查它。点击 X、Y 和 Z 锥体可将相机捕捉到一个轴上。

图片

Unity 手册提供了关于导航场景的绝佳提示: docs.unity3d.com/Manual/SceneViewNavigation.html

图片

发挥创造力!

我们设计这些 Unity 实验室,为你提供一个自主实验 C# 的平台,因为这是成为优秀 C# 开发者的最有效途径。在每个 Unity 实验室结束时,我们将为你提供一些可以尝试的建议。在进入下一章之前,花些时间尝试一下你刚刚学到的一切。

  • 在你的场景中再添加几个球体。尝试使用其他台球球形图。你可以从与 8 Ball Texture.png 相同的位置下载它们。

  • 尝试通过选择 GameObject >> 3D Object 菜单中的 Cube、Cylinder 或 Capsule 添加其他形状。

  • 尝试使用不同的图像作为纹理。看看当你将它们用于创建纹理并添加到不同形状时,人物或风景照片会发生什么。

  • 你能否通过形状、纹理和灯光创建一个有趣的 3D 场景?

图片

编写的 C# 代码越多,你就越能掌握它。这是成为优秀 C# 开发者的最有效方式。我们设计这些 Unity 实验室,为你提供实践和实验的平台。