cocos2dx 3.6 如何写一个ting wings :动态纹理

首先,几年前曾经玩过一段时间游戏开发,当时没用什么游戏引擎,整个开发过程很繁琐,但流程很清晰。现在各种引擎,遍地开花,开发方便,效果绚丽,但封装过于复杂,好多时候,是知其然而不知其所以然。还是要踏踏实实的走啊。

最近刚好离职,也不着急找工作,索性把以前未完成的想法,实现一下。
参考文章:
how-to-create-dynamic-textures-with-ccrendertexture-in-cocos2d-2-x
how-to-create-a-game-like-tiny-wings-with-cocos2d-2-x-part-1
how-to-create-a-game-like-tiny-wings-with-cocos2d-2-x-part-2
(译)如何使用CCRenderTexture来创建动态纹理
(译)如何制作一个类似tiny wings的游戏:第一部分
(译)如何制作一个类似tiny wings的游戏:第二部分(完)
如何使用CCRenderTexture创建动态纹理 Cocos2d-x 2.1.4
如何制作一个类似Tiny Wings的游戏 Cocos2d-x 2.1.4
如何制作一个类似Tiny Wings的游戏(2) Cocos2d-x 2.1.4
Cocos2d-x3.2与OpenGL渲染总结(一)Cocos2d-x3.2的渲染流程

这个教程,原版是ios下得,在最后一个链接,作者进行了相应的移植,使用的时cocos2dx 2.1.4。我在学习得过程中,发现cocos2dx的v2和v3版本,api变化比较大,核心的渲染过程也有了明显的差异。

在测试创建动态纹理时,发现作者在2.1.4版本下得代码,在3.6版本下没有实现渐变,和条纹的效果,经过几天时间的研究,整理出一份可以在3.6版本下,实现动态纹理的代码。为方便大家互相学习,将代码附在下文。


cocos2dx 3.6 如何写一个ting wings :动态纹理_第1张图片
iOS Simulator Screen Shot 2015年7月15日 9.22.19.png
//
//  TextureTestScene.h
//  MyTestGame
//
//  Created by shutup on 15-7-15.
//
//

#ifndef __MyTestGame__TextureTestScene__
#define __MyTestGame__TextureTestScene__

#include "cocos2d.h"
class TextureTestScene : public cocos2d::Layer
{
public:
    // there's no 'id' in cpp, so we recommend returning the class instance pointer
    static cocos2d::Scene* createScene();
    
    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();
    // implement the "static create()" method manually
    CREATE_FUNC(TextureTestScene);
    virtual void onEnter();
    //单色渐变
    cocos2d::Sprite *spriteWithColor(cocos2d::Color4F bgColor, float textureWidth, float textureHeight);
    //渐变加条纹
    cocos2d::Sprite * spriteWithColor1AndColor2(cocos2d::Color4F c1, cocos2d::Color4F c2, float textureWidth, float textureHeight, int nStripes);
    
    //随机颜色
    cocos2d::Color4F randombrightColor();
    //生成背景
    void genBackground();
    //触屏事件
    virtual bool onTouchBegan(cocos2d::Touch *touch,cocos2d::Event * event);
    
    TextureTestScene();
    virtual ~TextureTestScene();
   
    //绘制条纹的回调
    void drawStripes(cocos2d::Color4F c2, float textureWidth, float textureHeight, int nStripes);
    //绘制渐变的回调
    void drawGridient(float textureWidth, float textureHeight);
    private :
    cocos2d::Sprite* _background;
    cocos2d::CustomCommand _customCommand;
};
#endif /* defined(__MyTestGame__TextureTestScene__) */

//
//  TextureTestScene.cpp
//  MyTestGame
//
//  Created by shutup on 15-7-15.
//
//

#include "TextureTestScene.h"
USING_NS_CC;
TextureTestScene::TextureTestScene() {
    // TODO Auto-generated constructor stub
    _background = nullptr;
}

TextureTestScene::~TextureTestScene() {
    // TODO Auto-generated destructor stub
}


bool TextureTestScene::init() {
    if ( !Layer::init() )
    {
        return false;
    }
    return true;
}

Scene* TextureTestScene::createScene() {
    auto scene = Scene::create();
    auto layer = TextureTestScene::create();
    scene->addChild(layer);
    return scene;
}

void TextureTestScene::onEnter()
{
    
    Layer::onEnter();
    genBackground();
    setTouchEnabled(true);
    //设置为单点触摸
    setTouchMode(Touch::DispatchMode::ONE_BY_ONE);
}
bool TextureTestScene::onTouchBegan(Touch *pTouches, Event *pEvent)
{
    this->genBackground();
    return true;
}
Color4F TextureTestScene::randombrightColor()
{
    while(true)
    {
        float requiredBrightness = 192;
        Color4B randomColor = Color4B(rand()%255,rand()%255,rand()%255,255);
        if(randomColor.r > requiredBrightness || randomColor.g > requiredBrightness || randomColor.b >requiredBrightness)
        {
            return Color4F(randomColor);
        }
    }
    return Color4F();
}

void TextureTestScene::genBackground()
{
    if (_background)
    {
        _background->removeFromParentAndCleanup(true);
    }
    //渐变纹理
//    Color4F bgColor = this->randombrightColor();
//    _background = this->spriteWithColor(bgColor, 512, 512);
    
    //条纹纹理
    Color4F bgColor = this->randombrightColor();
    Color4F color2 = this->randombrightColor();
    int nStripes =((rand() % 4) + 1) * 2;
    _background = this->spriteWithColor1AndColor2(bgColor, color2, 512, 512, nStripes);
    
    
    Size winSize = Director::getInstance()->getVisibleSize();
    _background->setPosition(Vec2(winSize.width / 2, winSize.height / 2));
    this->addChild(_background, -1);
}

Sprite* TextureTestScene::spriteWithColor(Color4F bgColor,float textureWidth,float textureHeight) {
    
    RenderTexture* rt = RenderTexture::create(textureWidth,textureHeight);
    rt->beginWithClear(bgColor.r,bgColor.g,bgColor.b,bgColor.a);
    //draw the gradient
    
    _customCommand.init(_globalZOrder);
    _customCommand.func = CC_CALLBACK_0(TextureTestScene::drawGridient, this,textureWidth,textureHeight);
    auto renderer = Director::getInstance()->getRenderer();
    renderer->addCommand(&_customCommand);
    
    //do something more
//    draw the noise
    Sprite* noise = Sprite::create("Noise.png");
    BlendFunc blendFunc = {GL_DST_COLOR,GL_ZERO};
    noise->setBlendFunc(blendFunc);
    noise->setPosition(Vec2(textureWidth/2,textureHeight/2));
    noise->visit();
    
    rt->end();
    return Sprite::createWithTexture(rt->getSprite()->getTexture());
}
Sprite * TextureTestScene::spriteWithColor1AndColor2(Color4F c1, Color4F c2, float textureWidth, float textureHeight, int nStripes)
{
    // 1: Create new RenderTexture
    RenderTexture *rt = RenderTexture::create(textureWidth, textureHeight);
    
    // 2: Call CCRenderTexture:begin
    rt->beginWithClear(c1.r, c1.g, c1.b, c1.a);
    
    // 3: Draw into the texture
    
    _customCommand.init(_globalZOrder);
    _customCommand.func = CC_CALLBACK_0(TextureTestScene::drawStripes, this,c2,textureWidth,textureHeight,nStripes);
    auto renderer = Director::getInstance()->getRenderer();
    renderer->addCommand(&_customCommand);
    // Layer 4: Noise
    Sprite *noise = Sprite::create("Noise.png");
    BlendFunc blendFunc = {GL_DST_COLOR, GL_ZERO};
    noise->setBlendFunc(blendFunc);
    noise->setPosition(Vec2(textureWidth / 2, textureHeight / 2));
    noise->visit();
    
    // 4: Call CCRenderTexture:end
    rt->end();
    
    // 5: Create a new Sprite from the texture
    return Sprite::createWithTexture(rt->getSprite()->getTexture());
}

void TextureTestScene::drawStripes(Color4F c2, float textureWidth, float textureHeight, int nStripes)
{
    this->setGLProgram(GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_COLOR));
    CC_NODE_DRAW_SETUP();
    
    {
        // Layer 1: Stripes
        Point *vertices = new Point[nStripes * 6];
        Color4F *colors = new Color4F[nStripes * 6];
        
        int nVertices = 0;
        float x1 = -textureHeight;
        float x2;
        float y1 = textureHeight;
        float y2 = 0;
        float dx = textureWidth / nStripes * 2;
        float stripeWidth = dx / 2;
        for (int i = 0; i < nStripes; ++i)
        {
            x2  = x1 + textureHeight;
            
            vertices[nVertices] = Point(x1, y1);
            colors[nVertices++] = Color4F(c2.r, c2.g, c2.b, c2.a);
            
            vertices[nVertices] = Point(x1 + stripeWidth, y1);
            colors[nVertices++] = Color4F(c2.r, c2.g, c2.b, c2.a);
            
            vertices[nVertices] = Point(x2, y2);
            colors[nVertices++] = Color4F(c2.r, c2.g, c2.b, c2.a);
            
            vertices[nVertices] = vertices[nVertices - 2];
            colors[nVertices++] = Color4F(c2.r, c2.g, c2.b, c2.a);
            
            vertices[nVertices] = vertices[nVertices - 2];
            colors[nVertices++] = Color4F(c2.r, c2.g, c2.b, c2.a);
            
            vertices[nVertices] = Point(x2 + stripeWidth, y2);
            colors[nVertices++] = Color4F(c2.r, c2.g, c2.b, c2.a);
            x1 += dx;
        }
        
//      glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION|GLProgram::VERTEX_ATTRIB_COLOR);
        GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POSITION | GL::VERTEX_ATTRIB_FLAG_COLOR);
        
        glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
        glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_FLOAT, GL_FALSE, 0, colors);
        glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
        glDrawArrays(GL_TRIANGLES, 0, (GLsizei)nVertices);
        //通知cocos2d-x 的renderer,让它在合适的时候调用这些OpenGL命令
//        CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, 3);
        //如果出错了,可以使用这个函数来获取出错信息
        CHECK_GL_ERROR_DEBUG();
        CC_SAFE_DELETE_ARRAY(vertices);
        CC_SAFE_DELETE_ARRAY(colors);
        
    }
    
    {float gradientAlpha = 0.7f;
        Point vertices[4];
        Color4F colors[4];
        int nVertices =0;
        vertices[nVertices] = Point(0,0);
        colors[nVertices++] = Color4F(0,0,0,0);
        vertices[nVertices] = Point(textureWidth,0);
        colors[nVertices++] = Color4F(0,0,0,0);
        vertices[nVertices] = Point(0,textureHeight);
        colors[nVertices++] = Color4F(0,0,0,gradientAlpha);
        vertices[nVertices] = Point(textureWidth,textureHeight);
        colors[nVertices++] = Color4F(0,0,0,gradientAlpha);
        //这句有点问题
        //  glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION|GLProgram::VERTEX_ATTRIB_COLOR);
        GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POSITION | GL::VERTEX_ATTRIB_FLAG_COLOR);
        glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION,2,GL_FLOAT,GL_FALSE,0,vertices);
        glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR,4,GL_FLOAT,GL_FALSE,0,colors);
        glBlendFunc(CC_BLEND_SRC,CC_BLEND_DST);
        glDrawArrays(GL_TRIANGLE_STRIP,0,(GLsizei)nVertices);
        CHECK_GL_ERROR_DEBUG();
    }
}

void TextureTestScene::drawGridient(float textureWidth, float textureHeight)
{
    this->setGLProgram(GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_COLOR));
    CC_NODE_DRAW_SETUP();
    
    {
        float gradientAlpha = 0.7f;
        Point vertices[4];
        Color4F colors[4];
        int nVertices =0;
        vertices[nVertices] = Point(0,0);
        colors[nVertices++] = Color4F(0,0,0,0);
        vertices[nVertices] = Point(textureWidth,0);
        colors[nVertices++] = Color4F(0,0,0,0);
        vertices[nVertices] = Point(0,textureHeight);
        colors[nVertices++] = Color4F(0,0,0,gradientAlpha);
        vertices[nVertices] = Point(textureWidth,textureHeight);
        colors[nVertices++] = Color4F(0,0,0,gradientAlpha);
        //这句有点问题
        //  glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION|GLProgram::VERTEX_ATTRIB_COLOR);
        GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POSITION | GL::VERTEX_ATTRIB_FLAG_COLOR);
        glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION,2,GL_FLOAT,GL_FALSE,0,vertices);
        glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR,4,GL_FLOAT,GL_FALSE,0,colors);
        glBlendFunc(CC_BLEND_SRC,CC_BLEND_DST);
        glDrawArrays(GL_TRIANGLE_STRIP,0,(GLsizei)nVertices);
        CHECK_GL_ERROR_DEBUG();
    }
}

你可能感兴趣的:(cocos2dx 3.6 如何写一个ting wings :动态纹理)