cocos2d-x는 m_pTargetedHandlers, m_pStandardHandlers 이 두가지로 터치을 관리한다.



m_pTargetedHandlers 는 직접 터치이벤트을 받을 타켓이 모여있는 집합이고

m_pStandardHandlers 는 CCLayer들이 모여 있는 집합이다.


m_pTargetedHandlers  여기에 셋팅하는 방법은
CCTouchDispatcher* touchDispatcher = CCDirector::sharedDirector()->getTouchDispatcher();
if(touchDispatcher){
CCTouchHandler* handler = touchDispatcher->findHandler(this);

//if is not already added to the touch dispatcher - then lets add it
if(!handler){
touchDispatcher->addTargetedDelegate( tCCTouchDelegate *pDelegate, int nPriority, bool bSwallowsTouches );
}
}

m_pStandardHandlers 에 셋팅하는 방법은
CCLayer에서 setTouchEnabled( true ) 이 함수만 실행 해주면 된다.

터치 이벤트 순서는

m_pTargetedHandlers  1

m_pStandardHandlers  2




터치 이벤트가 들어오면 터치 핸들러에 등록된 순서대로 아래 그림과 같이 번호가 적힌 대로 터치 이벤트를 발생 시켜 준다.


위에가 지금 보여지고 있는 레이어상에 등록된 모든 터치 이벤트라고 생각하고

지금 레이어 위에 새로운 레이어(팝업창)을 띄워 보자 그 새로운 레이어에는 총 4가지의 터치 이벤트가 있다고 생각하면

아래와 같은 그림처럼 되어 있을 것이다. 

따로 터치 가중치를 안주면 처리 방식은 스택형식으로 된다.





이제 우리가 원하는거는 Layer_2(팝업창)에만 터치 이벤트를 받아오게 하고 싶은 것이다.

이것을 하기 위해선 세가지 조건을 충족 시켜야한다.


첫쨰

touchDispatcher->addTargetedDelegate( tCCTouchDelegate *pDelegate, int nPriority, bool bSwallowsTouches );

여기 함수에서 bool bSwallowsTouches 이 속성이 있는데 여기에 ture을 주면 된다.


둘째 

이타겟은 충돌범위는 화면 전체를 가지고 있거나 터치다운 이벤트 시  무조건 true값을 넘겨줘야 한다.


셋째 

bool bSwallowsTouches 이 속성을 줄 녀석은 팝업창 등록 시 맨 처음 등록 되는 타겟에 셋팅이 들어가야한다.

무슨 말이냐면 레이어2번에는 총 4개의 터치 이벤트가 있는데 따로 터치 가중치를 안주면 첫번째로 등록 시킨

터치 이벤트는 4번째로 터치 이벤트를 받게 된다.


이렇게 되면 Layer2(팝업창)에만 터치이벤트를 받을 수 있게 된다.







Posted by 부우산사나이
:

Cocos2dxEditText.java 파일에서


    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event)
    {
        if(keyCode==KeyEvent.KEYCODE_BACK) {             
            // 여기에 처리할 코드 넣기
          }           
   
        return true;
    }


이렇게 추가 해주면 된다.

Posted by 부우산사나이
:

안드로이드는 홈키나 전화 받을 때 라이프 사이클로 인해


onPause()과 onResume() 함수가 호출된다.


이것들이 호출되면 화면상에 보여지고 있는 텍스쳐를 다 날려버리고


다시 로딩한다.


그래서 홈키로 인해 나갔다가 다시 들어가면 로딩시간이 길어지게 된다.


해결 방안으로는


CoCos2dxGLSurfaceView.java에서


@Override
    public void onResume() {   
        //super.onResume();
        this.queueEvent(new Runnable() {
            @Override
            public void run() {
                Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleOnResume();
            }
        });
    }

    @Override
    public void onPause() {
        this.queueEvent(new Runnable() {
            @Override
            public void run() {
                Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleOnPause();
            }
        });
       
        //super.onPause();
    }


super.onResume(), super.onPause() 호출 하는 부분을 주석 처리하면


홈키 눌렸다가 들어가도 전혀 로딩시간이 필요가 없다,


다시 로딩을 안하니 테스트로 하루종일 해봤으나 별 문제가 없어 보이나


추천하지 않는다. 왠지 불안하니깐.


그래서 더 찾아보니


안드로이드 3.0 이상 부터 지원하는 함수 하나가 추가가 되어 있었다.


setPreserveEGLContextOnPause 이 함수이다.


이함수에서 setPreserveEGLContextOnPaus(true); 로 셋팅하면


텍스쳐를 날려버리지 않고 들고 있게된다.


Posted by 부우산사나이
:

안드로이드 2.2 이하는 4메가 이상 폰트를 로드 할 수 없다.


로드가 안된 상태에서 텍스트를 셋팅하다 보면 어플이 뻗는다.


해결 방안으로는 로드 실패시 시스템 폰트로 로드 시키거나.


sd카드에서 폰트를 로드시키면 된다.


1번 해결 방안

paint.setTypeface(typeFace);
               
FontMetricsInt fm = paint.getFontMetricsInt();
 int h = (int) Math.ceil(fm.bottom - fm.top);
               
//폰트가 제대로 안만들어 진 상태 그래서 기본 폰트 사용
 if(h == 0)
{
        paint.setTypeface(Typeface.create("Arial", Typeface.NORMAL));
}



2번 해결방안


final Typeface typeface = Typeface.createFromAsset(pContext.getAssets(), pAssetName);

createFromAsset 이 함수 말고 createFromFile 이 함수 사용 하면 된다.

final Typeface typeface = Typeface.createFromFile("mnt/sdcard/폰트경로")

이렇게하면 1메가 넘는 폰트도 사용할 수 있다.


어차리 요즘은 2.2이하는 거의 없으므로 그냥 시스템 폰트 쓰는걸 추천한다.




Posted by 부우산사나이
:

코코스에서는 키패드 불려내면 기본적인 키패드밖에 지원해주지 않는다.

 

그래서 여러가지 키패드를 불려내고 싶으면 구현해야한다.

 

CCTextFieldTTF::attachWithIME()

 

이 함수가 키패드 불려내는 함수 인데

 

이 것을 새롭게 하나 구현 하면 된다.

 

bool CCTextFieldTTF::attachWithIME( int keyType )
{
 bool bRet = CCIMEDelegate::attachWithIME();
 if (bRet)
 {
  // open keyboard
  CCEGLView * pGlView = CCDirector::sharedDirector()->getOpenGLView();
  if (pGlView)
  {
   pGlView->setIMEKeyboardState(true, keyType);
  }
 }
 return bRet;
}

 

이런식으로 구현

 

CCEGLView::setIMEKeyboardState(bool bOpen, int keyType) 이 함수 또한 새로 구현 한거임

 

CCEGLView소스는 안드로이드,win32,ios 플래폼 세군데 있는데 일단 함수는 세군대 다 만들어주고

 

난 안드로이드에서 패드 불려낼꺼니깐 안드로이드 CCEGLView  cpp,h 파일에서 구현 해주면 된다.

 

void CCEGLView::setIMEKeyboardState(bool bOpen, int keyType)
{
 setKeyboardState_KeyTypeJNI((int)bOpen, keyType);
}

 

이런식으로

 

결국엔 안드로이다 함수를 불려야 하므로 JNI통신을 해야한다.

 

이부분이 JNI통신 하는 부분

void openKeyboard_KeyTypeJNI(int keyType) {
  JniMethodInfo t;

  if (JniHelper::getStaticMethodInfo(t, "org/cocos2dx/lib/Cocos2dxGLSurfaceView", "openIMEKeyboard_KeyPadType", "(I)V")) {
   t.env->CallStaticVoidMethod(t.classID, t.methodID, keyType);
   t.env->DeleteLocalRef(t.classID);
  }
 }

 

당연히 이클립스에서 해당 java파일에서 openIMEKeyboard_KeyPadType 이 함수 부분 구현해야 한다.

 

여기서 가장 중요한것은

 

setInputType 이 함수가 키패드 타입을 셋팅 할 수 있는 함수라는 것이다.

 

//키패드 타입 설정

Cocos2dxGLSurfaceView.this.mCocos2dxEditText.setInputType(msg.arg1);

final InputMethodManager imm = (InputMethodManager)

Cocos2dxGLSurfaceView.mCocos2dxGLSurfaceView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
//키패드 보이게 호출

imm.showSoftInput(Cocos2dxGLSurfaceView.this.mCocos2dxEditText, 0);

 

Posted by 부우산사나이
:

정리하기 귀찮아 나중에 다시 ㅎㅎ

Posted by 부우산사나이
:

코코스 투디에서 자바랑 jni통신을 해야 할 경우가 많다.

 

모 코코스엔진이 편의성을 잘 지원 하니 그냥 쉽게 통신할 수 있다.

 

우선

 

JniHelper.h 헤더 파일을 인쿠르드 하면 된다.

 

그러고 나면 jni.h 파일을 찾을 수 없다고 뜨는데 그때는

 

Program Files\Java\jdk1.7.0_05\include 을 포함 디렉토리에 추가 시켜주면 해결이 된다.

 

아래 소스는 ccimage에 있는 내용

 

JniMethodInfo methodInfo;
        if (! JniHelper::getStaticMethodInfo(methodInfo, "org/cocos2dx/lib/Cocos2dxBitmap", "createTextBitmap"
            "(Ljava/lang/String;Ljava/lang/String;IIII)V"))
        {
            CCLOG("%s %d: error to get methodInfo", __FILE__, __LINE__);
            return false;
        }
  
        jstring jstrText =javaNewStringChar(methodInfo.env,text);
  //jstring jstrText = new
        jstring jstrFont = methodInfo.env->NewStringUTF(pFontName);

        methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, jstrText,
            jstrFont, (int)fontSize, eAlignMask, nWidth, nHeight);

        methodInfo.env->DeleteLocalRef(jstrText);
        methodInfo.env->DeleteLocalRef(jstrFont);
        methodInfo.env->DeleteLocalRef(methodInfo.classID);

 

"org/cocos2dx/lib/Cocos2dxBitmap" 해당 클래스의 경로를 지정한다

"createTextBitmap" 실행 시킬 함수명을 지정 해준다.

"(Ljava/lang/String;Ljava/lang/String;IIII)V" 함수의 인자값을 지정해준다.

인자값 지정해주는 형식은 인터넷 검색을 하면 자세히 나오니 일단 설명은 생략

모 간단하게 이야기하면 c언어로 변환하면 string,string,int,int,int,int  이정도가 된다.

 

CallStaticVoidMethod(클래스,함수명,string,string,int,int,int,int )이 함수를 사용해서 자바에 있는 함수를 실행 할수 있다.

 

 

Posted by 부우산사나이
:

스크롤바 구현하다가 다른 페이지 화면을 현재 페이지에 띄우게 됐는데

 

다른 페이지부분을 현재 페이지 일정 영역에만 그리기 위해서 다른 페이지 부분을 클리핑 해야 겠다고 생각하고

 

찾아보니 역시나 있다.!!

 

해당 클래스에서  ccNode을 상속 받고 visit()함수를 오버라이딩해주고 아래와 같이 셋팅해주면 클리핑이 된다.

 

 

void 해당클래스네임::visit()
{
glPushMatrix();
glEnable(GL_SCISSOR_TEST);
CCEGLView::sharedOpenGLView().setScissorInPoints( x, y , width, height);
CCNode::visit();
glDisable(GL_SCISSOR_TEST);
glPopMatrix();
}
Posted by 부우산사나이
:

http://www.cocos2d-iphone.org/forum/topic/18522

Posted by 부우산사나이
: