最近需要使用【 opengl 】绘制一个闪电效果,在网上翻了好多资料,最后在一个网站上找到了一个比较好的样子,参考了它的思路。
参考网站链接【 http://krazydad.com/bestiary/bestiary_lightning.html 】。
由于链接中的实现方式采用递归,当点数很多的时候很容易出现堆栈溢出的问题,这里作者修改成了for循环。
下面作者备份下代码,比较简单的一个实现,采用cococs2d-x:
1)首先定义两个类,一个是闪电中的单独线段类,一个是整条闪电类:
class SegmentNode: public cocos2d::CCObject |
class ThunderNode: public cocos2d::CCObject |
_pSegmentNodeArray = new cocos2d::CCArray; |
cocos2d::CCArray *_pSegmentNodeArray; |
void setColor( int r, int g, int b, int a) |
_pSegmentNodeArray->release(); |
_pSegmentNodeArray = NULL; |
2)定义随机数方法,并通过随机数来对Y轴坐标进行随机设置:
#define MY_RAND ((rand()%100 - 50)/50.0f) |
void ThunderLayer::internelGenerateThunderNode(ThunderNode *_pThunderNode, float x1, float x2, float y, float qiangdu, float offset, float jiange) |
for ( float pos_x = x1 + jiange; pos_x <= x2; pos_x += jiange) |
float pos_y = y + MY_RAND * qiangdu; |
SegmentNode *pn = new SegmentNode; |
pn->start = ccp(pos_x_last,pos_y_last); |
pn->end = ccp(pos_x,pos_y); |
pn->offset = MY_RAND * offset; |
_pThunderNode->_pSegmentNodeArray->addObject(pn); |
3)调用随机数方法来生成闪电数据:
void ThunderLayer::generateThunderNodes( float dt) |
while (_pThunderNodeArray->count() > 0) |
CCObject *obj = _pThunderNodeArray->lastObject(); |
_pThunderNodeArray->removeLastObject( false ); |
ThunderNode *_pThunderNode = NULL; |
for ( int times = 5; times > 0; times--) |
_pThunderNode = new ThunderNode(); |
_pThunderNode->lineWidth = 2 + MY_RAND * 1; |
_pThunderNode->setColor(128 + MY_RAND * 127,128 + MY_RAND * 127,128 + MY_RAND * 127,255); |
internelGenerateThunderNode(_pThunderNode,10,300,100 + MY_RAND * 3, 8, 10,10); |
_pThunderNodeArray->addObject(_pThunderNode); |
4)在draw函数中绘制:
void ThunderLayer::draw() |
CCObject *_pPointNodesObj = NULL; |
CCARRAY_FOREACH(_pThunderNodeArray, _pPointNodesObj) |
ThunderNode *_pThunderNode = (ThunderNode *)_pPointNodesObj; |
ccDrawColor4B(_pThunderNode->color[0],_pThunderNode->color[1],_pThunderNode->color[2],_pThunderNode->color[3]); |
glLineWidth(_pThunderNode->lineWidth); |
CCARRAY_FOREACH(_pThunderNode->_pSegmentNodeArray, pnObj) |
SegmentNode *pn = dynamic_cast <SegmentNode*>(pnObj); |
ccDrawLine(pn->start,pn->end); |
5)通过不停的调用【 generateThunderNodes 】方法来刷新闪电的数据:
this ->schedule(schedule_selector(GameOverLayer::generateThunderNodes),1.0f); |
发表评论