Fez*_*vez 12 c++ qt qgraphicsview
我目前正在构建一个小型的实时策略2D引擎.而且我想知道如何处理那些最终会让我的屏幕变得更加精彩的精灵.
仅供参考,我不是针对任何AAA级别的,我只是想尝试实现一些机器学习方法.因此,我选择了魔兽争霸II放弃软件ISO,无耻地采取了一些图形,我在第一个问题上摔倒了.
http://img263.imageshack.us/img263/1480/footman.png
正如你上面所看到的,即使是魔兽争霸II的简单仆人也有大约50个精灵用于动画.这是很多.它会经常改变精灵.(黑线只是检查我的alpha通道是否正确)
因此,最后一个问题:如何有效地实现不断变化的QGraphicsObject?如何有效地实现反复更改其外观的QGraphicsItem?
我是否只是重载paint()QGraphicsPixmapItem 的方法并继续更改屏幕上使用的Pixmap?它会导致一些"口吃"吗?我听说有时候,创建一个所有像素图,隐藏所有像素图并在需要时复制它们是明智/可能的.(复制比其他操作便宜)还有其他任何聪明的想法吗?
感谢您的任何意见!(RTS引擎教程,复杂性等等......)
Den*_*ant 15
(我先从一般的想法开始,然后会有一个可能的Qt实现)
我不知道WCII精灵是如何存储的,但你应该使用精灵表(如果需要的话自己构建).与此工作表相关联,您将获得一些精灵的描述,该精灵至少包含动画列表,并且对于每个动画,它的标识符/名称以及帧列表.
您描述这些动画帧的详细程度取决于您,但必须至少包含要显示的精灵表的矩形.
作为一个例子,看看这个精灵表(显然没有优化,但举个例子,它没关系:)).这是相关的动画描述(第12到39行).所有动画都不包括在内,但你会明白这一点.
你可以看到"空闲"动画是由3帧构成的,这些子节点与精灵表中的前3帧相匹配.与子矩阵相关联,此示例中还有2个信息:
现在,你将如何在Qt中实现它?
动画的描述文件格式完全取决于您,但我建议使用一些层次结构文件格式.由于Qt提供了XML解析器,因此它可以是完美的.如果您习惯于提升并喜欢像JSon这样的轻量级格式,那么可以使用boost.ptree来解析无关紧要的XML/JSon文件,并使用通用接口从中提取数据.
对于图形表示,您必须使用一些类:
我将从描述TimerProxy角色开始.它的作用是发送时间更新消息.它在这里是因为Qt Graphics对象不提供任何类型的"定时"更新(即更新(float dt),其中给出的dt是您最喜欢的时间单位).您可能想知道为什么我们使用代理类来处理时间.这是为了限制活跃QTimer的数量; 如果你有每个AnimatedSprite中的一个,你最终可能会有大量的计时器活跃,这显然是一个很大的禁忌.
所以它履行了两个角色:
现在,对于解决方案的核心:AnimatedSprite.该类具有以下角色:
在初始化时,您应该给它以下信息:
在运行时,更新方法如下所示:
在timeUpdated(int)插槽中,您希望更新已用时间,并检查是否应使动画继续下一帧.如果是这样,只需将当前帧指针更新为新帧.
最后,要渲染,您只需重新实现QGraphicsItem :: paint(...)方法来绘制当前的子对象,它可能如下所示:
void AnimatedSprite::paint(QPainter *painter,
const QStyleOptionGraphicsItem * /*option*/,
QWidget * /*widget*/)
{
painter->drawImage(mCurrentAnim.mCurrentFrame->mOrigin,
mSpriteSheet,
mCurrentAnim.mCurrentFrame->mSubRect);
}
Run Code Online (Sandbox Code Playgroud)
希望有所帮助(并且不是太大,哇:s)