在 App 中检测 Fling touch

Detecting Fling touch in App

我正在尝试实现轻扫触摸来控制应用程序中的桨,我已经设法通过检测单次触摸来移动桨,但我不明白如何进行投掷操作。我已经尝试通过参考官方 android docs 来实施这个解决方案,但这会使应用程序崩溃。有什么建议吗?

package com.nblsoft.pong;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.v4.view.GestureDetectorCompat;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;



public class PongLogic extends View {

    MainActivity mainactivity = (MainActivity) getContext();
    private GestureDetectorCompat mDetector = new GestureDetectorCompat(mainactivity, new MyGestureListner());


    //set screen constrains in dip
    Configuration configuration = this.getResources().getConfiguration();
    int dpHeight = configuration.screenHeightDp; //The current height of the available screen space, in dp units, corresponding to screen height resource qualifier.
    int dpWidth = configuration.screenWidthDp; //The current width of the available screen space, in dp units, corresponding to screen width resource qualifier.

    //int smallestScreenWidthDp = configuration.smallestScreenWidthDp; //The smallest screen size an application will see in normal operation, corresponding to smallest screen width resource qualifier.

    //DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();
    //float dpHeight = displayMetrics.heightPixels / displayMetrics.density;
    //float dpWidth = displayMetrics.widthPixels / displayMetrics.density;

    private int dptopixel(int DESIRED_DP_VALUE) {

        final float scale = getResources().getDisplayMetrics().density;

        return (int) ((DESIRED_DP_VALUE) * scale + 0.5f);
    }

    private int pixeltodp(int DESIRED_PIXEL_VALUE) {

        final float scale = getResources().getDisplayMetrics().density;

        return (int) ((DESIRED_PIXEL_VALUE) - 0.5f / scale);
    }

    //set paddle size, speed, position vector

    int AI_paddle_pos_x = 4 * (dptopixel(dpWidth) / 100);           //3 for 320x480, 10 for 1080x1920 etc.
    int paddle_width = (dptopixel(dpWidth) / 10);            //
    int AI_paddle_pos_y = (dptopixel(dpHeight) / 10);           //48 for 320x480, 190 for 1080x1920 etc.
    int paddle_height = (dptopixel(dpHeight) / 100) + 3;      //the paddle is 100% of the total height of phone.

    int user_paddle_pos_x = 4 * (dptopixel(dpWidth) / 100);
    int user_paddle_pos_y = dptopixel(dpHeight) - ((dptopixel(dpHeight) / 10) + (dptopixel(dpHeight) / 100) + 3);


    //Score
    int score_user = 0;
    int score_AI = 0;

    //User Paddle
    public Rect paddle_user = new Rect(user_paddle_pos_x,
            user_paddle_pos_y,
            user_paddle_pos_x + paddle_width,
            user_paddle_pos_y + paddle_height);

    int user_paddle_vel = 0;

    //AI paddle
    Rect paddle_AI = new Rect(AI_paddle_pos_x,
            AI_paddle_pos_y,
            AI_paddle_pos_x + paddle_width,
            AI_paddle_pos_y + paddle_height);



    //set ball position vector, Velocity vector, acceleration
    int ball_pos_x = 0;
    int ball_pos_y = (dptopixel(dpHeight) / 2);
    int ball_size = dptopixel(dpWidth) / 100;
    int ball_velocity_x = 1;
    int ball_velocity_y = 3;


    // Ball
    Rect ball = new Rect(ball_pos_x,
            ball_pos_y,
            ball_pos_x + ball_size,
            ball_pos_y + ball_size);


    //Override onDraw method
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Paint myUI = new Paint();
        myUI.setColor(Color.WHITE);

        Paint myscore = new Paint();
        myscore.setTextSize(dptopixel(dpWidth / 20));
        myscore.setColor(Color.WHITE);

        //mytext.setStyle(Paint.Style.STROKE);
        //mytext.setStrokeWidth(2);


        // Draw Score
        canvas.drawText(Integer.toString(score_AI), (dptopixel(dpWidth) / 10), (dptopixel(dpHeight) / 4), myscore);
        canvas.drawText(Integer.toString(score_user), (dptopixel(dpWidth) / 10), 3 * (dptopixel(dpHeight) / 4), myscore);

        // Draw Middle point
        canvas.drawRect(0, ((dptopixel(dpHeight)) / 2), (dptopixel(dpWidth)), (((dptopixel(dpHeight)) / 2) + 2), myUI);

        // Draw both paddles
        canvas.drawRect(paddle_user, myUI);
        canvas.drawRect(paddle_AI, myUI);

        // Draw ball
        canvas.drawRect(ball, myUI);


        //Practise Methods
        //canvas.drawText(Integer.toString(dptopixel(dpHeight)),300,300,mytext);
        //canvas.drawText(Integer.toString(dptopixel(dpWidth)), 400, 400, mytext);

        //canvas.drawText(Integer.toString(dpHeight),500,500,mytext);
        //canvas.drawText(Integer.toString(dpWidth),600,600,mytext);

        //canvas.drawText("Fuck", 700, 700, mytext);
        //canvas.drawRect(0,0,dptopixel(dpWidth),dptopixel(dpHeight),mytext);


        //Game Loop Updater
        update();
        invalidate();
    }

    private void update() {

        if(ball.centerY() < dptopixel(dpHeight)/2){ paddle_AI.offsetTo(ball.centerX()- dptopixel(10), AI_paddle_pos_y); }

        if (paddle_user.contains(ball)) {
            ball_velocity_y = ball_velocity_y * -1;

        } else if (paddle_AI.contains(ball)) {
            ball_velocity_y = ball_velocity_y * -1;
        } else if ((ball.centerX() > (dptopixel(dpWidth))) || (ball.centerX() < 0)) {
            ball_velocity_x = ball_velocity_x * -1;
        } else if (ball.centerY() < 0) {

            //Update the user score
            score_user = 1 + score_user;

            //re draw the ball
            ball.offsetTo(0, (dptopixel(dpHeight) / 2));
        } else if (ball.centerY() > (dptopixel(dpHeight))) {

            //Update the AI score
            score_AI = 1 + score_AI;

            //re draw the ball
            ball.offsetTo(0, (dptopixel(dpHeight) / 2));
        }

        ball.offset(ball_velocity_x, ball_velocity_y);
    }


    //Override Touch method

    /*
    //
        NOT WORKING SWIPE METHODS

    float x1, x2, y1, y2;
    final int MIN_DISTANCE = 70;
    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                x1 = event.getX();
                y1 = event.getY();
                break;
            case MotionEvent.ACTION_UP:
                x2 = event.getX();
                y2 = event.getY();
                float deltaX = x2 - x1;
                float deltaY = y2 - y1;
                if (deltaX > MIN_DISTANCE)
                {
                    paddle_user.offset(1, 0);
                    break;
                }
                else if (Math.abs(deltaX) > MIN_DISTANCE)
                {
                    paddle_user.offset(-1, 0);

                    break;
                }

        }
        return true;

    }*/



    @Override
    public boolean onTouchEvent(MotionEvent event) {

        this.mDetector.onTouchEvent(event);
        return super.onTouchEvent(event);

/*
        if (event.getAction() == MotionEvent.ACTION_MOVE) {
            if (event.getX() > dptopixel(dpWidth) / 2) {
                paddle_user.offset(10, 0);
            } else {
                paddle_user.offset(-10, 0);
            }
        }
        return true;
*/
    }

/*    @Override
    public boolean onTouch(View v, MotionEvent event) {
        this.paddle_user.offsetTo(10,10);
        return true; //Event Handled
    }
*/

    public PongLogic(Context context) {
        super(context);
        setBackgroundColor(Color.BLACK);            //to set background
        this.setFocusableInTouchMode(true);             //to enable touch mode
    }

class MyGestureListner extends GestureDetector.SimpleOnGestureListener{

    @Override
    public boolean onFling(MotionEvent event1, MotionEvent event2,
                           float velocityX, float velocityY) {
        if (event1.getAction() == MotionEvent.ACTION_DOWN) {
            user_paddle_vel = (int) velocityX;
            paddle_user.offset(user_paddle_vel,0);
        }
        else if(event1.getAction() == MotionEvent.ACTION_UP){
            user_paddle_vel = 0;
        }
        return true;
    }
}

}

你可以看看我在 Medium 上的文章,我一步一步地解释了如何去做:https://medium.com/@euryperez/android-pearls-detect-swipe-and-touch-over-a-view-203ae2c028dc#.lcmg4jytc