cocos2dx 游戏当中的战争迷雾

使用cocos2dx的tilemap制作了个斜45度的rts游戏,这东西战争迷雾怎么可能少了,于是乎就琢磨怎么做一个。

最开始的想法很简单,建立一个二维数组,里面清0,在你的视野的地方放1。

继续用tilemap来实现,新建一个层里面放入50%透明度的瓦片。

当二维数组放1的时候相对应的瓦片setVisable(false)。

很简单的就实现了效果。

详细做法可以参照 笨木头 同学的详细教程。


但是这个做法有一个很大的问题。运行效率非常坑爹啊~~

地图小的时候,没什么影响。但是当地图变大的时候。。。我的地图大小超过了100*100.那么绘制顶点就好超过10000+.虽然绘制次数不多,但是顶点非常多。非常影响效率。

于是就琢磨有没有替代的方法。就参考unity3d的Fog of War那个shader做了现在这个。

原理参考

http://blog.csdn.net/xoyojank/article/details/12259161

http://shallway.net/blog/fog-of-war-shader%E6%88%98%E4%BA%89%E8%BF%B7%E9%9B%BE/

原作是利用的shader来完成的。我也是图省事直接用的Texture2D的可以利用数据来生成一个纹理。然后每一帧更新一次纹理。再把纹理放大,与tilemap重合,就实现了战争迷雾的效果。

TextureSprite.h

#ifndef __TextureSprite_SCENE_H__
#define __TextureSprite_SCENE_H__


#include "cocos2d.h"


class TextureSprite : public cocos2d::Sprite
{
public:
virtual bool init(int w,int h);
static TextureSprite* create(int w, int h);
//set with color
void changeData(int x,int y, cocos2d::Color4B color);
void clearWithColor(cocos2d::Color4B color);
~TextureSprite();
private:
cocos2d::Size m_layerSize;
unsigned char *m_data;
void Update(float dt);
private:
};


#endif 







//类文件

#include "TextureSprite.h"
USING_NS_CC;


TextureSprite* TextureSprite::create(int w, int h){
TextureSprite* sp = new TextureSprite();
if (sp&&sp->init(w,h))
{
sp->autorelease();
return sp;
}
else
{
delete sp;
sp = nullptr;
return nullptr;
}
}
bool TextureSprite::init(int w,int h)
{
if (!Node::init())
{
return false;
}
auto dataLen = w * h * 4;
m_data = new unsigned char[dataLen];
auto allcolor = Color4B::BLACK;
allcolor.a = 150;
m_layerSize = Size(w, h);
clearWithColor(allcolor);
auto _texture = new (std::nothrow) Texture2D();
if (_texture)
{
_texture->initWithData(m_data, dataLen, Texture2D::PixelFormat::RGBA8888, w, h, Size((float)w, (float)h));
}
initWithTexture(_texture);
_texture->release();
setAnchorPoint(Vec2(m_layerSize.height / m_layerSize.width - 0.5f, -0.5f*(m_layerSize.width / m_layerSize.height)));
schedule(schedule_selector(TextureSprite::Update));
return true;
}
void TextureSprite::Update(float dt){
_texture->updateWithData(m_data, 0, 0, getContentSize().width, getContentSize().height);
}
void TextureSprite::clearWithColor(cocos2d::Color4B color){
int w = 4 * m_layerSize.width;
for (int i = 0; i < m_layerSize.height; i++)
{
for (int j = 0; j < m_layerSize.width; j++)
{
m_data[i * w + j * 4 + 0] = color.r;
m_data[i * w + j * 4 + 1] = color.g;
m_data[i * w + j * 4 + 2] = color.b;
m_data[i * w + j * 4 + 3] = color.a;
}
}
}
void TextureSprite::changeData(int x, int y, cocos2d::Color4B color){
int w = 4 * m_layerSize.width;
m_data[y * w + x * 4 + 0] = color.r;
m_data[y * w + x * 4 + 1] = color.g;
m_data[y * w + x * 4 + 2] = color.b;
m_data[y * w + x * 4 + 3] = color.a;
}
TextureSprite::~TextureSprite(){
delete m_data;
}


Texture2D的根据数据创建纹理只支持RGBA8888,所有指针数组只能用unsigned char.

这个是可以更改纹理的精灵。

再建一个node对这个精灵包装一下,就稳妥了


评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值