xna游戏制作教程之第12章创建场景和赛道.docx
- 文档编号:14325473
- 上传时间:2023-06-22
- 格式:DOCX
- 页数:22
- 大小:544.87KB
xna游戏制作教程之第12章创建场景和赛道.docx
《xna游戏制作教程之第12章创建场景和赛道.docx》由会员分享,可在线阅读,更多相关《xna游戏制作教程之第12章创建场景和赛道.docx(22页珍藏版)》请在冰点文库上搜索。
xna游戏制作教程之第12章创建场景和赛道
概览
要制作本书的最后一个大游戏——XNARacing,你必需第一在下一章学习一些高级议题。
本章涵盖了场景生成和赛道的渲染技术,下一章深切研究赛车游戏需要的物理引擎,最后一章你将学习游戏屏幕,游戏逻辑、优化赛车游戏和游戏开发中的一些窍门。
本书介绍的那个游戏是一个完整的赛车游戏,但它只能展示了一个赛道并简化了游戏规则。
完整的XNA赛车游戏是由微软作为XNA框架的一个starterkit(入门套件)提供的。
完整的游戏涵盖更多的任务,更酷的功能,更多的可选赛车、更酷的3D物体,和高达10个视频教程,你能够下载并观看以了解更多的知识。
这本书覆盖了所有的大体知识,让你创造一个很酷的游戏,但我想不单单涵盖一个游戏(或许你不太喜欢玩赛车游戏,为此即便你不想要做一个赛车游戏本章和下一章的内容仍很有趣),而且一本书也太短,不能覆盖到赛车游戏的方方面面。
在你继续设计你的小小的赛车游戏前,你应该想一想那个游戏应该能干什么。
由于有许多赛车游戏可供参考,尤其是在游戏机平台,不是很难找出这些游戏的需求。
大多数赛车游戏有看上去很棒的汽车并显示道路周围的景色。
游戏本身往往超级简单,但游戏设计者会花大力气优化控制器输入并增加小功能,使赛车游戏更有趣。
在你肯定你的游戏的大致走向后,你将考虑所需的三维模型,纹理,效果和诸如场景和赛道之类的其他数据,这对你的游戏超级重要。
我花了一半以上的开发时刻,只是让场景和赛道渲染正确。
你会在接下来的一章中看到为何要做这么多的工作,为何场景和赛道渲染需要一些新的shader。
当我说:
“很多工作,”只是相对而言。
请记住,那个赛车游戏是在几礼拜内完成的,和RocketCommander一样是个好游戏,固然你不能拿它与那些AAA级游戏比较,毕竟那些游戏需要几年时刻和很多人开发,专门是大型游戏公司开发的游戏机平台的游戏,开发人员往往有100人以上。
而我只是一个人,我想已经做得够好得了。
像在七十年代或八十年代,一个人能够在几天或几周时刻内完成编写、设计和测试他的游戏,这种时期已经结束了,(见图12-1)。
但别急,有了XNA,在短时刻内制作出你的游戏再次变得可能。
若是你想一想,过去游戏的编程环境并无此刻如此友好。
只为了取得屏幕上的一个像素,也需要你自己实现方式。
更别提还要编写很多汇编代码只是为了能在一个简单的硬件配置上正常工作。
游戏比较
赛车游戏大致能够分成三大类。
有时,游戏也被分为更多的类别。
你固然能够想到更多的类别,若是你添加的各类类似的赛车游戏如卡丁车游戏,卡车游戏,摩托车比赛,未来赛车游戏等等,你能够创造更多的类别,但我想维持简单,所以只讨论经典的赛车游戏:
真实赛车:
如GT赛车,ColinMcRaeRally,TestDrive和FormulaOne都是真实赛车的例子。
这些游戏都是高度仿真的,给玩家留下真的在驾驶赛车的印象。
在展会上这些游戏往往和方向盘控制器一路展示,有时在舞台上还有显示器,特殊的赛车座椅,或多台显示器或其他设备以增强真实度。
这些游戏的大体规则是挑战最快圈速,通过可选多种赛车或增加游戏模式使游戏规则变得更复杂。
街头赛车:
如NeedforSpeed,MidnightClub,StreetRacing或Juiced这些游戏在过去几年中变得很流行。
游戏的大体规则仍然是相同的,但拟真度再也不重要。
它更像是在看电影,一切东西都要酷,如此的游戏需要改装过的汽车和很酷的音乐。
它们很受欢迎,尤其是在游戏机平台上。
趣味赛车:
如赛道狂飙,Wipeout,Carmageddon那些再也不把重点放在真实度上的游戏属于这一类。
它们都拥有有趣和疯狂的轨道或改装车,能够射击或做其他疯狂的情形。
你乃至能够把所有疯狂的赛车游戏如CrazyTaxi或侠盗车手也归于这一类别中,这其实已不是真正的赛车游戏了,你只是驱车逛游。
任务再也不是光驾驶汽车,而是完成某些特定的目标。
你也不能仅仅因为它是3D的而把一个冒险游戏称之为3D射击游戏,但有些射击游戏也有冒险成份。
一些如哥谭赛车的游戏可归于不只一个类别。
它们比街头赛车更真实,但也没有像GT赛车或FormulaOne那么高的拟真度,因为你还能够改装你的赛车并驱车穿越街道。
极品飞车也再也不是高拟真的了,无论你撞击到墙上的速度有多快你也无法撞毁你的车,你能够超越其他车辆,逃避警察的追捕,破坏公共财产等,那个游戏变得更像街头赛车。
下面咱们阅读一下这些类别的代表游戏。
GT赛车
最真实的赛车游戏是PlayStation平台上的GT赛车,FormulaOne,EnthusiaProfessionalRacing,科林麦克雷拉力赛等。
大多数游戏有PC平台的版本,有时也有Xbox的版本。
在Xbox平台上街头赛车和趣味赛车比PlayStation平台更多。
总之,我不太了解这些游戏,我通常在完成第一圈前就睡着了。
这种游戏最好去问我兄弟。
我放了一张GT赛车的漂亮图片(见图12-2)。
图12-2
Xbox360平台上此种类别的最流行的游戏可能是哥谭赛车,归功于更多的街头赛车视角,那个游戏仍是有点乐趣的,但即便如此我也没玩多久,几个任务后就有点重复了。
但我必需说,游戏做得专门好,我希望其他经典的赛车游戏也能包括点街头赛车的风格,显然,有一些额外的游戏模式比只是开车兜圈子更好玩。
极品飞车
极品飞车是由EASports出品的一个超级流行的游戏,有许多版本,多到我也无法完全弄清楚数量。
最近的两个游戏是极品飞车地下狂飙(2005年,见图12-3)和极品飞车卡本峡谷(2006年)。
通常所有的极品飞车游戏出此刻所有最新的主机平台和PC上,这使得在每一个平台销量有所下降,但所有平台的销售总和是很可观的。
图12-3
这种游戏有很漂亮的图像和精细的背景。
另外,还有一些额外的游戏模式,漂移过弯和实现特殊技能的奖励分。
你还能够改装你的车,喷上油漆或贴膜等,在车辆改装画面中能够实现那个功能。
赛道狂飙
最后是趣味赛车,我选择赛道狂飙作为代表。
我没选择疯狂赛车游戏,因为它们往往不是一个单纯的赛车游戏,更像是一个射击和赛车游戏的混合物。
在赛道狂飙(见图12-4)中你必需抵达终点,途中有几个检查点,你能够看到你的当前时刻,你上次通过那个检查点是不是进步。
不是很容易抵达终点,有时完成赛道只要几秒钟,你不断地想超越自己的最好成绩或在多人游戏模式中你的对手的成绩。
你常常取得铜牌,但你也想在这条赛道上取得银牌或金牌,这必需要比以前快1-2秒才行。
一会儿后你就就会在同一赛道上玩上30遍只是为了快上几秒钟。
那个游戏很容易上瘾,是此种类型的一个超级成功的游戏。
图12-4
你不会看到其他游戏有这么多的循环和机缘在关卡中飞跃。
关卡各不相同,你能够花几分钟的时刻去测试一个赛道,或几个小时完成所有的单人赛道。
XNA赛车游戏
让咱们谈谈你的赛车游戏的设计方向。
我更喜欢趣味赛车,因为像在TestDrive游戏中驾驶汽车老是让我感觉枯燥。
可是,许多人喜欢真实赛车游戏。
我的弟弟是真实赛车和街头赛车的爱好者,不然我将完全不了解这种类型的游戏,除非是在杂志或游戏展览会上看到。
总之,我想开发趣味赛车,因为制作拟真图形真的很难。
混合一点街头赛车风格不错,能使游戏的外观和声音更酷。
最近我最喜欢的游戏规则是赛道狂飙,只是让你疯狂地驾车通过圆轨道,坡道,洞等等。
那个游戏的规则是尽快地抵达终点,但我喜欢变得愈来愈难。
慢慢驾驶无法让你通过任何圆轨道或某些斜坡,若是你从赛道上掉下来就必需从头开始。
它更像是一个驾车转圈圈的街机游戏。
最近发布的赛道狂飙仍有很漂亮的图形。
它们可能不像这里提到的其他游戏那么真实,但作为一个趣味赛车这并非那么重要。
有些技术仍然超级好,赛道狂飙解决了许多困难,如处置这么多的道路片断,在关卡中看得更远。
在如极品飞车或哥谭赛车游戏中你很难看到此刻的道路片断。
你要面临着一样的问题,因此,我要确保场景和赛道渲染尽可能地快,若是达到了帧的上限,能够忽略一些以达到优化的目的。
场景绘制
在前一章你已经看到了在.x模型的帮忙下用简化的方式来产生三维场景。
你第一创建了diffuse纹理,并由此成立了一个法线贴图,最终添加了一个高程图为XNAShooter生成了峡谷。
对于那个游戏你仍然要利用一个超级简化的办法去渲染场景,因为开发时刻很短,而且制做一个高精度的场景渲染引擎往往要花费几个月的时刻。
如ArenaWars游戏中利用的场景引擎,支持超级大的场景,但它从来没被利用在游戏中,在不同的硬件配置中进行优化要做大量的工作,尤其是还要支持24中不同类型的地面纹理。
为了维持简单,那个赛车游戏只利用一个超级大的地面纹理,但你也需要一个法线贴图和一个额外的细节纹理用来添加一些细节,专门是当你离地面超级近时,这种情形通常发生在你停留在超级靠近场景的时候。
一开始我制作了一个4096×4096的纹理,但它很难被更新,包括法线贴图也是。
未紧缩的diffuse纹理约有64MB,另外还要64MB用于法线贴图。
想像一下在一台只有1GB内存的电脑上创建10个或更多的这种纹理,结果必然很糟。
即便紧缩为一个DXT5纹理,4096×4096的法线贴图仍有约12MB,单单载入进程就很恼人。
另一个让我舍弃利用4096×4096纹理的原因是XNA中的内容管道,当它把这么大的一个纹理转换到.xnb内容文件时耗时很长。
我缩小到2048×2048纹理,这看起来与4096×4096几乎一样好,但只占用1/4的大小和载入时刻。
法线贴图乃至降低到1024×1024,因为它看起来没多大不同。
另一个不利用大尺寸纹理的原因是微软的Xbox360显存大小有限(64MB),你不该载入太多的东西或太大的纹理,不然性能将大大下降。
不要成立一个超大尺寸的纹理,作为替代,我添加了一个细节纹理,使镜头拉近时场景看起来更好,在下面几页会讨论到如何绘制这些纹理。
纹理
第一,你需要一个高程图,并明白你的场景有多大。
最初我想让一个场景的texel(纹理像素,纹理的1个像素)是1米(3.3英尺),那么4096×4096纹理使整个场景大小为4×4千米大(约×2.5英里)。
在纹理减少到2048×2048时场景大小维持不变,则此刻每一个纹理像素是2×2米。
那么你的场景从哪里取得高度值?
自己画可能不会超级好,你也没有一个好的程序帮你做这件事,也肯定没有足够的时刻编写一个自概念场景高程图编辑器。
一个好主意是在互联网上寻觅并利用现成的高程图,有很多资源能够利用(国家地理,美国航天局NASA,其中乃至还有其他行星的高程图)。
对于那个赛车游戏我想有一些山。
对测试来讲足够好了,但后来我需要山围绕在场景周围,所以我必需要修改高程图,使场景中间是座大山,其他山体围绕在边界上。
最后的高程图中能够看图12-5。
请注意,那个游戏利用的高程图只有257×257个像素,因为在Landscape类中只能生成257×257个(66049个)极点的网格,即256*256*2个多边形(约13万个多边形)。
太多多边形会极大地拖慢渲染速度,但处置130000多边形对今天的显卡来讲不是大问题,Xbox360也能处置得专门好(仍维持在数百帧每秒)。
图12-5
你可能会注意到,高程图上用于城市地域的平坦地域,只是简单地把所有建筑物和物体放置在相同的高度上。
中间的白色区域是大山,围绕在地图边界上的白灰色部份表明边界的山体。
那个高程图与一个有一点起伏的纹理产生法线贴图。
另外,你也能够像上一章一样混合diffuse贴图,可是因为我要频繁地改变diffuse贴图致使法线贴图往往再也不受到diffuse贴图的影响。
图12-6显示了利用了diffuse贴图和法线贴图的游戏场景。
图12-6
请注意,对这些纹理我尝试了很多次直到它们成为此刻那个样子,我并非完全满意,但你必需适可而止,尤其是当你没有更多的时刻进行改良时。
例如,法线贴图从远处看很棒,但靠近时缺少转变,或许通过更好地匹配diffuse纹理能够加以改良。
无论如何,在游戏中它们看起来专门好,我也没有听到任何抱怨。
最后,在你靠近场景时还添加了细节贴图。
你不会马上注意到细节贴图,但图12-7显示了利用与不利用细节贴图之间的令人信服的不同。
在那个赛车游戏中有这么大的一个场景,并允许拉近镜头,若是没有细节纹理,画面表现是不好的。
图12-7
渲染
若是你打开RacingGame的项目,你能够看到很多从以前章节而来的类,但还有两个新的命名空间将会在本章中讨论:
Landscapes和Tracks。
在Landscapes命名空间只有一个类Landscape(见图12-8),它负责渲染场景,包括所有在场景上的物体,所有赛道和赛道上的物体,大体上是除你的车之外的所有东西。
在Misson类你只是挪用Landscape的Render方式执行所有的渲染。
对于阴影映射有几个辅助方式可用,有关阴影映射的细节将在第14章中讨论。
图12-8
所有场景物体都在Landscape类被创建是被成立,尤其是在Track类的构造函数中,它被用在了Landscape类内部。
你马上就可以够看到本游戏中利用的3D模型。
要渲染场景,你第一必需做的是在构造函数中产生它。
在你查看构造函数前你应看看Landscape类中的TestRenderLandscape单元测试,在类实现前应先写单元测试。
你也注意到了其他单元测试,GenerateLandscapeHeightFile会为场景高程图产生一个关卡文件,并生成一个特殊的内容文件,那个方式和在RocketCommander中的一样,因为在Xbox360中加载位图数据是不可能的。
os=pos;
Readmybook:
D
Vector3edge1=pos-CalcLandscapePos(x,y+1,heights);
Vector3edge2=pos-CalcLandscapePos(x+1,y,heights);
Vector3edge3=pos-CalcLandscapePos(x-1,y+1,heights);
Vector3edge4=pos-CalcLandscapePos(x+1,y+1,heights);
Vector3edge5=pos-CalcLandscapePos(x-1,y-1,heights);
vertices[index].normal=(
(edge2,edge1)+
(edge4,edge3)+
(edge3,edge5));
angent=(edge1);
0.0f1.0fv=newVector2(
y/(float)(GridHeight-1),
x/(float)(GridWidth-1));
}255.0f
4096米
2米
os,
[(num+1)%;
}
floatdistance=(p2,p3);
intnumberOfIterations=
(int)(NumberOfIterationsPer100Meters*(distance/100.0f));
if(numberOfIterations<=0)
numberOfIterations=1;
Vector3lastPos=p1;
for(intiter=0;iter { TrackVertexnewVertex=newTrackVertex( (p1,p2,p3,p4, iter/(float)numberOfIterations)); (newVertex); } 档案不支持spline,.fbx文件也不行。 即便他们能导出spline,你仍需要做大量的工作从赛道中提取数据,因为在XNA中从导入的模型中取得极点数据是不可能的。 我决定利用目前超级流行的Collada格式,这种格式允许在不同的应用程序间彼此导入导出3D数据。 相较其他格式,Collada的主要优势是一切都存储为XML格式,从导出的文件上你能够很容易看出哪个数据对应哪个功能。 你乃至不需要寻觅任何文件,只需寻觅你需要的数据并提取它(在这里,你只需寻觅spline和辅助数据,其余的对你并非重要)。 对游戏来讲Collada不是一个真正优秀的导出格式,因为它通常贮存了太多的信息,而且XML数据仅仅是一堆文字,所以比起二进制文件,Collada文件的尺寸也大得多,出于那个理由,而且我也不能在XNAStarterKit中利用任何外部数据格式,所有的Collada数据在TrackImporter类中被转换为内部数据格式。 利用自己的数据格式加速了加载进程,并确保没有人能创建自己的赛道。 嘿,等一下,你不希望他人创建自己的赛道吗? 我的确希望这变得更易,你需要3DStudioMax才能创建或改建赛道并非好。 我必需在以后实现某种方式能够导入和创建赛道。 导入赛道数据 为了使装载Collada文件变得容易些利用了一些辅助类。 第一,XmlHelper类(见图12-16)能帮你加载和管理XML文件。 图12-16 ColladaLoader类只是一个很短的类,它加载Collada文件(只是一个xml文件),让利用XmlHelper方式的派生类更易。 ●ColladaTrack是用来加载赛道本身(trackPoints),其他辅助对象如widthHelpers可使赛道变宽和变窄,roadHelpers用于隧道,棕榈树,路灯等路边的物体。 最后所有的场景物体在你接近他们时被显示(因为在场景中有大量的物体)。 ●ColladaCombiModels是一个小的辅助类,它用于一次加载并显示多个模型,只需设置一个包括多达10个模型的组合模型,这十个模型有不同的位置和旋转值。 例如,若是你想放置一个具有建筑物的城市区域,只需利用文件,若是你需要一些棕榈树外加几块石头可利用文件。 想对加载进程了解得更多,能够利用TrackLine和Track类中的单元测试,但更重要的查看ColladaTrack构造函数本身: publicColladaTrack(stringsetFilename) : base(setFilename) { if("-spline")==false) thrownewException("TheColladaTrackfile"+Filename+ "doesnothaveasplinegeometryinit.Unabletoload"+ "track! "); Pleaseexportagain"+ "withoutbakingmatrices.Unabletoloadtrack! "); XmlNodesplineTranslateNode=( "translate"); XmlNodesplineScaleNode=( "scale"); Vector3splineTranslate=; if(splineTranslateNode! =null) { float[]translateValues= ( splineTranslate=MaxScalingFactor*newVector3( translateValues[0],translateValues[1],translateValues[2]); } Renderrestofroadmaterials] }Thishappensbecauseweneedtorender Thisstillhappens Bettertohaveanotsoroundtrack,butat roadVertices=newTangentVertex[*5]; Fortheroaditselfweonlyneedverticesfortheleft roadVertices[num*5+0]=points[num].RightTangentVertex; roadVertices[num*5+1]=points[num].MiddleRightTangentVertex; roadVertices[num*5+2]=points[num].MiddleTangentVertex; roadVertices[num*5+3]=points[num].MiddleLeftTangentVertex; roadVertices[num*5+4]=points[num].LeftTangentVertex; }Wehave1segmentlessthanpointsbecause texint[]indices=newint[-1)*8*3]; intvertexIndex=0; for(intnum=0;num<-1;num++) { for(intsideNum=0;sideNum<4;sideNum++) { Polygon indices[num*24+6*sideNum+0]=vertexIndex+sideNum; indices[num*24+6*sideNum+1]= vertexIndex+5+1+sideNum; indices[num*24+6*sideNum+2]=vertexIndex+5+sideNum; Polygon indices[num*24+6*sideNum+3]= vertexIndex+5+1+sideNum; indices[num*24+6*sideNum+4]=vertexIndex+sideNum; indices[num*24+6*sideNum+5]=vertexIndex+1+sideNum; }verticesare aregeneratedattheendofthismethod] }//GenerateVerticesAndObjects(landscape) 在编写那个代码时我写了很多注释。 第一部份生成一个专门大的切线数组,数组大小是TrackLine类中的赛道极点的5倍。 此数据直接传递到极点缓冲区,然后被用于构造多边形的索引缓冲区。 每一个道路片有8个多边形(由四部份组成,每部份两个多边形),因此该索引缓冲区大小是赛道极点索引的24倍。 为了确保仍然能够正确利用所有这些索引,必需利用int类型替代short类型,以前我利用short类型是因为如此做能节省一半内存。 但在这种情形下有超过32000个索引(专家关卡的赛道有2000个道路片,它的24倍已达到48000个索引)。 因为赛道是自动生成而不是手工产生,所以你需要许多迭代点,若是你没有足够的迭代点会致使重叠错误,如此就无法使赛道足够圆滑(见图12-18)。 图12-18 你可能会问,为何是四个部份产生每
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- xna 游戏 制作 教程 12 创建 场景 赛道