美文网首页cocos2dx
cocos2dx 3.6 如何写一个ting wings :动态

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

作者: SHUTUP | 来源:发表于2015-07-15 09:20 被阅读1091次

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

    最近刚好离职,也不着急找工作,索性把以前未完成的想法,实现一下。
    参考文章:
    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版本下,实现动态纹理的代码。为方便大家互相学习,将代码附在下文。


    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 :动态

        本文链接:https://www.haomeiwen.com/subject/cmnuqttx.html