|
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
}
'Android' 카테고리의 다른 글
cocos2d-x 안드로이드 진동기능 설정 cocos2d-x android vibration definition (0) | 2013.11.08 |
---|---|
cocos2d-x 안드로이드 웹페이지 호출 cocos2d-x loading a wep page in Android (0) | 2013.11.08 |
Bresenham 브레센함 알고리듬 : 원 그리기 (0) | 2013.03.07 |
Conway's Game Of Life Java code (0) | 2012.10.05 |
Android image crop (0) | 2012.09.19 |