Bounce bola atrás android

He tomado Ejemplo de Acelerador con SensorManager, en el que lienzo (bola) se ponen al día su posición según el dispositivo Acelerador se rotan. Aquí está la imagen:

introduzca la descripción de la imagen aquí

Como se muestra en la imagen hay una bola y una línea. La posición de la pelota se actualiza con frecuencia, mientras que la posición de la línea es estática.

Me gustaría que la bola rebote cuando toque la línea. He intentado desde el 3 de día, pero no entiendo cómo puedo hacer esto.

aquí está mi código:

public class ballsensor extends Activity implements SensorEventListener { // sensor-related private SensorManager mSensorManager; private Sensor mAccelerometer; // animated view private ShapeView mShapeView; // screen size private int mWidthScreen; private int mHeightScreen; // motion parameters private final float FACTOR_FRICTION = 0.5f; // imaginary friction on the // screen private final float GRAVITY = 9.8f; // acceleration of gravity private float mAx; // acceleration along x axis private float mAy; // acceleration along y axis private final float mDeltaT = 0.5f; // imaginary time interval between each // acceleration updates // timer private Timer mTimer; private Handler mHandler; private boolean isTimerStarted = false; private long mStart; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // set the screen always portait setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); // initializing sensors mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); mAccelerometer = mSensorManager .getDefaultSensor(Sensor.TYPE_ACCELEROMETER); // obtain screen width and height Display display = ((WindowManager) this .getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); mWidthScreen = display.getWidth(); mHeightScreen = display.getHeight() - 35; // initializing the view that renders the ball mShapeView = new ShapeView(this); mShapeView.setOvalCenter((int) (mWidthScreen * 0.6), (int) (mHeightScreen * 0.6)); setContentView(mShapeView); } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } @Override public void onSensorChanged(SensorEvent event) { // obtain the three accelerations from sensors mAx = event.values[0]; mAy = event.values[1]; float mAz = event.values[2]; // taking into account the frictions mAx = Math.signum(mAx) * Math.abs(mAx) * (1 - FACTOR_FRICTION * Math.abs(mAz) / GRAVITY); mAy = Math.signum(mAy) * Math.abs(mAy) * (1 - FACTOR_FRICTION * Math.abs(mAz) / GRAVITY); } @Override protected void onResume() { super.onResume(); // start sensor sensing mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onPause() { super.onPause(); // stop senser sensing mSensorManager.unregisterListener(this); } // the view that renders the ball private class ShapeView extends SurfaceView implements SurfaceHolder.Callback { private final int RADIUS = 30; private final float FACTOR_BOUNCEBACK = 0.50f; private int mXCenter; private int mYCenter; private RectF mRectF; private final Paint mPaint; private ShapeThread mThread; private float mVx; private float mVy; public ShapeView(Context context) { super(context); getHolder().addCallback(this); mThread = new ShapeThread(getHolder(), this); setFocusable(true); mPaint = new Paint(); mPaint.setColor(0xFFFFFFFF); mPaint.setAlpha(192); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); mPaint.setAntiAlias(true); mRectF = new RectF(); } // set the position of the ball public boolean setOvalCenter(int x, int y) { mXCenter = x; mYCenter = y; return true; } // calculate and update the ball's position public boolean updateOvalCenter() { mVx -= mAx * mDeltaT; mVy += mAy * mDeltaT; System.out.println("mVx is ::" + mVx); System.out.println("mVy is ::" + mVy); mXCenter += (int) (mDeltaT * (mVx + 0.6 * mAx * mDeltaT)); mYCenter += (int) (mDeltaT * (mVy + 0.6 * mAy * mDeltaT)); if (mXCenter < RADIUS) { mXCenter = RADIUS; mVx = -mVx * FACTOR_BOUNCEBACK; } if (mYCenter < RADIUS) { mYCenter = RADIUS; mVy = -mVy * FACTOR_BOUNCEBACK; } if (mXCenter > mWidthScreen - RADIUS) { mXCenter = mWidthScreen - RADIUS; mVx = -mVx * FACTOR_BOUNCEBACK; } if (mYCenter > mHeightScreen - 2 * RADIUS) { mYCenter = mHeightScreen - 2 * RADIUS; mVy = -mVy * FACTOR_BOUNCEBACK; } return true; } // update the canvas. @Override protected void onDraw(Canvas canvas) { if (mRectF != null) { mRectF.set(mXCenter - RADIUS, mYCenter - RADIUS, mXCenter + RADIUS, mYCenter + RADIUS); canvas.drawColor(0XFF000000); // canvas.drawOval(mRectF, mPaint); Bitmap kangoo = BitmapFactory.decodeResource(getResources(), R.drawable.stripe1); Bitmap ball = BitmapFactory.decodeResource(getResources(), R.drawable.blackwhiteball); canvas.drawBitmap(ball, mXCenter - RADIUS, mYCenter - RADIUS, mPaint); canvas.drawBitmap(kangoo, 130, 10, null); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { mThread.setRunning(true); mThread.start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { boolean retry = true; mThread.setRunning(false); while (retry) { try { mThread.join(); retry = false; } catch (InterruptedException e) { } } } } class ShapeThread extends Thread { private SurfaceHolder mSurfaceHolder; private ShapeView mShapeView; private boolean mRun = false; public ShapeThread(SurfaceHolder surfaceHolder, ShapeView shapeView) { mSurfaceHolder = surfaceHolder; mShapeView = shapeView; } public void setRunning(boolean run) { mRun = run; } public SurfaceHolder getSurfaceHolder() { return mSurfaceHolder; } @Override public void run() { Canvas c; while (mRun) { mShapeView.updateOvalCenter(); c = null; try { c = mSurfaceHolder.lockCanvas(null); synchronized (mSurfaceHolder) { mShapeView.onDraw(c); } } finally { if (c != null) { mSurfaceHolder.unlockCanvasAndPost(c); } } } } } } 

En lugar de intentar arreglar su código, trabaje a nivel de diseño desarrollando una arquitectura de software que tenga dos componentes: el modelo de física y la pantalla. La clave es separar la física del problema de la pantalla. Modelar la física se hace mucho más fácil cuando se hace por separado de la pantalla. Asimismo, la pantalla también se vuelve más fácil. Tenga dos paquetes separados – uno para la física y otro para la pantalla.

Comience con una versión más simple del problema donde el mundo de la física sólo tiene un punto y una línea. Modela el punto que se refleja fuera de la línea. Tienes algún código que hace esto. Basta con extraerlo del código actual. Asegúrese de que la física hace lo que usted espera sin preocuparse por la pantalla.

Diseñe una clase para la pelota. La pelota tiene propiedades de velocidad y posición. Tiene un método de movimiento que actualiza la posición basada en la velocidad de un clic de tiempo. El método de movimiento comprueba si ha interactuado (chocó) con la pared y cambia la velocidad de acuerdo a la física que desea que su mundo tenga. La detección de colisión se realiza preguntando a la pared si es. La física podría ser ángulo de incidencia igual a ángulo de reflexión, o podría tener una propiedad de spin en la pelota que cambia la forma en que la pelota rebote. La clave es que todo el modelado de la física se realiza por separado de la pantalla. Del mismo modo, crear una clase para la pared. Inicialmente la pared es fija, pero se podría añadir movimiento a ella. Lo bueno es que si has diseñado la clase de pelota correctamente cambiar la pared para que se mueva no afecta el diseño de la clase de pelota. Además, ninguno de estos cambios en la física afectan la forma en que se realiza la visualización.

Hacer una pantalla que simplemente traduce la física en una presentación en la pantalla.

A partir de ahí, puede agregar complejidad a su modelo. Haz que el punto sea un círculo. Rehacer la física para que funcione con esta nueva complejidad. La pantalla no cambiará mucho, pero manténgala separada.

Tengo mi clase CS1 hacer versiones de este mismo problema. Hace dos años, les pedí que hicieran un juego de pong. El año pasado una versión de Ciempiés. Este próximo semestre tendrán Breakout como un proyecto. Cuando modelan la física por separado de la pantalla, lo hacen funcionar. Cuando no lo hacen, por lo general es un lío confuso.

Physyle modyle se ejecutará en hilos separados, y utilizar la mejor resolución de tiempo disponible para las actualizaciones de posición. (milisegundos debería ser suficiente) Así es como diseño gameloop:

  lastFrameTime = System.currentTimeMillis(); // as long as we run we move while (state == GameState.RUNNING) { currentFrame++; timeNow = System.currentTimeMillis(); // sleep until this frame is scheduled long l = lastFrameTime + FRAME_DELAY - timeNow; updatePositions(); redraw(); if (l > 0L) { try { Thread.sleep(l); } catch (Exception exception) { } } else { // something long kept us from updating, reset delays lastFrameTime = timeNow; l = FRAME_DELAY; } lastFrameTime = timeNow + l; // be polite, let others play Thread.yield(); } 

Es importante abandonar el control del hilo, para tareas de interfaz de usuario que procesarán eventos y comandos de colmena a su motor phyiscs.

En cuanto a la detección de colisiones – es bastante simple de matemáticas. Su línea es vertical, y zou sólo debe comprobar si la diferencia en x-coord de la línea y el centro es menor que el radio – a continuación, inversa x-componen de la velocidad

Puede usar Rect.intersects (Rect, Rect) para detectar colisiones. Utilice su ancho de mapa de bits y altura para configurar los nuevos Rects.

Aquí hay un ejemplo sucio:

 import java.util.Timer; import android.app.Activity; import android.content.Context; import android.content.pm.ActivityInfo; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.os.Handler; import android.view.Display; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.WindowManager; public class ballsensor extends Activity implements SensorEventListener { // sensor-related private SensorManager mSensorManager; private Sensor mAccelerometer; // animated view private ShapeView mShapeView; // screen size private int mWidthScreen; private int mHeightScreen; // motion parameters private final float FACTOR_FRICTION = 0.5f; // imaginary friction on the // screen private final float GRAVITY = 9.8f; // acceleration of gravity private float mAx; // acceleration along x axis private float mAy; // acceleration along y axis private final float mDeltaT = 0.5f; // imaginary time interval between each // acceleration updates // timer private Timer mTimer; private Handler mHandler; private final boolean isTimerStarted = false; private long mStart; @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); // set the screen always portait setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); // initializing sensors mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); mAccelerometer = mSensorManager .getDefaultSensor(Sensor.TYPE_ACCELEROMETER); // obtain screen width and height final Display display = ((WindowManager) this .getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); mWidthScreen = display.getWidth(); mHeightScreen = display.getHeight() - 35; // initializing the view that renders the ball mShapeView = new ShapeView(this); mShapeView.setOvalCenter((int) (mWidthScreen * 0.6), (int) (mHeightScreen * 0.6)); setContentView(mShapeView); } @Override public void onAccuracyChanged(final Sensor sensor, final int accuracy) { } @Override public void onSensorChanged(final SensorEvent event) { // obtain the three accelerations from sensors mAx = event.values[0]; mAy = event.values[1]; final float mAz = event.values[2]; // taking into account the frictions mAx = Math.signum(mAx) * Math.abs(mAx) * (1 - FACTOR_FRICTION * Math.abs(mAz) / GRAVITY); mAy = Math.signum(mAy) * Math.abs(mAy) * (1 - FACTOR_FRICTION * Math.abs(mAz) / GRAVITY); } @Override protected void onResume() { super.onResume(); // start sensor sensing mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onPause() { super.onPause(); // stop senser sensing mSensorManager.unregisterListener(this); } // the view that renders the ball private class ShapeView extends SurfaceView implements SurfaceHolder.Callback { private final int RADIUS = 30; private final float FACTOR_BOUNCEBACK = 0.50f; private int mXCenter; private int mYCenter; private final RectF mRectF; private final Paint mPaint; private final ShapeThread mThread; private float mVx; private float mVy; private final Rect lineRect = new Rect(); private final Rect ballRect = new Rect(); public ShapeView(final Context context) { super(context); getHolder().addCallback(this); mThread = new ShapeThread(getHolder(), this); setFocusable(true); mPaint = new Paint(); mPaint.setColor(0xFFFFFFFF); mPaint.setAlpha(192); mPaint.setStyle(Paint.Style.FILL_AND_STROKE); mPaint.setAntiAlias(true); mRectF = new RectF(); } // set the position of the ball public boolean setOvalCenter(final int x, final int y) { mXCenter = x; mYCenter = y; return true; } // calculate and update the ball's position public boolean updateOvalCenter() { mVx -= mAx * mDeltaT; mVy += mAy * mDeltaT; System.out.println("mVx is ::" + mVx); System.out.println("mVy is ::" + mVy); mXCenter += (int) (mDeltaT * (mVx + 0.6 * mAx * mDeltaT)); mYCenter += (int) (mDeltaT * (mVy + 0.6 * mAy * mDeltaT)); if (mXCenter < RADIUS) { mXCenter = RADIUS; mVx = -mVx * FACTOR_BOUNCEBACK; } if (mYCenter < RADIUS) { mYCenter = RADIUS; mVy = -mVy * FACTOR_BOUNCEBACK; } if (mXCenter > mWidthScreen - RADIUS) { mXCenter = mWidthScreen - RADIUS; mVx = -mVx * FACTOR_BOUNCEBACK; } if (mYCenter > mHeightScreen - 2 * RADIUS) { mYCenter = mHeightScreen - 2 * RADIUS; mVy = -mVy * FACTOR_BOUNCEBACK; } if(Rect.intersects(lineRect, ballRect)){ mVx = -mVx * FACTOR_BOUNCEBACK; mVy = -mVy * FACTOR_BOUNCEBACK; mXCenter += (int) (mDeltaT * (mVx + 0.6 * mAx * mDeltaT)) * 5; mYCenter += (int) (mDeltaT * (mVy + 0.6 * mAy * mDeltaT)) * 5; } return true; } // update the canvas. @Override protected void onDraw(final Canvas canvas) { if (mRectF != null) { mRectF.set(mXCenter - RADIUS, mYCenter - RADIUS, mXCenter + RADIUS, mYCenter + RADIUS); canvas.drawColor(0XFF000000); // canvas.drawOval(mRectF, mPaint); final Bitmap kangoo = BitmapFactory.decodeResource(getResources(), R.drawable.blankcard); lineRect.set(130, 10, 130 + kangoo.getWidth(), 10 + kangoo.getHeight()); final Bitmap ball = BitmapFactory.decodeResource(getResources(), R.drawable.blankcard); ballRect.set(mXCenter - RADIUS, mYCenter - RADIUS, mXCenter - RADIUS + ball.getWidth(), mYCenter - RADIUS + ball.getHeight()); canvas.drawBitmap(ball, mXCenter - RADIUS, mYCenter - RADIUS, mPaint); canvas.drawBitmap(kangoo, 130, 10, null); } } @Override public void surfaceChanged(final SurfaceHolder holder, final int format, final int width, final int height) { } @Override public void surfaceCreated(final SurfaceHolder holder) { mThread.setRunning(true); mThread.start(); } @Override public void surfaceDestroyed(final SurfaceHolder holder) { boolean retry = true; mThread.setRunning(false); while (retry) { try { mThread.join(); retry = false; } catch (final InterruptedException e) { } } } } class ShapeThread extends Thread { private final SurfaceHolder mSurfaceHolder; private final ShapeView mShapeView; private boolean mRun = false; public ShapeThread(final SurfaceHolder surfaceHolder, final ShapeView shapeView) { mSurfaceHolder = surfaceHolder; mShapeView = shapeView; } public void setRunning(final boolean run) { mRun = run; } public SurfaceHolder getSurfaceHolder() { return mSurfaceHolder; } @Override public void run() { Canvas c; while (mRun) { mShapeView.updateOvalCenter(); c = null; try { c = mSurfaceHolder.lockCanvas(null); synchronized (mSurfaceHolder) { mShapeView.onDraw(c); } } finally { if (c != null) { mSurfaceHolder.unlockCanvasAndPost(c); } } } } } } 

Necesita mejoras, pero puede ser que usted en el camino correcto.

  • .execute no se puede resolver a un tipo - AsyncTask (Android)
  • ¿Por qué el diálogo personalizado de Android aparece en pantalla completa?
  • Pasando el archivo con intención, ¿cómo lo recupero?
  • Android: IllegalStateException llamando a DialogFragment
  • Android - Excepción fatal: junit.framework.AssertionFailedError en WebViewCore
  • Tiempo desde el primer arranque
  • Android uiautomator runtest error no encontró clase
  • Cómo establecer TimeZone en android
  • onclicklistener en el elemento específico de la recyclerview en android
  • System.out.println en la prueba de Android
  • Iterate Json datos del servicio web en el orden correcto
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.