题外话:工作几年来,屡屡在网上可以找到解决方案和技术分享。从事Cocos2d-x开发几年来,从网上找到学习到很多的知识,也屡屡在犯愁的时候得到解决方案,非常感谢Cocos2d-x引擎,及提供的开发者社区。现在是时候来整理整理我的开发积累了。一直来都没啥头绪,也不知道写些什么。干脆就从开发中碰到的问题开始入手。从我设计现在的项目开始我的博客之旅。然后我会从一个Cocos2d-x项目的思路写下去,就从我现在的项目构思,架构,优化写下去,到最后希望能整理一个开源的框架来鞭策自己进步。(之前QQ第三方登录,发了这篇文章,早上起来看到居然有好些人阅读,看了看排版内容,真是对不起观众,所以现在开始好好整理,全部移植到这个账号里来)
Cocos2d-x图片灰态的适用处理办法
一、构思分析
Cocos2d-x项目一直以来都对图片的要求很高,提起优化每个人都会从讲到纹理图片优化开始。所以从项目经理、美术、策划一票人都应该会重视这个问题。RPG游戏,卡牌游戏就更加会注重这些了,所以能省则省,在不影响美观的情况下,尽量做到图片资源最优。今天美术同学就跟我提出了一个需求,希望一些按钮的灰态处理,程序能自己处理。
首先我第一个想到的是设置Color,发现其结果类似于添加一个灰色的遮罩。没办法只能是用Shander了。曾经我在一个卡牌游戏中使用过通过Shandr来达到灰态处理(Cocos2d-x3.2 Lua)。直接移植到现在项目(Cocos2d-x 3.5 C++) 效果还不错,但是哥们反应这个Shander函数在Debug的时候会挂掉,调查了下果然会出现。当我查找灰态的Shander文件的时候,偶然想了下3.5会不会有相应的处理方法。突然发现Scale9Sprite有这个处理方式,发现跟我实现的差不多,我的Shander文件现在引擎里面有了,所以稍加修改,一测试就OK了。所以说最好的文档资料是引擎本身。
实用于任务系统、签到奖励等功能中。亦可以用于按钮灰态中。
二、代码实现
这里实现一个WWShanderFactory类。首先看头文件
class WWShanderFactory
{
public:
WWShanderFactory();
virtual ~WWShanderFactory();
static void convSpriteGray(Sprite* node);
static void convSpriteNormal(Sprite* node);
static void convImageViewGray(ImageView* node);
static void convImageViewNormal(ImageView* node);
};
提供的4个函数中,前两个为Sprite的灰色和常态处理。后面两个为ImageView的相关处理。在看下具体实现。
void WWShanderFactory::convSpriteGray(Sprite* node)
{
GLProgramState *glState = nullptr;
auto program = GLProgram::createWithByteArrays(ccPositionTextureColor_noMVP_vert,
ccUIGrayScale_frag);
glState = GLProgramState::getOrCreateWithGLProgram(program);
node->setGLProgramState(glState);
}
void WWShanderFactory::convSpriteNormal(Sprite* node)
{
GLProgramState *glState = GLProgramState::getOrCreateWithGLProgramName("ShaderPositionTextureColor_noMVP");
glState->setUniformTexture("u_texture", node->getTexture()->getName());
glState->getGLProgram()->updateUniforms();
node->setGLProgramState(glState);
}
void WWShanderFactory::convImageViewGray(ImageView* iv)
{
((ui::Scale9Sprite*)(iv->getVirtualRenderer()))->setState(ui::Scale9Sprite::State::GRAY);
}
void WWShanderFactory::convImageViewNormal(ImageView* iv)
{
((ui::Scale9Sprite*)(iv->getVirtualRenderer()))->setState(ui::Scale9Sprite::State::NORMAL);
}
代码中的具体细节可以自行研究下。这里就不多讲了。接下来看看具体使用。
auto sp_demo = Sprite::create("res/Images/Common/comm_box.png");
sp_demo->setPosition(Vec2(640, 500));
addChild(sp_demo);
WWShanderFactory::convSpriteGray(sp_demo);
WWShanderFactory::convSpriteNormal(sp_demo);
效果图如下:
左边为灰态。右边为常态。