第一章 第四节 接口:整合契约

翻译 2007年10月11日 11:42:00

如我前面所说,这将是一个面向对象的游戏引擎。C++惯例,为引擎的多样的类使用多重继承来提供预先定义的行为集合。

 

虽然这是一个强大的技术,但是有它的危险。如果一个类继承两个定义了同样的属性或者方法的基类,这就会产生问题。同样的名字将会冲突,产生一个编译器错误。C#通过不允许多重继承来解决这个问题,只能继承一个基类。为了取得多重继承的好处而又消除危险,C#使用interface机制。如果你熟悉C++,你可以把interface看作纯虚或者抽象基类。C# interface可以定义方法和属性,但是不包含他们的实现。一个C#类可以继承任意所需的interface。实现接口定义的每一个方法和属性是子类的责任。如果被继承的接口某个方法或者属性没有被提供,编译器会报错。

 

类实例在运行时进行查询,以决定他们是否支持某一个给定的接口。这就允许我们在一个包含不同类型的对象集合中,逐个调用这些对象支持的接口方法。既然每个类可以为接口方法提供自己的实现,那么可以自由的为一个类提供唯一的和恰当的实现。作为一个例子,让我们看看两个类,他们实现一个声明了Render方法的接口IRenderable。这个接口稍后就会详细讨论,眼下暂且认为一个类使用这个方法来把当前的对象恰当的绘制到屏幕上。

 

对于这个例子,我们假设其中一个对象是billboard,由两个三角形组成,表示一棵树;另外一个对象是一个室外游戏的整个地形模型,由成百上千的三角形组成。很容易了解需求,从而这两个类实现这个方法必定是不同的。Billboard仅仅需要绘制两个只是朝向视点的三角形,然后贴上树的纹理。另一方面,地形类首先必须确定哪些三角形是可见的(当前没有硬件可以每一帧都实时的渲染整个世界这么大尺寸的地形),然后变换顶点以适合此视点的纹理,然后再绘制和贴纹理。

 

让我们看看将要使用在这个游戏引擎中的更重要的一些接口。随着这本书的进度,我们将看到这些接口的各种不一样的实现。这些接口的代码如清单1-4所示。

 

第一个接口是前面提到的IRenderable接口。一个类如果实现这个类,则可以使用方法Render绘制自己到屏幕。这个方法的参数是摄像机定义,定义了当前视点,这就是任何需要渲染自己的类实现此接口所需要的所有信息。

 

第二个接口是ICullable,任意不是总是需要绘制自己的类需要实现此接口。这个接口定义了两个属性。这些属性管理了对象(不论对象需要渲染或不需要)的剔除状态。第一个属性是Culled,它负责把剔除状态标志置为不剔除状态。第二个属性定义成只读布尔变量IsCulled,通过Get方法来读写它的值。对于游戏效能很重要,任何图形对象都支持这个接口。前面提到的地形,对象中的三角形数量如果不较少到仅仅可视的三角形属性,就会是图形卡负载过重。

 

下一个接口是ICollidable接口。任何类,它表示的对象需要与其他对象发生物理碰撞,则应该支持这个接口。这个接口的属性和方法支持两个对象之间的碰撞检测。接口定义了几个属性,它们从几个级别上暴露了对象的几何信息。为了这个接口能起作用,肇事的两个对象都需要支持这个接口。第一个属性是CenterOfMass,它是一个Vector3类型。此属性一世界坐标定义了对象的中心位置。第二个属性是BoundingRadius。这个值定义了对象的最小外接球。

 

此接口定义的第一个方法是CollideSphere,它需要一个对象的引用作为参数。此方法在两个对象之间执行球碰撞检测。这是最快速的碰撞检测方法,因为只需要检测对象之间的距离与两个对象包围球半径之和做对比。这是低精度的碰撞检测,因为它有可能会误报,如果两个对象靠近,但是没有任何多边形相交或者接触,而它有可能会检测到已经碰撞。如果这个对象既不是玩家,并且两个都距离视点足够远,或者位于视线之外,那么这个方法就足够了。然而,我通常使用这个接口的第二个方法。CollidePolygon方法,它需要三个Vector3变量作为参数。这个方法被模型里的每个多边形调用,直到检测到碰撞或者所有多边形都返回否定的布尔值。如你所见,这将非常耗费计算。不幸的是,如果我们需要百分之百精确的碰撞检测,我们必须使用这个扩展,即第二个方法。

 

下一个是IDynamic接口。这个接口支持任意的对象随着时间的流逝移动或者改变。此接口只定义了一个方法:Update。此方法只接受一个浮点参数,即记录对象上一次更新到现在的毫秒数。使用这个方法整合对象的位置和角度,以及动画的适当帧,或者两者。此接口的属性都与物理动力学有关,我会在第十章讲解。

 

最后一个我们目前要将的接口是ITerrainInfo。任意需要查询地形信息的类实现这个接口。地形信息对于在地面上移动或者在地形表面之上活动的对象是非常重要的。此接口第一个方法是HeightOfTerrain,它返回指定位置地形的Y坐标值,单位是英尺。防止对象在低于这个值之下移动,对象在表面上,而不是在地下穿行。第二个方法是HeightAboveTerrain,这是第一个方法的扩展,他返回作为坐标位置传入的Y轴值与地形高度之间的差异。此方法对于在地面上飞行而不至于和地表相撞的对象非常重要。下一个方法是InLineOfSight,它返回一个正树值(true),如果在作为参数提供的两个点之间存在不被阻隔的视线。最后一个方法是GetSlope,它被任何对象(例如陆地车辆)来匹配停在斜坡上的角度。如你在清单1-4中看到的,此方法接受对象的位置和运动方向。运动方向使此方法返回一个attitude,旋转这个物体,使得匹配对象运动方向。

 

清单1.4:接口定义

public interface IRenderable

{

   void Render(Camera cam);

}

 

public interface ICullable

{

   bool Culled { set; }

   bool IsCulled { get; }

}

 

public interface ICollidable

{

   Vector3 CenterOfMass { get; }

   float BoundingRadius { get; }

   bool CollideSphere ( Object3D other );

   bool CollidePolygon ( Vector3 Point1, Vector3 Point2, Vector3 Point3 );

}

 

public interface IDynamic

{

   void Update( float DeltaT );

}

 

public interface ITerrainInfo

{

   float HeightOfTerrain( Vector3 Position );

   float HeightAboveTerrain( Vector3 Position );

   bool InLineOfSight( Vector3 Position1, Vector3 Position2 );

   Attitude GetSlope( Vector3 Position, float Heading );

}

 

 

【老罗笔记】异类(Outliers)

序 罗赛托之谜意大利福贾省的罗赛托的人们患心脏病的死亡率相当低,沃尔夫和布鲁恩对什么是那里人们的健康根源做过研究(友善和谐的社区)。本书将对什么是成功的根源进行研究。=================...
  • kesalin
  • kesalin
  • 2014年04月01日 09:49
  • 10337

计算机操作系统第四版第四章课后习题答案

共享信息,共同进步。
  • shazh520
  • shazh520
  • 2016年12月06日 08:40
  • 8377

《区块链学堂》第四课:以太坊高级数据类型和代币合约(附课程视频)

成功推出三期课程后,本周日区块链学堂推出了第四课:以太坊高级数据类型和代币合约。 本期介绍了Address, Mapping等以太坊高级数据类型和代币合约,并且当场实战编程,创造出我们自己的数字货币...
  • ethchinese
  • ethchinese
  • 2017年04月12日 14:51
  • 1672

计算机操作系统第一章第四节

  • 2011年12月24日 11:11
  • 1.81MB
  • 下载

第一章第四节 不再当“瞎忙族”——《与时间同行》(5)

身边不少朋友常抱怨说“很忙、很累、很少加薪、一身老年病!”但一直以来,我的观点是:工作是为了让我们更好的生活。不要因为工作牺牲了生活。工作中多加思考,莫当瞎忙族。 管理好时间,先从改变瞎忙的状态开始...
  • jobchanceleo
  • jobchanceleo
  • 2012年09月10日 08:45
  • 2530

读书笔记第一章第四节1.4各存储引擎直接的比较

存储引擎是MySQL核心 数据库与传统文件系统的最大区别就是是否支持事务 show engines  查看当前MySQL支持的存储引擎 从表的大小...
  • zhexienianlai
  • zhexienianlai
  • 2017年01月10日 19:51
  • 117

第一章 遇见HADOOP 第四节 超越批处理(hadoop:the definitive guide)

MapReduce根本上是一个批处理系统,它并不适用于交互式分析。你不可能在几秒 或更少的时间内得到查询结果。典型的查询需要耗时几分钟甚至更长,所以它最好是 线下使用,不需要一个人坐在那里等循环处理的...
  • fkbush
  • fkbush
  • 2016年02月24日 09:37
  • 481

爱贝云计费接口契约鉴权说明

爱贝云计费契约鉴权功能说明:提供契约型商品的应用,应用可以在用户使用商品时调用本接口进行契约的鉴权。对于包时长类型的契约,鉴权成功会返回契约的有效截止时间;鉴权失败则返回错误码。对于包次数类型的契约,...
  • iapppay
  • iapppay
  • 2015年10月20日 17:27
  • 753

WCF接口、抽象类等数据契约传递方式

WCF接口、抽象类等数据契约传递方式
  • QQ282030166
  • QQ282030166
  • 2016年11月08日 17:51
  • 605

wcf之二(接口契约式编程思想)

wcf接口契约式编程思想
  • jielizhao
  • jielizhao
  • 2015年01月26日 10:37
  • 737
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:第一章 第四节 接口:整合契约
举报原因:
原因补充:

(最多只允许输入30个字)