2016-02-25 7 views
0

Я делаю клон-понг, и я реализовал мяч как объект Rect(). Теперь, чтобы переместить мяч, я использую Rect.offset (dx, dy), который смещает мяч с определенной скоростью. Для отскока шара от стены я умножаю скорость соответствующей оси на -1. Теперь для отскока по оси Y он отлично отскакивает, но по оси X он начинает странно странно. Это какой-то сбой с андроид-студией или я что-то делаю неправильно?Rect.offset() не работает вдоль отрицательной оси x

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

'Rect # смещение (Dx, Dy)' не имеет ничего магического с ' "отрицательной оси х" ': см [здесь] (http://androidxref.com /6.0.1_r10/xref/frameworks/base/graphics/java/android/graphics/Rect.java#280) – pskink

+0

Когда я передаю 'ball.offset (ball_velocity, -1 * ball_velocity)' мяч правильно отскакивает от нижнего края , Однако при передаче 'ball.offset (-1 * ball_velocity, ball_velocity)' вместо того, чтобы отскакивать назад от вертикального края, он начинает тянуться к нижней части экрана. Почему это происходит? Должен ли я использовать какой-либо другой способ перемещения мяча? –

+0

отлаживать ваш код тогда: как вы видели, нет ничего загадочного в коде 'Rect # offset' – pskink

ответ

0

Хорошо, я выяснил, почему метод смещения ведет себя беспорядочно. Сначала у меня была исходная позиция смещения в другой части условного. Во-вторых, я отрицал компонент dx только тогда, когда значение if оценивается как true. Это произошло только для одного кадра, потому что я оценивал положение X объекта Rect. Это заставляет его становиться ложным, как только -dx вычитается из положения мяча.

Чтобы решить эту проблему, мне пришлось поместить смещение из условного и передать два отдельных значения для dx и dy. Затем я настроил условное выражение так, чтобы он присваивал только положительные и отрицательные значения переменным, которые позже передавались в функцию 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); 
    }