在 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
我正在尝试实现轻扫触摸来控制应用程序中的桨,我已经设法通过检测单次触摸来移动桨,但我不明白如何进行投掷操作。我已经尝试通过参考官方 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