15

私は現在、アンドロイド用のエアホッケーシミュレーションを開発しています。マルチプレイヤー モードでは、画面上の 2 つのタッチ イベントを追跡しています。これは、タッチ ポイントが閉じない限りうまく機能します。 ノーマルタッチ

2 本の指が近づくと、Android は両方のポイントの中間にある 1 つのタッチ イベントのみを認識します。

2つのイベントが重なる

さらに悪いことに、Android は衝突後に ID を台無しにすることがあります。

間違った ID が割り当てられている

私はすでに次のタッチポイントを推定し、ID を手動で割り当てることを考えていましたが、より良い方法を知っている人や、この問題をプログラムで既に修正した人を知っている人はいますか?

注:Samsung Galaxy S 3でテストしています

4

3 に答える 3

6

必ずしも問題の論理的な修正ではありませんが、アプリケーションの可能な解決策は次のとおりです。

私が完全に間違っていなければ、エアホッケーの試合では対戦相手がお互いの試合場に侵入することを許すべきではありません。太い境界線が画面の中央を横切ると仮定した場合 (ポートレート モード)、その境界線を超えて何かを行うことは許可されないため、境界線に到達した後に指を追跡しても意味がありません。

追跡されたタッチ イベントを有効な物理的な位置にカプセル化すると、無効なポイントを無視するのに役立つ場合があります (物理的な位置が交差しない場合)。

また、タッチ ベクトルの方向を追跡する必要がある場合もあります。ベクトルが画面の中心から「自分の端」に向かって伸びている場合、それは相手の侵入指または自分の戻ってきた指である可能性があります。どちらの場合も、ホッケーのパックに影響を与えるべきではありません (おそらく)。

于 2012-09-26T13:18:39.277 に答える
2

使用しているデバイスによって異なる場合がありますが、私は以下のコードを Huawei X5 で使用しています。

private static PointF touchScreenStartPtArr[] = new PointF[10];
private static PointF touchScreenStopPtArr[] = new PointF[10];
private static PointF touchScreenCurrPtArr[] = new PointF[10];

OnTouchListener onTouchListenerMulti = new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        int action = event.getAction() & MotionEvent.ACTION_MASK;
        int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
        int fingerId = event.getPointerId(pointerIndex);

        switch (action) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_POINTER_DOWN:
            touchScreenStartPtArr[fingerId].x = event.getX(pointerIndex);
            touchScreenStartPtArr[fingerId].y = event.getY(pointerIndex);
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_POINTER_UP:
        case MotionEvent.ACTION_CANCEL:
            touchScreenStopPtArr[fingerId].x = event.getX(pointerIndex);
            touchScreenStopPtArr[fingerId].y  = event.getX(pointerIndex);
            break;
        case MotionEvent.ACTION_MOVE:
            int pointerCount = event.getPointerCount();
            for (int i = 0; i < pointerCount; i++) {
                touchScreenCurrPtArr[fingerId].x = event.getX(i);
                touchScreenCurrPtArr[fingerId].y = event.getY(i);
            }
            break;
        }
        return true;
    }
};  

1 本の指が離されるとポインター ID が変わる可能性があるため、正しい指を識別するために pointerId ではなく fingerId を使用していることに注意してください。

それがうまくいくことを願っています。

于 2012-09-28T18:30:04.320 に答える
2

これが私がそれを見る方法です。

タッチスクリーン ハードウェアは、2 回のタッチが 1 回のタッチと同じになる解像度を提供します。これは変更できないものです。

問題は、2 つのタッチが融合したときにどうするかということです。(これは、プログラムでテストできるものです。たとえば、2 タッチ ポイント -> 1 タッチ ポイントで、かつ、前のタッチ ポイント 1 が前のタッチ ポイント 2 に十分近い場合...)。あなたの場合、両方のパックをマージされたタッチ ジェスチャに沿って分離するまで移動し、個別のコントロールを返します。

もちろん、スプリット後にどのタッチがどのパックをコントロールするかなど、これにはいくつかの問題があります。マージ中に 1 人が指を離したのかもしれません。

マージが発生した場合、両方のプレーヤーがパックのコントロールを失う可能性があります。これは、あなたの手が対戦相手の手にぶつかるときの手首への衝撃をシミュレートできます:)

@dbm のアイデアも気に入っています。

お役に立てれば。おそらくしませんでした:)

于 2012-09-28T20:13:25.033 に答える