我正在做一个Pong克隆,我已经将球实现为Rect()对象。现在移动球我使用Rect.offset(dx,dy),它以一个特定的速度抵消球。为了将球从墙上弹开,我将各轴的速度乘以-1。现在,为了沿着Y轴反弹,它会完美地反弹,但是沿着X轴它开始奇怪的行为。这是Android工作室的一些小故障,还是我做错了什么?
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.view.MotionEvent;
import android.view.View;
public class PongLogic extends View {
//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) ;
//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);
//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 = 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 mytext = new Paint();
mytext.setColor(Color.WHITE);
//mytext.setStyle(Paint.Style.STROKE);
//mytext.setStrokeWidth(2);
// Draw Middle point
canvas.drawRect(0, ((dptopixel(dpHeight)) / 2), (dptopixel(dpWidth)), (((dptopixel(dpHeight)) / 2) + 2), mytext);
//draw both paddles
canvas.drawRect(paddle_user,mytext);
canvas.drawRect(paddle_AI, mytext);
//draw ball
canvas.drawRect(ball,mytext);
//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.centerX() > (dptopixel(dpWidth))/2){
ball.offset(-ball_velocity,ball_velocity);
}
else{
ball.offset(ball_velocity,ball_velocity);
}
}
//Override Touch method
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
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
}
}
答案 0 :(得分:0)
好的,我已经弄清楚为什么偏移方法表现不正常。首先,我在条件的else部分中有原始偏移位置。第二,我只在if评估为true时否定了dx组件。这只发生在一帧,因为我正在评估Rect对象的X位置。一旦从球的位置减去-dx,就会导致它变为假。
要解决它,我必须将偏移量置于条件之外,并为dx和dy传递两个单独的值。然后我调整了条件,以便它只为变量分配正值和负值,然后传递给offset()函数,而不是调用offset函数本身。
这是新的update()
方法
private void update() {
if (ball.centerX() > (dptopixel(dpWidth))/2){
ball_velocity_x = -3;
}
else if (ball.centerY() > (dptopixel(dpHeight))) {
ball_velocity_y = -3;
}
ball.offset(ball_velocity_x, ball_velocity_y);
}