cocos2dx:模擬touch事件

     最近終於開始學習cocos2d-x引擎了,Cocos2d-x作爲一個手機遊戲引擎,屏幕觸摸事件(touch)的處理一定時非常重要的。上個禮拜,我就開始琢磨,如何在telnet終端通過CCConsole命令模擬touch事件? 要在引擎裏模擬touch事件,就先要弄清楚引擎是如何處理touch事件的。就以往的經驗,touch事件的處理是比較複雜的,所以千萬不能先看代碼或者查資料,要先想清楚。

    觸摸事件是通過觸摸屏傳感器產生中斷傳給CPU,CPU再調用驅動的中斷處理程序傳給OS,OS再通過touch事件回調接口傳給應用處理的。引擎的位置顯然在應用層。那我們的目標就是OS的回調接口,以Android爲例,應用入口在android_main(),回調接口也是在這裏指定的:

void android_main(struct android_app* state) {


    // Make sure glue isn't stripped.
    app_dummy();
    

    memset(&engine, 0, sizeof(engine));
    state->userData = &engine;
    state->onAppCmd = engine_handle_cmd;
    state->onInputEvent = engine_handle_input;
    state->inputPollSource.process = process_input;
    engine.app = state;

....

}


input事件的處理函數就是engin_handle_input:


static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {


    pthread_t thisthread = pthread_self();
    LOG_EVENTS_DEBUG("engine_handle_input(%X, %X), pthread_self() = %X", app, event, thisthread);


    struct engine* engine = (struct engine*)app->userData;


    if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {
        engine->animating = 1;
        engine->state.x = AMotionEvent_getX(event, 0);
        engine->state.y = AMotionEvent_getY(event, 0);


        return handle_touch_input(event);
    }
    else
        return handle_key_input(event);


    return 0;
}


input事件分兩種類型,touch input 和 key input,我們關心的是touch事件,處理函數爲handle_touch_input():


static int32_t handle_touch_input(AInputEvent *event) {


    pthread_t thisthread = pthread_self();
    LOG_EVENTS_DEBUG("handle_touch_input(%X), pthread_self() = %X", event, thisthread);


    switch(AMotionEvent_getAction(event) &
           AMOTION_EVENT_ACTION_MASK) {


    case AMOTION_EVENT_ACTION_DOWN:
        {
            LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_DOWN");
            int pointerId = AMotionEvent_getPointerId(event, 0);
            float xP = AMotionEvent_getX(event,0);
            float yP = AMotionEvent_getY(event,0);


            LOG_EVENTS_DEBUG("Event: Action DOWN x=%f y=%f pointerID=%d\n",
                 xP, yP, pointerId);
            float x = xP;
            float y = yP;


            cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesBegin(1, &pointerId, &x, &y);
            return 1;
        }
        break;

.....
   
    }
}

爲節省篇幅,只列出touch begin的代碼,其他的類似。

這樣,就很清楚了,要模擬屏幕touch事件,只要通過:

cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesBegin/handleTouchesEnd/handleTouchesMove

這幾個接口就可以實現了。

這樣,就可以在telnet終端裏輸入

>touch tap 300 600

>touch swipe 800 600 800 300

來模擬touch事件了

代碼可以看這裏:

https://github.com/cocos2d/cocos2d-x/pull/5462


發佈了72 篇原創文章 · 獲贊 7 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章