BbaDdo :: cocos2d-x 1.01 ripple, wave, liquid 응용

 

 

 

 

 

cocos2d-x openGl10 엔진을 이용한 ripple, wave, liquid 효과 적용,

C++로 코딩 한번 해 봄.액션 시퀀스를 사용하지 않고 각 효과 클래스 객체가 릴리즈 될때의 초간격을 이용해 구현. 이유가 있음

초 간격을 잘못 주면 다운...폰 배터리 빼고 다시 켜야함.

이구.. 보니느 스맛뽄이 꾸질꾸질 구형이라

2.13 cocos2d-x는 visual studio 에서만 확인,

물론 안드로이드 자바 랩핑까지만 되는 것만 봄...

 

 

 

 

helloWorldScene.h

 

#ifndef __HELLOWORLD_SCENE_H__

#define __HELLOWORLD_SCENE_H__

 

#include "cocos2d.h"

#include "SimpleAudioEngine.h"

#include <platform.h>

 

using namespace cocos2d;

using namespace CocosDenshion;

 

class HelloWorld : public CCLayer

{

private:

         CCSize            m_size;

         ccTime            m_t; //float

         cc_timeval        m_start;          //구조체 (, 마이크로초) long, long

         cc_timeval        m_end;                     //터치무브 시간 구함

         cc_timeval        m_result;                  //시스템시간으로 계산

             CCLabelTTF*       m_pLabel;     

         CCLabelBMFont*    m_pLabel2;

         bool              m_touchOff;                        //wave effect activity off, 웨이브 실행시 터치 오프

         bool              m_changedWaveOff; //sellect wave button off, 웨이브 이펙트 변경시 에러방지

         int               m_caseEffect;              //case 순서

         int               m_nRipple;                         //리플의 경우 연속터치시 다른 이펙트와 충돌 방지용

         int               m_nCheck;                          //위와 동일

         CCSprite*         m_pTx;                             //텍스트 띄우기

         SimpleAudioEngine* m_soundRipples;          //효과음

         SimpleAudioEngine* m_soundWaves;            //효과음

         SimpleAudioEngine* m_soundLiquid;           //효과음

public:

         HelloWorld();

         ~HelloWorld();

 

         // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone

         virtual bool init(); 

 

         // there's no 'id' in cpp, so we recommand to return the exactly class pointer

         static cocos2d::CCScene* scene();

        

         // a selector callback

         virtual void menuCloseCallback(CCObject* pSender);

 

         // for the subclass of CCLayer, each has to implement the "static node()" method manually

         LAYER_NODE_FUNC(HelloWorld);

 

         //터치이벤트

         virtual void ccTouchesBegan(CCSet *pTouch, CCEvent *pEvent);

         virtual void ccTouchesMoved(CCSet *pTouch, CCEvent *pEvent);

         virtual void ccTouchesEnded(CCSet *pTouch, CCEvent *pEvent);

         virtual void ccTouchesCancelled(CCSet *pTouch, CCEvent *pEvent);

         void UpdateLabel();

 

         // 리플, 웨이브 효과

         void MadeRipple(const CCPoint &p, const ccTime &t);

         void MadeWave(const ccTime &t);

         void MadeLiquid(const ccTime &t);

 

         // 리플 반복 터치 허용, 웨이브 반복 터치 불허

         void TouchOn();

 

         // 리플 -> 웨이브 변경 방지

         void waveChangeOn();

 

         // 텍스트 스크롤

         void ScrollTx(ccTime t);

};

 

#endif // __HELLOWORLD_SCENE_H__

 

 

 

 

helloWorldScene.cpp

 

#include "HelloWorldScene.h"

 

 

HelloWorld::HelloWorld()

{

        m_touchOff = false;

        m_changedWaveOff = false;

        m_caseEffect = 0;

        m_nRipple = 0;

        m_nCheck = 0;

}

 

HelloWorld::~HelloWorld()

{

}

 

CCScene* HelloWorld::scene()

{

        // 'scene' is an autorelease object

        CCScene *scene = CCScene::node();

        

         // 'layer' is an autorelease object

         HelloWorld *layer = HelloWorld::node();

 

         // add layer as a child to scene

         scene->addChild(layer);

 

         // return the scene

         return scene;

}

 

// on "init" you need to initialize your instance

bool HelloWorld::init()

{

         //////////////////////////////

         // 1. super init first

         if ( !CCLayer::init() )

         {

                  return false;

         }

 

         /////////////////////////////

         // 2. add a menu item with "X" image, which is clicked to quit the program

         //    you may modify it.

 

         // add a "close" icon to exit the progress. it's an autorelease object

         CCMenuItemImage *pCloseItem = CCMenuItemImage::itemFromNormalImage(

                       "CloseNormal.png", "CloseSelected.png", this, menu_selector(HelloWorld::menuCloseCallback) );

         pCloseItem->setPosition( ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20) );

         pCloseItem->setTag(1);

 

         CCMenuItemImage *pSelectedItem = CCMenuItemImage::itemFromNormalImage(

                        "Normal.png", "Selected.png", this, menu_selector(HelloWorld::menuCloseCallback) );

         pSelectedItem->setPosition( CCPointMake(20, 20));

         pSelectedItem->setTag(2);

                 

         // create menu, it's an autorelease object

         CCMenu* pMenu = CCMenu::menuWithItems(pCloseItem, pSelectedItem, NULL);

         pMenu->setPosition( CCPointZero );

         this->addChild(pMenu, 1);

 

         /////////////////////////////

         // 3. add your codes below...

 

         // add a label shows "Hello World"

         // create and initialize a label

         m_pLabel = CCLabelTTF::labelWithString("Hello World", "fonts/impact.ttf", 30);

         m_pLabel->setColor(ccc3(197,245,244));

 

         m_pLabel2 = CCLabelBMFont::labelWithString("Ripple", "fonts/futura-48.fnt");

        

         // ask director the window size

         m_size = CCDirector::sharedDirector()->getWinSize();

 

                  // position the label on the center of the screen

         m_pLabel->setPosition( CCPointMake(m_size.width / 2, m_size.height - 40) );

         m_pLabel2->setPosition( CCPointMake(m_size.width / 2, 40) );

 

         // add the label as a child to this layer

         this->addChild(m_pLabel, 1);

         this->addChild(m_pLabel2, 1);

 

         // add "HelloWorld" splash screen"

         CCSprite* pSprite = CCSprite::spriteWithFile("HelloWorld.png");

 

         // position the sprite on the center of the screen

         pSprite->setPosition( CCPointMake(m_size.width/2, m_size.height/2) );

 

         // add the sprite as a child to this layer

         this->addChild(pSprite, 0);

 

         // 설명

         m_pTx = CCSprite::spriteWithFile("method.png");  //외부파일 로딩

         m_pTx->setAnchorPoint(ccp(0, 0.5)); //앵커 좌측하단, ccp()코코스좌표함수

         m_pTx->setPosition(CCPointMake(m_size.width, m_size.height/2));      //이미지 좌측하단 위치

         this->addChild(m_pTx, 2);         

 

         //스케줄러 호출

         schedule(schedule_selector(HelloWorld::ScrollTx), 0.5f);    //텍스트 스크롤

 

         // 터치이벤트 활성화

         this->setIsTouchEnabled(true);

        

         // 효과음 프리로드

         m_soundRipples->sharedEngine();

         m_soundWaves->sharedEngine();

         m_soundLiquid->sharedEngine();

 

         m_soundRipples->preloadEffect("waterdrop.wav");

         m_soundWaves->preloadEffect("wave.wav");

         m_soundLiquid->preloadEffect("bubble.wav");

 

         m_soundRipples->setEffectsVolume(1);

         m_soundWaves->setEffectsVolume(1);

         m_soundLiquid->setEffectsVolume(1);

 

         return true;

}

 

 

//텍스트 스크롤

void HelloWorld::ScrollTx(ccTime t)

{

         if(m_pTx->getPositionX() < -m_pTx->boundingBox().size.width)

         {

                  m_pTx->setPosition(ccp(m_size.width, m_size.height/2));

         }

         CCActionInterval *move = CCMoveBy::actionWithDuration(5, CCPointMake(-m_pTx->boundingBox().size.width, 0));

         m_pTx->runAction(move);

}

 

 

 

//리플 효과 주기 터치지점

void HelloWorld::MadeRipple(const CCPoint &p, const ccTime &t)

{

         // 리플효과 연속터치 횟수

         ++m_nRipple;

 

        

         // CCPoint center중심점, float r 범위, int wav 발생웨이브수, float amp, ccGridSize &gridSize, ccTime t 실행시간

         this->runAction(CCRipple3D::actionWithPosition(p, 0, 0, 0, ccg(32,24), 2.83f));

         this->runAction(CCRipple3D::actionWithPosition(p, m_size.height, 8, 10.f+t, ccg(32,24), 2.8f));

 

         this->runAction(CCRipple3D::actionWithPosition(p, 0, 0, 0, ccg(32,24), 1.73f));

         this->runAction(CCRipple3D::actionWithPosition(p, 200, 4, 40.f+t, ccg(32,24), 1.7f));

        

         this->runAction(CCRipple3D::actionWithPosition(p, 0, 0, 0, ccg(32,24), 0.53f));

         this->runAction(CCRipple3D::actionWithPosition(p, 100, 2, 80.f+t, ccg(32,24), 0.5f));

 

 

         //시간지연

         CCDelayTime* wait = CCDelayTime::actionWithDuration(3); 

 

         //터치 활성화

         CCCallFunc* waveChangeAction = CCCallFunc::actionWithTarget(this, callfunc_selector(HelloWorld::waveChangeOn));

 

         //시퀀스 등록: 액션 시퀀스 뒤에 콜백함수 호출,   

  //일반적인 액션시퀀스는 CCActionInterval *seq = (CCActionInterval*)CCSequence::actions

         CCFiniteTimeAction *seq = CCSequence::actions(wait, waveChangeAction, NULL);

         this->runAction(seq); // 시퀀스를 실행

     

}

 

// 웨이브 효과 주기 t 동안

void HelloWorld::MadeWave(const ccTime &t)

{

         // int wav 발생웨이브수, float amp, ccGridSize &gridSize 간격단위, ccTime t 실행시간

         this->runAction(CCWaves3D::actionWithWaves(0, 0, ccg(15,10), t+1.1f));

         this->runAction(CCWaves3D::actionWithWaves(3, 30, ccg(15,10), t+1.0f));

        

         //시간지연

         CCDelayTime* wait = CCDelayTime::actionWithDuration(t+1.3f); 

 

         //터치 활성화

         CCCallFunc* touchAction = CCCallFunc::actionWithTarget(this, callfunc_selector(HelloWorld::TouchOn));

 

         //시퀀스 등록: 액션 시퀀스 뒤에 콜백함수 호출,   

         CCFiniteTimeAction *seq = CCSequence::actions(wait, touchAction, NULL);

         this->runAction(seq); // 시퀀스를 실행

}

 

 

// 물효과

void HelloWorld::MadeLiquid(const ccTime &t)

{

         // int wav 발생웨이브수, float amp, ccGridSize &gridSize 간격단위, ccTime t 실행시간

         this->runAction(CCLiquid::actionWithWaves(0, 0, ccg(16,12), t+2.6f));

         this->runAction(CCLiquid::actionWithWaves(8, 10, ccg(16,12), t+2.5f));

        

         //시간지연

         CCDelayTime* wait = CCDelayTime::actionWithDuration(t+2.8f); 

 

         //터치 활성화

         CCCallFunc* touchAction = CCCallFunc::actionWithTarget(this, callfunc_selector(HelloWorld::TouchOn));

 

         //시퀀스 등록: 액션 시퀀스 뒤에 콜백함수 호출, 

         CCFiniteTimeAction *seq = CCSequence::actions(wait, touchAction, NULL);

         this->runAction(seq); // 시퀀스를 실행

}

 

 

void HelloWorld::TouchOn()

{

         m_touchOff = false;

}

 

void HelloWorld::waveChangeOn()

{       

         ++m_nCheck;

         if(m_nRipple == m_nCheck)

         {

                  m_changedWaveOff = false;

                  m_nRipple = 0;

                  m_nCheck = 0;

         }

}

 

void HelloWorld::UpdateLabel()

{

         //현재 시간 저장  

         CCTime::gettimeofdayCocos2d(&m_end, NULL);  //cc_timeval 구조체 long, long

         CCTime::timersubCocos2d(&m_result, &m_start, &m_end);  // 인터발 구함

         m_t = m_result.tv_sec + m_result.tv_usec / 1000000.f;  // ccTime 형으로 계산, float

        

         char str[17] = {}; //13 + 4 : 10,000 단위까지, 이상은 에러발생

//       sprintf_s(str, "Interval : %.2f", m_t);  //문자열 만들기

         sprintf(str, "Value : %.2f", m_t);  //문자열 만들기

         m_pLabel->setString(str);  //라벨 변경

}

 

 

 

 

//==================================//

//터치 이벤트

//==================================//

 

void HelloWorld::ccTouchesBegan(CCSet *pTouch, CCEvent *pEvent)

{

         // 현재 시간 저장

         CCTime::gettimeofdayCocos2d(&m_start, NULL);

        

         if(m_touchOff) return;

 

         //라벨 바꾸기

         UpdateLabel();

}

 

 

void HelloWorld::ccTouchesMoved(CCSet *pTouch, CCEvent *pEvent)

{

         if(m_touchOff) return;

         UpdateLabel();

}

 

void HelloWorld::ccTouchesEnded(CCSet *pTouch, CCEvent *pEvent)

{

         if(m_touchOff) return;

         UpdateLabel();

 

         //좌표 추출

         CCTouch *touch = (CCTouch*)(pTouch->anyObject());

         CCPoint touchGlPoint = touch->locationInView(touch->view());

 

 

         switch(m_caseEffect)

         {

         case 0:

                  //파문 효과

                  m_changedWaveOff = true;

                  m_soundRipples->playEffect("waterdrop.wav", false); //: 재생할 사운드 파일이름

                                                     //UI 좌표를 GL좌표로 변경

                  MadeRipple(CCDirector::sharedDirector()->convertToGL(touchGlPoint), m_t);

                  break;

         case 1:

                  m_touchOff = true;        

                  //웨이브효과

                  m_soundWaves->playEffect("wave.wav", false); //: 재생할 사운드 파일이름

                  MadeWave(m_t);

                  break;

         case 2:

                  m_touchOff = true;

                  //물효과

                  m_soundLiquid->playEffect("bubble.wav", false); //: 재생할 사운드 파일이름

                  MadeLiquid(m_t);

                  break;

         }       

 

 

 

//       CCLog("t: %f", m_t);

}

 

void HelloWorld::ccTouchesCancelled(CCSet *pTouch, CCEvent *pEvent)

{

         // 디바이스 정지시

}

 

 

void HelloWorld::menuCloseCallback(CCObject* pSender)

{

         CCMenuItem* item = (CCMenuItem*)pSender;

         if(item->getTag() == 1)

         {

                  CCDirector::sharedDirector()->end();

         }

         else if(item->getTag() == 2)

         {

                  if(m_touchOff || m_changedWaveOff) return;

                 

                  if(m_caseEffect == 0)

                  {

                           m_caseEffect = 1;

                           m_pLabel2->setString("Wave");  //라벨 변경

                  }

                  else if(m_caseEffect == 1)

                  {

                           m_caseEffect = 2;

                           m_pLabel2->setString("Liquid");  //라벨 변경

                  }

                  else

                  {

                           m_caseEffect = 0;

                           m_pLabel2->setString("Ripple");  //라벨 변경

                  }

         }

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)

         exit(0);

#endif 

}


카운터

Total : / Today : / Yesterday :
get rsstistory!