最近项目中需要用到闪电这个效果,在网上找到的闪电效果有两种:一种是官网给的捕鱼达人的demo,一种是自己用layer的draw函数画线实现。
这2种效果貌似都不好办,先说官网给的捕鱼达人的闪电效果吧,花了一部分的时间去研究了一下,官网的捕鱼达人的电光特效是用2dx 3.2写的,3.2的引擎里面有不少新东西,而且中间也用到shader,而且一个闪电效果的代码量居然有3个类。很庞大的有木有。因为项目需要,而画线有一个问题(待会儿说),我也尝试把3.2版本的闪电效果改成3.0的,但是出于能力有限,以失败告终。....
然后就是layer的画线,这里面的问题是,layer虽然画出线了,效果是实现了,但是draw函数画出的线永远是处于最底层,网上也有资料说把其他精灵的zorder设为负数就能看到,我也尝试过,表示不行。之后在stackoverflow上看到这样的一篇资料:
下面给上我的源码,虽然我也没弄清楚为何要这么用,但是对于新手来说,先会用就行了。
Lightning.h 文件
/****************************** * * 创建闪电层 * ******************************/ #include "cocos2d.h" USING_NS_CC; class LightningLayer :public Layer{ public: /** 创建闪电层 参数1:子弹的坐标 参数2:敌人的坐标 **/ static LightningLayer* create(Point bulletPos,Point enemeyPos); /** layer层的draw方法 **/ void onDrawPrimitives(const kmMat4 &transform,bool transformUpdated); /** * 父类Layer的draw函数 */ void draw(Renderer *renderer,const kmMat4& transform,bool transformUpdated); /** 闪电的动作 **/ void showAction(); /** 画闪电 **/ void drawLighting(Point bulletPosition,Point enemeyPosition,float displace); private: bool needToBreakOutShanDian ; Point bulletPosition,enemeyPosition; float curDetail; CustomCommand _customCommand; };
#include "Lightning.h" LightningLayer* LightningLayer::create(Point bulletPos,Point enemeyPos) { LightningLayer* lightning = new LightningLayer(); if (lightning && lightning->init()){ lightning->bulletPosition = bulletPos; lightning->enemeyPosition = enemeyPos; lightning->needToBreakOutShanDian = false; lightning->curDetail = 5.0f; return lightning; } CC_SAFE_DELETE(lightning); } void LightningLayer::onDrawPrimitives(const kmMat4 &transform,bool transformUpdated){ //画线的颜色 ccDrawColor4B(225,255,220,255); //线条宽度 glLineWidth(2); kmGLPushMatrix(); kmGLLoadMatrix(&transform); //调用函数 drawLighting(bulletPosition,enemeyPosition,100); } void LightningLayer::draw(Renderer *renderer,bool transformUpdated) { _customCommand.init(_globalZOrder); _customCommand.func = CC_CALLBACK_0(LightningLayer::onDrawPrimitives,this,transform,transformUpdated); renderer->addCommand(&_customCommand); } /** * 闪电的动作 */ void LightningLayer::showAction() { //暂留 } /** * 画闪电 */ void LightningLayer::drawLighting(Point bulletPosition,float displace){ if (displace < curDetail) { DrawPrimitives::drawLine(bulletPosition,enemeyPosition); } else { float mid_x = (bulletPosition.x + enemeyPosition.x) / 2; float mid_y = (bulletPosition.y + enemeyPosition.y) / 2; mid_x += (CCRANDOM_0_1() - .5)*displace; mid_y += (CCRANDOM_0_1() - .5)*displace; Point midPoint = Point(mid_x,mid_y); drawLighting(bulletPosition,midPoint,displace / 2); drawLighting(enemeyPosition,displace / 2); } }
使用方法:
bulletPos = bullet->getPosition(); enemyPos = enemy->getPosition(); LightningLayer *lightning = LightningLayer::create(bulletPos,enemyPos); this->addChild(lightning,2);