Skip to content

cocos2d-x CCTableViewのtableCellTouchedがAndroidでうまく動かない件をとりあえず解決

2013年1月16日

CCTableViewをアンドロイド実機でみてみると、なかなかタッチができない状況に陥った。

原因を調べてみると、フォーラムで以下のようなやり取りが行われていた。
http://www.cocos2d-x.org/boards/6/topics/16462

要約すると、

ハイエンドのAndroidはタッチの判定が繊細で、タッチしようとしてもドラッグ扱いになってしまう。

ということだった。

つまり、「タッチしようとした時に、1pxも指を動かさずにタッチしないとタッチしたことにならないよ!

ということらしい。そしてフォーラム内でもそれはバグだとジェームズ・チャン氏が言っている。

そのやり取り内で、「CCScrollView内でしきい値を設定してやればなんとかなるよ!」といっているのでやってみた。

CCScrollView.h
以下をhで宣言する。

CCPoint tmpBeganPoint;

CCScrollView.cpp

bool CCScrollView::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
    if (!this->isVisible())
    {
        return false;
    }
    CCRect frame;
    CCPoint frameOriginal = this->getParent()->convertToWorldSpace(this->getPosition());
    frame = CCRectMake(frameOriginal.x, frameOriginal.y, m_tViewSize.width, m_tViewSize.height);

    //dispatcher does not know about clipping. reject touches outside visible bounds.
    if (m_pTouches->count() > 2 ||
        m_bTouchMoved          ||
        !frame.containsPoint(m_pContainer->convertToWorldSpace(m_pContainer->convertTouchToNodeSpace(touch))))
    {
        return false;
    }

    if (!m_pTouches->containsObject(touch))
    {
        m_pTouches->addObject(touch);
    }

    if (m_pTouches->count() == 1)
    { // scrolling

        tmpBeganPoint = this->convertTouchToNodeSpace(touch); // Add here!

        m_tTouchPoint     = this->convertTouchToNodeSpace(touch);
        m_bTouchMoved     = false;
        m_bDragging     = true; //dragging started
        m_tScrollDistance = ccp(0.0f, 0.0f);
        m_fTouchLength    = 0.0f;
    }
    else if (m_pTouches->count() == 2)
    {
        m_tTouchPoint  = ccpMidpoint(this->convertTouchToNodeSpace((CCTouch*)m_pTouches->objectAtIndex(0)),
                                   this->convertTouchToNodeSpace((CCTouch*)m_pTouches->objectAtIndex(1)));
        m_fTouchLength = ccpDistance(m_pContainer->convertTouchToNodeSpace((CCTouch*)m_pTouches->objectAtIndex(0)),
                                   m_pContainer->convertTouchToNodeSpace((CCTouch*)m_pTouches->objectAtIndex(1)));
        m_bDragging  = false;
    } 
    return true;
}

あとは以下を、ccTouchMovedの
[newPoint = this->convertTouchToNodeSpace((CCTouch*)m_pTouches->objectAtIndex(0));]の下辺りに追加する

 float x = tmpBeganPoint.x - newPoint.x;
 float y = tmpBeganPoint.y - newPoint.y;
 if ( (-20 < x && x < 20) && (-20 < y && y < 20)  ) {
    m_bTouchMoved = false;
}

という風にすればいける。

これだと、タッチ開始からX,Yともにプラマイ20の幅だったらタッチにする、という感じになる。
もちろん、しきい値を変更すれば細かく取れるようにはなる。いちおう調べてみて、10くらいがちょうどいいかな、と感じた。

広告
コメントする

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。