搜档网
当前位置:搜档网 › 3D游戏编程入门经典

3D游戏编程入门经典

3D游戏编程入门经典
3D游戏编程入门经典

注:讲述了3D游戏编程所需要的基本知识。利用.net和c#编写成为游戏开发人员的条件

我所遇到的每一个开发人员都至少在某一段时间想成为一个游戏开发人员。对于很多人来说,视频游戏不只是空闲时的一种爱好,他们完全被游戏所吸引。人们沉浸在这些虚拟世界中,常常梦想由自己创建如此神奇的天地。

不要被美丽的图形、奇妙的故事情节和感人悦耳的音乐所愚弄,编写游戏是非常困难的工作,只有某些特定的开发人员才能够获得成功。除了所需要的技术天赋之外,一个优秀的游戏开发人员应当拥有其他一些技能,例如,您首先是一个游戏爱好者。如果不是游戏爱好者,则不可能编写出伟大的游戏,这一条件使得游戏开发工作更具有挑战性。

成为游戏开发人员确实不是一件容易的事情。如果没有经验,则不会被游戏开发公司聘用,并且当没有公司聘用时,将更难以获得经验。当前只有少量的课程以及某些学校专注于讲授游戏的开发。但是,入门的最好方式是制作一个样片(demo reel)。它能向您未来的老板展示您的能力和处理事情的方式。

通过本书,您将制作出一个引人注目的样片。

读者对象

我常常被问到:―为什么每个人都想使用.NET Framework编写游戏程序?‖。其他的问题包括:―.NET Framework不是只用于Web服务器应用程序的吗?‖,―它不是很慢吗?‖,等等。对于游戏开发人

员(或者未来的游戏开发人员)来说,这些都是很重要的问题,但他们误解了.NET Framework。

.NET Framework不是最新的Web服务器版本,也不是任何服务器组件的扩展。当然能够使用.NET Framework创建强大的Web服务器应用程序,但是,这并不是它们的全部功能。.NET Framework包括一种功能强大的客户端应用程序编程接口(API)以及Managed DirectX,实际上.NET开发人员需要掌握整个DirectX API。利用它能够编写很多新的应用程序,包括游戏。如果认为.NET Framework只能够编写服务器应用程序,则显得有一点单纯。您也可以利用它创建复杂的客户端应用程序。

关于.NET的性能问题仍然存在,这些问题也很难简单描述。当引入一门―新的‖语言或者运行库时,开发人员在采用之前,通常比较犹豫。不久以前,很多游戏仍然是采用汇编语言编写的,因为游戏开发人员不相信C或者C++语言足够快。.NET Framework也遵循这个规则。在证明.NET Framework的性能之前,游戏开发人员都会以一种怀疑的眼光看待它。在本书中,大量的游戏是使用.NET运行库开发的。事实胜于雄辩,与其喋喋不休地讨论.NET运行库的性能有多好,还不如让本书中一些真实的游戏来证明这一点。

为什么使用.NET Framework

任何曾经编写过Windows程序的人都(无论是否使用.NET Framework)

能够认识到,即使使用Win32 API编写简单的Windows应用程序都比较困难。设计.NET Framework的目的是提供一种较简单的方式来执行在Windows程序中一些常见的事情,并且为普通的开发人员自动处理很多问题,例如内存的管理。

利用.NET Framework,开发人员可以省去很多麻烦的任务,例如花费三天的时间寻找一个内存泄漏bug,他们可以将一些功能直接添加到正在编写的游戏里面。很多情况下,从游戏中删除某些好的特性是因为需要花费大量的时间解决问题,而这些问题.NET Framework 已经为您解决。

.NET Framework的另外一个令人感兴趣的特性是语言的中立性。只要所使用的功能兼容公共语言规范(Common Language Specification,CLS),则可以采用任何能够使用CLS兼容功能的语言。过去,Visual Basic开发人员转向使用严格的C++进行编码时,可能比较困难。现在,Visual Basic .NET开发人员能够较容易的转向C#,因为这两种语言之间仅存在较小的语法差别。本书中的代码是使用C#编写的。

本书的目的

编写本书的目的是为了满足游戏开发群体的需求,他们缺少关于本书主题方面的信息。由于不能找到所需要的信息,太多可能成为优秀游戏开发人员的程序员选择了退出。目前市场上的多数游戏开发书籍是

关于2D图形的,它们是比较好的起点,但现在编写的多数游戏几乎全是3D图形的,并且现在的游戏爱好者也希望如此。并不是不需要继续编写2D游戏,但是如果那是游戏开发人员所能够做的所有,则他所做的可能毫无用处。

本书并不教导您如何去编写一个价值数百万美元的游戏。而是给出所有的工具和信息,让读者自己学会如何开发3D游戏。在阅读本书的过程中,将实现两个完整的3D游戏,阅读完本书后,读者将能够设计并实现自己的3D游戏,以使自己成为一名优秀的游戏开发人员。本书中最后的游戏将留给读者作为一个练习。

作者简介

Tom Miller是Managed DirectX API的设计师和首席开发人员。自1997年开始,他工作于Microsoft公司。他最初在Visual Basic组工作,后来他喜爱上了游戏和游戏编程,因此进入了DirectX组。自1999年末,他在DirectX组工作,并且已经使得DirectX API(和通常的游戏编程)为更多人所接受。他也编写了到目前为止最具权威的关于Managed DirectX库的书籍。

欢迎您的宝贵意见!

作为本书的读者,您同时还是本书最重要的批评家和评论员。我尊重您的意见,想知道我们在什么地方做得不错,在哪些地方还能够做得

更好,您最想看到我们提供哪些方面的内容,以及您希望传递给我们的任何明智的言语。

我们非常欢迎您的评论。您可以给我们写电子邮件或者直接给我写信,阐明您喜欢或不喜欢本书的哪些方面——以及我们能够在哪些方面改进本书。

请您注意的是,我们不能在与本书主题相关的技术问题方面帮助您。但是,我们拥有一个用户服务小组,与本书相关的特定技术问题将转寄给他们。

信中务必包含本书的书名和作者,以及您的姓名、电子邮件地址和电话号码。我们将仔细阅读您的评论,并将它们与本书的作者和编辑共享。

我的电子邮件地址是:feedback@https://www.sodocs.net/doc/6913318804.html,

如果熟悉了如何利用CLR(公共语言运行库)编写代码后,在面临选择开发语言时,您可能已经知道了您的选择。在Visual Studio .NET产品的最新版本中,当编写托管代码时,可以使用4种语言:C#、Visual Basic .NET、Managed C++和J#。此外还可以使用从VisualStudio .NET 产品之外的第三方销售商处获得的其他语言,例如COBOL或者

FORTRAN。

尽管本书中将讨论的概念可以很容易地移植到任何完全兼容CLS(通用语言规范)的语言,但实际的代码将仅包含所提到的前两种语言:即C#和Visual Basic. NET。本书中将仅使用C#代码。您可以从https://www.sodocs.net/doc/6913318804.html,/downpage中下载本书配套的安装文件,获取相关代码。

在本章中,您将学习到:

● 定义.NET

● 托管代码

● 使用Visual Studio .NET IDE

● 在命令行中编译托管代码

● 开发人员

● 游戏开发过程

● 工具

1.1 什么是.NET?

自从Microsoft公司宣布并发行.NET之后,人们一直在尝试指出这种新―事物‖到底是什么。根据Microsoft公司的市场活动,人们知道它将对计算产生革命性作用。这是一个很宏远的目标,现在断言它是否能够完成目标还太早。但是,它正在一步步地向此目标努力。

当人们讨论.NET时,无法确定他们正在讨论.NET的哪个部分。Microsoft公司发行的其他―产品‖或―思想‖都不具有如此多的不同形式。紧随.NET名字的是众多的产品、服务,甚至是概念,因此指出.NET 实际上是什么,是非常困难的。

当本书中讨论.NET时,它指从.NET FrameworkSDK中可获得的新的开发语言和运行库。该SDK包含.NET运行库。而.NET运行库包含运行为.NET环境编写的应用程序所需要的所有东西。可以认为.NET 运行库由几部分组成。CLR的部件驻留在GAC(Global Assembly Cache)中。也包括Microsoft .NET语言的编译器(C#、VB .NET、VJ#等等)。可以在图1-1中看到GAC。

图1-1 GAC

人们对运行.NET代码的最常见误解之一是,代码是―解释执行的‖,像Java代码或者老的Visual Basic运行库一样。事实上,为.NET编写的代码在执行前首先被编译。当编译.NET应用程序时,它被编译为一种中间语言(IL,intermediary language)。这种IL实际上存储在可执行文件中或者已经创建的库中。

IL可能在两个位置中的某一处被编译为本机代码(native code)。在安装代码时,可以执行一个称为ngen(native generation,即本机生成器)的进程。它将IL直接编译为本机代码,并将所编译的本机代码存储在GAC中的特定位置——本机程序集缓存(native assembly cache)中。假设在安装时没有编译代码,则代码在第一次执行前必须被编译。在应用程序启动期间,.NET运行库中一种称为JIT(Just In Time)编译器的特殊功能在后台执行编译工作。

在后一种情形中,因为发生在后台的编译工作,应用程序的启动时间将受到影响。当启动时间对应用程序非常重要时(例如正在编写游戏时),确保在安装阶段包含ngen步骤是比较明智的。但是,在这期间无法进行某些优化,而如果利用JIT编译代码,则可以进行这些优化,因此如果启动时间不是很重要,则可以让.NET运行库处理它所能够做的工作。

1.2 什么是托管代码

在本书中将经常提到托管代码。在全书中使用的API被称为Managed 的DirectX,.NET语言常被称为托管语言。术语―托管‖来源于.NET 运行库具有一个内置的内存管理器这一事实。

在―过去‖(只是几年前),使用C和C++编写代码的开发人员不得不自己进行内存管理。当不再需要已分配的内存空间时,必须将其释放,除非希望该内存被―泄漏‖,内存泄漏将带来严重的性能问题。更糟糕的是因为直接处理指针,而它很容易破坏项目正在使用的内存。在很多情况下,这将导致很长时间的故障调试,因为通常实际看到出错的地方并不是内存初始被破坏的地方。

人们认为C和C++语言难于掌握,主要是因为具有很多这种类型的问题。许多开发人员不愿意尝试C和C++,也是因为这个原因,他

们尝试使用其他没有这些令人头痛问题的高级语言,例如Visual Basic。尽管这些新语言具有易用易学的优点,但也具有一些缺点。它们的性能无法与C和C++语言相比,在大多数情况下显得特别慢。另外,因为底层操作系统是使用C++开发的,所以这些语言难以实现C++的所有功能。尽管可以使用它们处理很多非常好的工作,但是如果想要获得操作系统的所有性能和优势,只能依靠自己。

与.NET运行库的第一个版本相比,.NET的大多数内容都已经改变了。Microsoft公司几乎完全重新设计了一种新的API,竭力确保开发人员关心的问题都会被解决。这种新的运行库必须易学易用,快速高效,并且不存在令人头痛的内存管理问题。在本书中,将看到.NET在这些方面的好处

1.3 使用Microsoft Visual Studio .NET 2003 IDE

编写代码

提示:

本书设定在Visual Studio .NET IDE中编写代码。这不是使用.NET编写游戏的需求,也不是使用.NET本身的需求,它是本书所选择的IDE。图1-2显示了Visual Studio .NET 2003 IDE。

该IDE提供了编写.NET应用程序所需要的所有工具。它不仅包括编

写代码所需要的编辑器,而且还有其他大量功能,使得.NET应用程序的开发变得容易。它的设计使得您能够方便地创建丰富的内容,如Windows应用程序。它也具有一个内置的编译器和调试器,并且无缝集成了所有功能。本书设定使用这种IDE进行开发。

图1-2 Visual Studio .NET IDE

熟悉这种IDE的最好方式是使用它编写一个简单应用程序。典型的计算机编程是编写一个简单的Hello World应用程序,该应用程序只是在屏幕上输出Hello Word文本。老实说,这非常令人厌烦,因此您应当尝试编写更复杂的程序。但也不需要奇特的程序,因为这只是对IDE的一个介绍,当然在程序中包括一些用户特性交互将更好。在这里将编写一个应用程序,询问用户的姓名和出生年份,然后输出用户

的当前年龄。

1.3.1 C#代码

现在启动Visual Studio .NET 2003 IDE。首次启动时,应当看到图1-2所示的默认启动页面。单击该页中的New Project按钮,启动一个新的项目。如果没有显示这个页面,也可以单击File | New Project菜单项,或者按下Ctrl+Shift+N快捷键。这将产生一个New Project对话框,如图1-3所示。

应当首先尝试C#代码,因此在New Project对话框中,从左边的列表框中选择Visual C# Projects项,从右边的列表框中选择Console Application项。为项目命名,然后单击OK按钮创建该项目。这将创建一个新的控制台应用程序,当前它什么都不执行。使用程序清单1.1中的代码替换自动生成的代码。

图1-3 New Project对话框

程序清单1.1 简单的C#控制台应用程序

using System;

class ConsoleApp

{

static void Main()

{

Console.Write("Hello World C#!\r\nPlease enter your name:");

string name = Console.ReadLine();

Console.Write("Hello {0}, please enter the year you were born:", name); int year = int.MaxValue;

while(year == int.MaxValue)

{

try

{

year = int.Parse(Console.ReadLine());

}

catch (FormatException)

{

Console.Write("You did not enter a valid number. "); Console.WriteLine("Please enter an integer, such as 1975. "); }

}

Console.WriteLine("You must be approximately {0} years old! ", DateTime.Now.Year-year);

Console.WriteLine("Press the key to exit the application");

Console.Read();

}

}

如果您已经熟悉了C、C++或者Java,则C#语言的语法与这些语言非常相似。尽管C#的底层运行库仍然是CLR,但是它的语法源于这些语言,熟悉它们的开发人员很容易进行移植。该代码根本不复杂,它在询问用户的姓名和出生年份之前,首先使用Console类输出一个简单的消息(该消息包含Hello World)。注意,该应用程序接着询问出生的年份,直到用户输入一个有效的数值。它最后利用一个简单的公式输出用户的当前年龄。图1-4显示了该应用程序的运行过程。

图1-4 第一个应用程序

1.3.2 VB .NET代码

如果读者更熟悉Visual Basic语法,很可能能够理解前文中的大多数代码。这两种语言的语法差别不是很大,但还是应当尝试编写一个Visual Basic .NET版本的应用程序。再次启动一个新的项目,并采用在C#代码中所使用的相同指令,其中不同之处是项目的类型。应当选择Visual Basic Projects项目,创建该项目后,使用程序清单1.2中的代码替换自动生成的代码。

程序清单1.2 简单的VB .NET控制台应用程序

Module Module1

Sub Main()

Console.Write("Hello World C#!" + vbCr + vbLf + "Please enter your name:")

Dim name As String = Console.ReadLine()

Console.Write("Hello {0}, please enter the year you were born:", name) Dim year As Integer = Integer.MaxValue

While year = Integer.MaxValue

Try

year = Integer.Parse(Console.ReadLine())

Catch fe As FormatException

Console.Write("You did not enter a valid number. ")

Console.WriteLine("Please enter an integer, such as 1975. ")

End Try

End While

Console.WriteLine("You must be approximately {0} years old! ", DateTime.Now.Year - year)

Console.WriteLine("Press the key to exit the application")

Console.Read()

End Sub ?Main

End Module ? Module1

如您所见,从C#到VB .NET的代码移植并不复杂。因为这两种语言运行于相同的运行库之上,所以这两段代码仅存在微小的语法差别。也应当注意到,这两段代码产生了相同的结果。这是.NET的一种强大功能,它允许开发人员使用他最熟悉的语言编写代码。如果使用了编程语言X,您不必担心不能利用编程语言Z中的功能Y。因为每一种托管语言使用了相同的底层运行库,它们都具有相似的功能集。

1.4 在命令行中编译.NET代码

到目前为止,使用Visual Studio .NET IDE是开发.NET应用程序最容易的方法,但它并不是仅有的方法。.NET运行库将C#、VB .NET和VJ#的编译器随其运行库一起发布,因此只要有一个文本编译器和.NET运行库,就能够创建任何.NET应用程序。

提示:

为了实际开发并使用.NET应用程序,需要.NET运行库。如果没有安装,您可以从Microsoft的网站https://www.sodocs.net/doc/6913318804.html,/net处下载。

打开一个文本编辑器(例如Notepad),输入前面某一个程序清单中的代码。保存该代码,并打开一个命令提示符。在使用.NET运行库中的编译器之前,需要设置路径,将其指向底层.NET Framework的位置。在命令窗口中,输入下面的命令更新路径:

set path=%path%;C:\WINDOWS\https://www.sodocs.net/doc/6913318804.html,\Framework\v1.1.4322

警告:

如果Windows文件夹不是在C:\windows处,当更新路径变量时,确

保输入了正确的Windows文件夹位置。

命令行编译器位于上文所列出的文件夹中,与一些组成.NET运行库本身的程序集相同。C#的编译器是csc.exe,VB .NET的编译器是vbc.exe。这些可执行文件具有相似的命令行参数集,可以使用单个参数/?来显示这些编译器的所有参数。

假设使用了该代码的C#版本,并将文件保存为class1.cs,可以利用如下命令将应用程序编译为名为app.exe的可执行程序。首先定位到代码文件所在的文件夹,然后运行下面的命令:

csc /out:app.exe /target:exe Class1.cs

输出应当类似于下面的内容:

Microsoft (R) Visual C# .NET Compiler version 7.10.3052.4

for Microsoft (R) .NET Framework version 1.1.4322

Copyright (C) Microsoft Corporation 2001-2002. All rights reserved.

现在运行该应用程序,它将产生与使用IDE作为开发环境时相同的

相关主题