水纹效果


//引用 封装的CCRippleSprite.h 类()

//
//  pgeRippleSprite.h
//  rippleDemo
//
//  Created by Lars Birkemose on 02/12/11.
//  Copyright 2011 Protec Electronics. All rights reserved.
//
// --------------------------------------------------------------------------
// import headers

#include "cocos2d.h"
#include <vector>

using namespace std;

// --------------------------------------------------------------------------
// defines

#define RIPPLE_DEFAULT_QUAD_COUNT_X             60
#define RIPPLE_DEFAULT_QUAD_COUNT_Y             40

#define RIPPLE_BASE_GAIN                        0.1f        // an internal constant

#define RIPPLE_DEFAULT_RADIUS                   100
#define RIPPLE_DEFAULT_RIPPLE_CYCLE             0.25f       // timing on ripple ( 1/frequenzy )
#define RIPPLE_DEFAULT_LIFESPAN                 1.4f        // entire ripple lifespan

// #define RIPPLE_BOUNCE                                       // makes ripples bounce off edges
#define RIPPLE_CHILD_MODIFIER                   2.0f        // strength modifier

// --------------------------------------------------------------------------
// typedefs

typedef enum {
    RIPPLE_TYPE_RUBBER,// a soft rubber sheet
    RIPPLE_TYPE_GEL,// high viscosity fluid
    RIPPLE_TYPE_WATER,// low viscosity fluid
} RIPPLE_TYPE;

typedef enum {
    RIPPLE_CHILD_LEFT,RIPPLE_CHILD_TOP,RIPPLE_CHILD_RIGHT,RIPPLE_CHILD_BOTTOM,RIPPLE_CHILD_COUNT
} RIPPLE_CHILD;

USING_NS_CC;

typedef struct _rippleData {
    bool                    parent;                         // ripple is a parent
    bool                    childCreated[ 4 ];              // child created ( in the 4 direction )
    RIPPLE_TYPE             rippleType;                     // type of ripple ( se update: )
    CCPoint                 center;                         // ripple center ( but you just knew that,didn't you? )
    CCPoint                 centerCoordinate;               // ripple center in texture coordinates
    float                   radius;                         // radius at which ripple has faded 100%
    float                   strength;                       // ripple strength
    float                   runtime;                        // current run time
    float                   currentRadius;                  // current radius
    float                   rippleCycle;                    // ripple cycle timing
    float                   lifespan;                       // total life span
} rippleData;

// --------------------------------------------------------------------------
// interface

class pgeRippleSprite : public CCSprite,public CCTargetedTouchDelegate {
public:
   //static methods:
    static pgeRippleSprite* create(const char * filename);
    static pgeRippleSprite* create(CCRenderTexture* rtt,float scale);
    
    pgeRippleSprite();
    ~pgeRippleSprite();
    bool initWithFile(const char* filename);
    bool initWithRendertexture(CCRenderTexture* rtt,float scale);
    
    void tesselate();
    void addRipple(CCPoint pos,RIPPLE_TYPE type,float strength);
    void addRippleChild(rippleData* parent,RIPPLE_CHILD type);
    void update(float dt);
    CCTexture2D* spriteTexture();
    
    virtual void draw();
    virtual void onEnterTransitionDidFinish();
    virtual void onExit();
    
    
    
    virtual bool ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent);
    virtual void ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent);
    virtual void ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent);
    virtual void ccTouchCancelled(CCTouch *pTouch,CCEvent *pEvent);
    
private:
    bool isPointInsideSprite(CCPoint pos);
    bool isTouchInsideSprite(CCTouch* pTouch);
       
    CCTexture2D*            m_texture;
    int                     m_quadCountX;                   // quad count in x and y direction
    int                     m_quadCountY;
    int                     m_VerticesPrStrip;              // number of vertices in a strip
    int                     m_bufferSize;                   // vertice buffer size
    CCPoint*                m_vertice;                      // vertices
    CCPoint*                m_textureCoordinate;            // texture coordinates ( original )
    CCPoint*                m_rippleCoordinate;             // texture coordinates ( ripple corrected )
    bool*                   m_edgeVertice;                  // vertice is a border vertice
    vector<rippleData*>     m_rippleList;                   // list of running ripples
    
    
    CCPoint screenSize;
    float scaleRTT;
    float runTime;
};

CCRippleSprite.cpp类

//
//  CCRippleSprite.cpp
//  RippleDemo-x
//
//  Created by guanghui on 7/30/13.
//
//

#include "CCRippleSprite.h"
#include <string>

using namespace std;




pgeRippleSprite* pgeRippleSprite::create(const char * filename)
{
    pgeRippleSprite *pSprite = new pgeRippleSprite();
    if (pSprite && pSprite->initWithFile(filename)) {
        pSprite->autorelease();
        return pSprite;
    }
    else
    {
        delete pSprite;
        pSprite = NULL;
        return NULL;
    }
}


pgeRippleSprite::pgeRippleSprite()
:m_texture(NULL),m_quadCountX(0),m_quadCountY(0),m_VerticesPrStrip(0),m_bufferSize(0),m_vertice(NULL),m_textureCoordinate(NULL),m_rippleCoordinate(NULL),m_edgeVertice(NULL),scaleRTT(0),screenSize(CCPointZero),runTime(0)
{
    
}
pgeRippleSprite::~pgeRippleSprite()
{
    rippleData* runningRipple;
    
    free(m_vertice);
    free(m_textureCoordinate);
    free(m_rippleCoordinate);
    free(m_edgeVertice);
    
    for (int count = 0; count < m_rippleList.size(); count++) {
        runningRipple = m_rippleList.at(count);
        free(runningRipple);
    }
    
    m_texture->release();
    
    
}
bool pgeRippleSprite::initWithFile(const char* filename)
{
    bool bRet = true;
    
    do {
        
        if (!CCSprite::init()) {
            bRet = false;
            break;
        }
        
        scaleRTT = 1.0f;
        
        
        //load texture
        m_texture = CCTextureCache::sharedTextureCache()->addImage(filename);
        m_texture->retain();
        
   
        
        //reset internal data
        m_vertice = NULL;
        m_textureCoordinate = NULL;
        //builds the vertice and texture-coordinate array
        m_quadCountX = RIPPLE_DEFAULT_QUAD_COUNT_X;
        m_quadCountY = RIPPLE_DEFAULT_QUAD_COUNT_Y;
        this->tesselate();
        
       screenSize = ccp(m_texture->getContentSize().width / scaleRTT,m_texture->getContentSize().height / scaleRTT);
        
        this->setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTexture));
       
        
    } while (0);
    
    
    return bRet;


}


void pgeRippleSprite::tesselate()
{
    int vertexPos = 0;
    CCPoint normalized;
    
    // clear buffers ( yeah,clearing nil buffers first time around )
    free( m_vertice );
    free( m_textureCoordinate );
    free( m_rippleCoordinate );
    free( m_edgeVertice );
    
    // calculate vertices pr strip
    m_VerticesPrStrip = 2 * ( m_quadCountX + 1 );
    
    // calculate buffer size
    m_bufferSize = m_VerticesPrStrip * m_quadCountY;
    
    // allocate buffers
    m_vertice = (CCPoint*)malloc( m_bufferSize * sizeof( CCPoint ) );
    m_textureCoordinate = (CCPoint*)malloc( m_bufferSize * sizeof( CCPoint ) );
    m_rippleCoordinate = (CCPoint*)malloc( m_bufferSize * sizeof( CCPoint ) );
    m_edgeVertice = (bool*)malloc( m_bufferSize * sizeof( bool ) );
    
    // reset vertice pointer
    vertexPos = 0;
    
    // create all vertices and default texture coordinates
    // scan though y quads,and create an x-oriented triangle strip for each
    for ( int y = 0; y < m_quadCountY; y ++ ) {
        
        // x counts to quadcount + 1,because number of vertices is number of quads + 1
        for ( int x = 0; x < ( m_quadCountX + 1 ); x ++ ) {
            
            // for each x vertex,an upper and lower y position is calculated,to create the triangle strip
            // upper + lower + upper + lower
            for ( int yy = 0; yy < 2; yy ++ ) {
                
                // first simply calculate a normalized position into rectangle
                normalized.x = ( float )x / ( float )m_quadCountX;
                normalized.y = ( float )( y + yy ) / ( float )m_quadCountY;
                
                // calculate vertex by multiplying rectangle ( texture ) size
                m_vertice[vertexPos] = ccp(normalized.x * m_texture->getContentSize().width / scaleRTT,normalized.y *
                                           m_texture->getContentSize().height / scaleRTT );
                
                // adjust texture coordinates according to texture size
                // as a texture is always in the power of 2,maxS and maxT are the fragment of the size actually used
                // invert y on texture coordinates
                m_textureCoordinate[vertexPos] = ccp(normalized.x * m_texture->getMaxS(),m_texture->getMaxT() - normalized.y *
                                                     m_texture->getMaxT());
                
                // check if vertice is an edge vertice,because edge vertices are never modified to keep outline consistent
                m_edgeVertice[ vertexPos ] = (
                                              ( x == 0 ) ||
                                              ( x == m_quadCountX ) ||
                                              ( ( y == 0 ) && ( yy == 0 ) ) ||
                                              ( ( y == ( m_quadCountY - 1 ) ) && ( yy > 0 ) ) );
                
                // next buffer pos
                vertexPos ++;
                
            }
        }
    }
 
}
void pgeRippleSprite::addRipple(CCPoint pos,float strength)
{
    rippleData* newRipple;
    
    // allocate new ripple
    newRipple = (rippleData*)malloc( sizeof( rippleData ) );
    
    // initialize ripple
    newRipple->parent = true;
    for ( int count = 0; count < 4; count ++ ) newRipple->childCreated[ count ] = false;
    newRipple->rippleType = type;
    newRipple->center = pos;
    newRipple->centerCoordinate = ccp(pos.x / m_texture->getContentSize().width * m_texture->getMaxS() / scaleRTT,m_texture->getMaxT() - (pos.y / m_texture->getContentSize().height * m_texture->getMaxT()/scaleRTT));
    newRipple->radius = RIPPLE_DEFAULT_RADIUS; // * strength;
    newRipple->strength = strength;
    newRipple->runtime = 0;
    newRipple->currentRadius = 0;
    newRipple->rippleCycle = RIPPLE_DEFAULT_RIPPLE_CYCLE;
    newRipple->lifespan = RIPPLE_DEFAULT_LIFESPAN;
    
    // add ripple to running list
    m_rippleList.push_back(newRipple);
    
    
}
void pgeRippleSprite::addRippleChild(rippleData* parent,RIPPLE_CHILD type)
{
    rippleData* newRipple;
    CCPoint pos;
    
    //CGSize screenSize = [CCDirector sharedDirector].winSize;
    
    // allocate new ripple
    newRipple = (rippleData*)malloc( sizeof( rippleData ) );
    
    // new ripple is pretty much a copy of its parent
    memcpy( newRipple,parent,sizeof( rippleData ) );
    
    // not a parent
    newRipple->parent = false;
    
    // mirror position
    switch ( type ) {
        case RIPPLE_CHILD_LEFT:
            pos = ccp( -parent->center.x,parent->center.y );
            break;
        case RIPPLE_CHILD_TOP:
            pos = ccp( parent->center.x,screenSize.y + ( screenSize.y - parent->center.y ) );
            break;
        case RIPPLE_CHILD_RIGHT:
            pos = ccp( screenSize.x + ( screenSize.x - parent->center.x ),parent->center.y );
            break;
        case RIPPLE_CHILD_BOTTOM:
        default:
            pos = ccp( parent->center.x,-parent->center.y );
            break;
    }
    
    newRipple->center = pos;
    newRipple->centerCoordinate = ccp(pos.x / m_texture->getContentSize().width * m_texture->getMaxS(),m_texture->getMaxT() - (pos.y / m_texture->getContentSize().height * m_texture->getMaxT()));
    newRipple->strength *= RIPPLE_CHILD_MODIFIER;
    
    // indicate child used
    parent->childCreated[ type ] = true;
    
    // add ripple to running list
    m_rippleList.push_back(newRipple);
}

void pgeRippleSprite::update(float dt)
{
    
    //runTime += dt;
    
    rippleData* ripple;
    CCPoint pos;
    float distance,correction;
    //CGSize screenSize = [CCDirector sharedDirector].winSize;
    
    // test if any ripples at all
    if ( m_rippleList.size() == 0 ) return;
    
    // ripples are simulated by altering texture coordinates
    // on all updates,an entire new array is calculated from the base array
    // not maintainng an original set of texture coordinates,could result in accumulated errors
    memcpy( m_rippleCoordinate,m_textureCoordinate,m_bufferSize * sizeof( CCPoint ) );
    
    // scan through running ripples
    // the scan is backwards,so that ripples can be removed on the fly
    for ( int count = ( m_rippleList.size() - 1 ); count >= 0; count -- ) {
        
        // get ripple data
        ripple = m_rippleList[count];
        
        // scan through all texture coordinates
        for ( int count = 0; count < m_bufferSize; count ++ ) {
            
            // dont modify edge vertices
            if ( m_edgeVertice[ count ] == false ) {
                
                // calculate distance
                // you might think it would be faster to do a box check first
                // but it really isnt,// ccpDistance is like my sexlife - BAM! - and its all over
                distance = ccpDistance( ripple->center,m_vertice[ count ] );
                
                // only modify vertices within range
                if ( distance <= ripple->currentRadius ) {
                    
                    // load the texture coordinate into an easy to use var
                    pos = m_rippleCoordinate[ count ];
                    
                    // calculate a ripple
                    switch ( ripple->rippleType ) {
                            
                        case RIPPLE_TYPE_RUBBER:
                            // method A
                            // calculate a sinus,based only on time
                            // this will make the ripples look like poking a soft rubber sheet,since sinus position is fixed
                            correction = sinf( 2 * M_PI * ripple->runtime / ripple->rippleCycle );
                            break;
                            
                        case RIPPLE_TYPE_GEL:
                            // method B
                            // calculate a sinus,based both on time and distance
                            // this will look more like a high viscosity fluid,since sinus will travel with radius
                            correction = sinf( 2 * M_PI * ( ripple->currentRadius - distance ) / ripple->radius * ripple->lifespan / ripple->rippleCycle );
                            break;
                            
                        case RIPPLE_TYPE_WATER:
                        default:
                            // method c
                            // like method b,but faded for time and distance to center
                            // this will look more like a low viscosity fluid,like water
                            
                            correction = ( ripple->radius * ripple->rippleCycle / ripple->lifespan ) / ( ripple->currentRadius - distance );
                            if ( correction > 1.0f ) correction = 1.0f;
                            
                            // fade center of quicker
                            correction *= correction;
                            
                            correction *= sinf( 2 * M_PI * ( ripple->currentRadius - distance ) / ripple->radius * ripple->lifespan / ripple->rippleCycle );
                            break;
                            
                    }
                    
                    // fade with distance
                    correction *= 1 - ( distance / ripple->currentRadius );
                    
                    // fade with time
                    correction *= 1 - ( ripple->runtime / ripple->lifespan );
                    
                    // adjust for base gain and user strength
                    correction *= RIPPLE_BASE_GAIN;
                    correction *= ripple->strength;
                    
                    // finally modify the coordinate by interpolating
                    // because of interpolation,adjustment for distance is needed,correction /= ccpDistance( ripple->centerCoordinate,pos );
                    pos = ccpAdd( pos,ccpMult( ccpSub( pos,ripple->centerCoordinate ),correction ) );
                    
                    // another approach for applying correction,would be to calculate slope from center to pos
                    // and then adjust based on this
                    
                    // clamp texture coordinates to avoid artifacts
                    pos = ccpClamp( pos,CCPointZero,ccp( m_texture->getMaxS(),m_texture->getMaxT() ) );
                    
                    // save modified coordinate
                    m_rippleCoordinate[ count ] = pos;
                    
                }
            }
        }
        
        // calculate radius
        ripple->currentRadius = ripple->radius * ripple->runtime / ripple->lifespan;
        
        // check if ripple should expire
        ripple->runtime += dt;
        if ( ripple->runtime >= ripple->lifespan ) {
            
            // free memory,and remove from list
            free( ripple );
            m_rippleList.erase(m_rippleList.begin() + count);
            
        } else {
            
#ifdef RIPPLE_BOUNCE
            // check for creation of child ripples
            if ( ripple->parent == true ) {
                
                // left ripple
                if ( ( ripple->childCreated[ RIPPLE_CHILD_LEFT ] == false ) && ( ripple->currentRadius > ripple->center.x ) ) {
                    this->addRippleChild(ripple,RIPPLE_CHILD_LEFT);
                }
                
                // top ripple
                if ( ( ripple->childCreated[ RIPPLE_CHILD_TOP ] == false ) && ( ripple->currentRadius > screenSize.y - ripple->center.y ) ) {
                    this->addRippleChild(ripple,RIPPLE_CHILD_TOP);
                }
                
                // right ripple
                if ( ( ripple->childCreated[ RIPPLE_CHILD_RIGHT ] == false ) && ( ripple->currentRadius > screenSize.x - ripple->center.x ) ) {
                    this->addRippleChild(ripple,RIPPLE_CHILD_RIGHT);
                }
                
                // bottom ripple
                if ( ( ripple->childCreated[ RIPPLE_CHILD_BOTTOM ] == false ) && ( ripple->currentRadius > ripple->center.y ) ) {
                    this->addRippleChild(ripple,RIPPLE_CHILD_BOTTOM);
                }
                
                
                
            }
#endif
            
        }
        
    }
    

}
CCTexture2D* pgeRippleSprite::spriteTexture()
{
    return m_texture;
}







void pgeRippleSprite::draw()
{
    
    if (!this->isVisible()) {
        return;
    }
    
    CC_NODE_DRAW_SETUP();
	ccGLEnableVertexAttribs( kCCVertexAttribFlag_Position | kCCVertexAttribFlag_TexCoords );
	
    ccGLBindTexture2D(m_texture->getName() );
    
        
    // vertex
    glVertexAttribPointer(kCCVertexAttrib_Position,2,GL_FLOAT,GL_FALSE,(void*) m_vertice);
    
    // if no ripples running,use original coordinates ( Yay,dig that kewl old school C syntax )
    glVertexAttribPointer(kCCVertexAttrib_TexCoords,( m_rippleList.size() == 0 ) ? m_textureCoordinate : m_rippleCoordinate);
    
    // draw as many triangle fans,as quads in y direction
    for ( int strip = 0; strip < m_quadCountY; strip++ ) {
        glDrawArrays( GL_TRIANGLE_STRIP,strip * m_VerticesPrStrip,m_VerticesPrStrip );
    }
 
}





bool pgeRippleSprite::isPointInsideSprite(cocos2d::CCPoint pos)
{
    float maxX = m_texture->getContentSize().width / scaleRTT;
    float maxY = m_texture->getContentSize().height / scaleRTT;
    
    
    if(pos.x < 0 || pos.y < 0 ||
       pos.x > maxX || pos.y > maxY) {
        return false;
    }
    else {
        return true;
    }
 
}

bool pgeRippleSprite::isTouchInsideSprite(cocos2d::CCTouch *pTouch)
{
    CCPoint pos;
    pos = pTouch->getLocationInView();
    pos = CCDirector::sharedDirector()->convertToGL(pos);
    pos = this->convertToNodeSpace(pos);
    
    return this->isPointInsideSprite(pos);
}

#pragma mark - touch events

bool pgeRippleSprite::ccTouchBegan(cocos2d::CCTouch *pTouch,cocos2d::CCEvent *pEvent)
{
    if (!this->isTouchInsideSprite(pTouch)) {
        return false;
    }
    
    this->ccTouchMoved(pTouch,pEvent);
    return true;
}


void pgeRippleSprite::ccTouchMoved(cocos2d::CCTouch *pTouch,cocos2d::CCEvent *pEvent)
{
    CCPoint pos;
    pos = pTouch->getLocationInView();
    pos = CCDirector::sharedDirector()->convertToGL(pos);
    pos = this->convertToNodeSpace(pos);
    
   this->addRipple(pos,RIPPLE_TYPE_WATER,2.0f);
    
    //runTime += 1.0 / 60.0f;
    
}


void pgeRippleSprite::ccTouchCancelled(cocos2d::CCTouch *pTouch,cocos2d::CCEvent *pEvent)
{
    //no-op
}


void pgeRippleSprite::ccTouchEnded(cocos2d::CCTouch *pTouch,cocos2d::CCEvent *pEvent)
{
   //no-op
}


void pgeRippleSprite::onEnterTransitionDidFinish()
{
    CCSprite::onEnterTransitionDidFinish();
    
    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,true);
}


void pgeRippleSprite::onExit()
{
    CCSprite::onExit();
    
    CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
}

实现效果
rippleSprite = pgeRippleSprite::create("image.png");
	rippleSprite->setScale(480.0 / 320);
	this->addChild(rippleSprite);

void HelloWorld::update( float dt )
{
	//-----------start(水纹效果相关)-------------------
	  rippleSprite->update(dt);
	//---------------end---------------------------------

	//------------CCParallaxNode(相关代码)-----------------
	/*float x = parallax_->getPositionX()-1;
	parallax_->setPositionX(x);*/
	//----------------end-------------------

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


    本文实践自 RayWenderlich、Ali Hafizji 的文章《How To Create Dynamic Textures with CCRenderTexture in Cocos2D 2.X》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.1.4进行学习和移植。在这篇文章,将会学习到如何创建实时纹理、如何用Gimp创建无缝拼接纹
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@163.com微信公众号:HopToad 欢迎转载,转载标注出处:http://blog.csdn.netotbaron/article/details/424343991.  软件准备 下载地址:http://cn.cocos2d-x.org/download 2.  简介2.1         引用C
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从Cocos2D-x官网上下载,进入网页http://www.cocos2d-x.org/download,点击Cocos2d-x以下的Download  v3.0,保存到自定义的文件夹2:从python官网上下载。进入网页https://www.python.org/downloads/,我当前下载的是3.4.0(当前最新
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发引擎,易学易用,支持多种智能移动平台。官网地址:http://cocos2d-x.org/当前版本:2.0    有很多的学习资料,在这里我只做为自己的笔记记录下来,错误之处还请指出。在VisualStudio2008平台的编译:1.下载当前稳
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《最强大脑》娱乐节目。将2048改造成一款挑战玩家对数字记忆的小游戏。邮箱:appdevzw@163.com微信公众号:HopToadAPK下载地址:http://download.csdn.net/detailotbaron/8446223源码下载地址:http://download.csdn.net/
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试以QtCreatorIDE来进行CMake构建。Cocos2d-x3.X地址:https://github.com/cocos2d/cocos2d-x1.打开QtCreator,菜单栏→"打开文件或项目...",打开cocos2d-x目录下的CMakeLists.txt文件;2.弹出CMake向导,如下图所示:设置
 下载地址:链接:https://pan.baidu.com/s/1IkQsMU6NoERAAQLcCUMcXQ提取码:p1pb下载完成后,解压进入build目录使用vs2013打开工程设置平台工具集,打开设置界面设置: 点击开始编译等待编译结束编译成功在build文件下会出现一个新文件夹Debug.win32,里面就是编译
分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net前言上次用象棋演示了cocos2dx的基本用法,但是对cocos2dx并没有作深入的讨论,这次以超级马里奥的源代码为线索,我们一起来学习超级马里奥的实
1. 圆形音量button事实上作者的本意应该是叫做“电位计button”。可是我觉得它和我们的圆形音量button非常像,所以就这么叫它吧~先看效果:好了,不多解释,本篇到此为止。(旁白: 噗。就这样结束了?)啊才怪~我们来看看代码:[cpp] viewplaincopyprint?CCContro
原文链接:http://www.cnblogs.com/physwf/archive/2013/04/26/3043912.html为了进一步深入学习贯彻Cocos2d,我们将自己写一个场景类,但我们不会走的太远,凡是都要循序渐进,哪怕只前进一点点,那也至少是前进了,总比贪多嚼不烂一头雾水的好。在上一节中我们建
2019独角兽企业重金招聘Python工程师标准>>>cocos2d2.0之后加入了一种九宫格的实现,主要作用是用来拉伸图片,这样的好处在于保留图片四个角不变形的同时,对图片中间部分进行拉伸,来满足一些控件的自适应(PS: 比如包括按钮,对话框,最直观的形象就是ios里的短信气泡了),这就要求图
原文链接:http://www.cnblogs.com/linji/p/3599478.html1.环境和工具准备Win7VS2010/2012,至于2008v2版本之后似乎就不支持了。 2.安装pythonv.2.0版本之前是用vs模板创建工程的,到vs2.2之后就改用python创建了。到python官网下载版本2.7.5的,然后
环境:ubuntu14.04adt-bundle-linux-x86_64android-ndk-r9d-linux-x86_64cocos2d-x-3.0正式版apache-ant1.9.3python2.7(ubuntu自带)加入环境变量exportANDROID_SDK_ROOT=/home/yangming/adt-bundle-linux/sdkexportPATH=${PATH}:/$ANDROID_SDK_ROOTools/export
1开发背景游戏程序设计涉及了学科中的各个方面,鉴于目的在于学习与进步,本游戏《FlappyBird》采用了两个不同的开发方式来开发本款游戏,一类直接采用win32底层API来实现,另一类采用当前火热的cocos2d-x游戏引擎来开发本游戏。2需求分析2.1数据分析本项目要开发的是一款游
原文链接:http://www.cnblogs.com/linji/p/3599912.html//纯色色块控件(锚点默认左下角)CCLayerColor*ccc=CCLayerColor::create(ccc4(255,0,0,128),200,100);//渐变色块控件CCLayerGradient*ccc=CCLayerGradient::create(ccc4(255,0,0,
原文链接:http://www.cnblogs.com/linji/p/3599488.html//载入一张图片CCSprite*leftDoor=CCSprite::create("loading/door.png");leftDoor->setAnchorPoint(ccp(1,0.5));//设置锚点为右边中心点leftDoor->setPosition(ccp(240,160));/
为了答谢广大学员对智捷课堂以及关老师的支持,现购买51CTO学院关老师的Cocos2d-x课程之一可以送智捷课堂编写图书一本(专题可以送3本)。一、Cocos2d-x课程列表:1、Cocos2d-x入门与提高视频教程__Part22、Cocos2d-x数据持久化与网络通信__Part33、Cocos2d-x架构设计与性能优化内存优
Spawn让多个action同时执行。Spawn有多种不同的create方法,最终都调用了createWithTwoActions(FiniteTimeAction*action1,FiniteTimeAction*action2)方法。createWithTwoActions调用initWithTwoActions方法:对两个action变量初始化:_one=action1;_two=action2;如果两个a
需要环境:php,luajit.昨天在cygwin上安装php和luajit环境,这真特么是一个坑。建议不要用虚拟环境安装打包环境,否则可能会出现各种莫名问题。折腾了一下午,最终将环境转向linux。其中,luajit的安装脚本已经在quick-cocos2d-x-develop/bin/中,直接luajit_install.sh即可。我的lin
v3.0相对v2.2来说,最引人注意的。应该是对触摸层级的优化。和lambda回调函数的引入(嗯嗯,不枉我改了那么多类名。话说,每次cocos2dx大更新。总要改掉一堆类名函数名)。这些特性应该有不少人研究了,所以今天说点跟图片有关的东西。v3.0在载入图片方面也有了非常大改变,仅仅只是