感觉CEGUI确实不想很多商业成熟的SDK,有些地方的表现不尽如人意,但是毕竟是个开源项目,使得我们能根据自己需求定制自己的功能。但在定制需求之前,我们需要对CEGUI进行一个比较详细的了解才能够得心应手的定制需求。下面就将学习CEGUI过程中遇到的重点难点罗列起来,方便自己和网友一起学习。
- Affector元素(Layout文件)
如:<Affector property="Visible" interpolator="Stringg">
动画系统中的Affector,在写CEGUI的 .animation 文件的时候,我们需要要了解每个XML标签的含义。其中Affector有些地方需要注意,其属性字段 interpolator 表明要插值的类型,其中包含很多CEGUI内置类型,如UVector,UDim之类,同样也包含String和Bool。Affector中可以防止KeyFrame,每个KeyFrame可以设置Affector所影响的属性。我们知道两个KeyFrame之间是会进行插值的,对于String,Bool类型,CEGUI到底是怎么插值呢?查看CEGUI::StringInterpolator 我们会发现,他们在两帧中间位置进行值的改变。String StringInterpolator::interpolateAbsolute(const String& value1, const String& value2, float position) { return position < 0.5 ? value1 : value2; }
也就是说,假设我们在第 0 秒的位置,写入关键帧,设置窗口图片为A,在第 2 秒的位置,写入关键帧,设置窗口图片为B。在实际表现上,CEGUI会在第 0 秒的时候设置窗口图片A,然后在第 1 秒的时候设置图片B。这就导致和一般的关键帧设置不一样。
在不修改源码的基础上,我们可以采用比较”狗血“一点的做法,来达到我们在第 0 秒和第 2 秒设置图片的方法。那就是:在第 0.9 秒的时候设置图片A,在第 1.1秒的时候图片B,这样能确保第 0 秒到第 0.9 秒都是A图片,然后在 第 1.0 秒的时候跟换成图片B。
当然如果可以的话,尽量修改源码,将CEGUI::StringInterpolator和其他不符合一般标准的插值器改换成到关键帧的位置更新,这样会比较方便。
- Area元素(Layout文件)
<Area> <Dim type="LeftEdge"><UnifiedDim scale="1" type="LeftEdge" /></Dim> <Dim type="TopEdge"><AbsoluteDim value="0" /></Dim> <Dim type="Width"><UnifiedDim scale="1" type="Width" /></Dim> <Dim type="Height"><UnifiedDim scale="1" type="Height" /></Dim> </Area>
我对于其中 <Dim type="LeftEdge"><UnifiedDim scale="1" type="LeftEdge" /></Dim> 一直有疑问,就是这个比例最终最终换算成绝对值会是对少?一般比例都是以父窗口尺寸为参考对象,但是这里有个 type = "LeftEdge",这就让我很担心,是以窗口左坐标值为参考,但实际上追踪代码发现,只要遇到比例,直接回去找父窗口尺寸来做参考。float UnifiedDim::getValue_impl(const Window&, const Rect& container) const { switch (d_what) { case DT_LEFT_EDGE: case DT_RIGHT_EDGE: case DT_X_POSITION: case DT_X_OFFSET: case DT_WIDTH: return d_value.asAbsolute(container.getWidth()); break; case DT_TOP_EDGE: case DT_BOTTOM_EDGE: case DT_Y_POSITION: case DT_Y_OFFSET: case DT_HEIGHT: return d_value.asAbsolute(container.getHeight()); break; default: CEGUI_THROW(InvalidRequestException("UnifiedDim::getValue - unknown or unsupported DimensionType encountered.")); break; } }