Простой круговорот с акселерометром
Я снова отредактировал всю тему, основываясь на том, что у меня есть, так как у меня было так много мнений по предыдущей теме и никаких ответов. А пока я разобрался, как работает акселерометр.
Теперь у меня есть круг (холст), который я хотел бы назвать "Зога", если не возражаете. Этот круг должен двигаться в зависимости от угла наклона телефона. Таким образом, в основном, если телефон перемещается на левую сторону, круг перемещается на левую сторону, если телефон перемещается вниз на правую сторону, цикл движется в этом направлении.
Cyrcle создается через класс Zoga.java, и вся магия происходит в GravitacijaActivity.java.
Вот 2 вопроса, которые у меня есть:
1.) Киркл двигается только в левом направлении.
2.) Cyrcle выходит за пределы экрана (на левой стороне курса).
Любые идеи о том, как решить эту проблему?
ПРИМЕЧАНИЕ. Я приложил весь свой код, даже макет main.xml, на тот случай, если кому-то еще понадобится этот код для целей обучения и учебы:)
GravitaijaActivity.java
package gravity.pack;
import android.app.Activity;
import android.os.Bundle;
import android.widget.FrameLayout;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
public class GravitacijaActivity extends Activity implements SensorEventListener{
public float xPos = 50.0f, yPos = 50.0f;
public float xAcc = 0.0f, yAcc = 0.0f;
public int radius = 30;
private SensorManager sensorManager;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
SensorManager.SENSOR_DELAY_GAME);
FrameLayout main = (FrameLayout) findViewById(R.id.main_view);
main.addView(new Zoga(this, xPos, yPos, radius));
}
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
public void onSensorChanged(SensorEvent sensorArg) {
if (sensorArg.sensor.getType() == Sensor.TYPE_ORIENTATION)
{
xAcc = sensorArg.values[1];
yAcc = sensorArg.values[2];
updateZoga();
}
}
public void updateZoga()
{
xPos += xAcc;
yPos += yAcc;
FrameLayout main = (FrameLayout) findViewById(R.id.main_view);
main.removeAllViews();
main.addView(new Zoga(this, xPos, yPos, radius));
try {
Thread.sleep(1);
} catch (InterruptedException e) {}
}
}
Zoga.java
package gravity.pack;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;
public class Zoga extends View{
private final float x;
private final float y;
private final float r;
private final Paint mPaint = new Paint (Paint.ANTI_ALIAS_FLAG);
public Zoga(Context context, float x, float y, float r) {
super(context);
mPaint.setColor(0xFFFF0000);
this.x = x;
this.y = y;
this.r = r;
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
canvas.drawCircle(x, y, r, mPaint);
}
}
Макет main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="@+id/main_view"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FF66FF33" />
2 ответа
Я сделал некоторые изменения в коде onSensorChange, чтобы переместить шар на экране. С примером в моем случае мяч не двигается правильно, и для этого я сделал изменения. Этот пример хорошо работает для моего.
public void onSensorChanged(SensorEvent sensorEvent)
{
//Try synchronize the events
synchronized(this){
//For each sensor
switch (sensorEvent.sensor.getType()) {
case Sensor.TYPE_MAGNETIC_FIELD: //Magnetic sensor to know when the screen is landscape or portrait
//Save values to calculate the orientation
mMagneticValues = sensorEvent.values.clone();
break;
case Sensor.TYPE_ACCELEROMETER://Accelerometer to move the ball
if (bOrientacion==true){//Landscape
//Positive values to move on x
if (sensorEvent.values[1]>0){
//In margenMax I save the margin of the screen this value depends of the screen where we run the application. With this the ball not disapears of the screen
if (x<=margenMaxX){
//We plus in x to move the ball
x = x + (int) Math.pow(sensorEvent.values[1], 2);
}
}
else{
//Move the ball to the other side
if (x>=margenMinX){
x = x - (int) Math.pow(sensorEvent.values[1], 2);
}
}
//Same in y
if (sensorEvent.values[0]>0){
if (y<=margenMaxY){
y = y + (int) Math.pow(sensorEvent.values[0], 2);
}
}
else{
if (y>=margenMinY){
y = y - (int) Math.pow(sensorEvent.values[0], 2);
}
}
}
else{//Portrait
//Eje X
if (sensorEvent.values[0]<0){
if (x<=margenMaxX){
x = x + (int) Math.pow(sensorEvent.values[0], 2);
}
}
else{
if (x>=margenMinX){
x = x - (int) Math.pow(sensorEvent.values[0], 2);
}
}
//Eje Y
if (sensorEvent.values[1]>0){
if (y<=margenMaxY){
y = y + (int) Math.pow(sensorEvent.values[1], 2);
}
}
else{
if (y>=margenMinY){
y = y - (int) Math.pow(sensorEvent.values[1], 2);
}
}
}
//Save the values to calculate the orientation
mAccelerometerValues = sensorEvent.values.clone();
break;
case Sensor.TYPE_ROTATION_VECTOR: //Rotation sensor
//With this value I do the ball bigger or smaller
if (sensorEvent.values[1]>0){
z=z+ (int) Math.pow(sensorEvent.values[1]+1, 2);
}
else{
z=z- (int) Math.pow(sensorEvent.values[1]+1, 2);
}
default:
break;
}
//Screen Orientation
if (mMagneticValues != null && mAccelerometerValues != null) {
float[] R = new float[16];
SensorManager.getRotationMatrix(R, null, mAccelerometerValues, mMagneticValues);
float[] orientation = new float[3];
SensorManager.getOrientation(R, orientation);
//if x have positives values the screen orientation is landscape in other case is portrait
if (orientation[0]>0){//LandScape
//Here I change the margins of the screen for the ball not disapear
bOrientacion=true;
margenMaxX=1200;
margenMinX=0;
margenMaxY=500;
margenMinY=0;
}
else{//Portrait
bOrientacion=false;
margenMaxX=600;
margenMinX=0;
margenMaxY=1000;
margenMinY=0;
}
}
}
}
Класс просмотра, где я рисую мяч
public class CustomDrawableView extends View
{
static final int width = 50;
static final int height = 50;
//Constructor de la figura
public CustomDrawableView(Context context)
{
super(context);
mDrawable = new ShapeDrawable(new OvalShape());
mDrawable.getPaint().setColor(0xff74AC23);
mDrawable.setBounds(x, y, x + width, y + height);
}
//Dibujamos la figura
protected void onDraw(Canvas canvas)
{
//Actividad_Principal x,y,z are variables from the main activity where I have the onSensorChange
RectF oval = new RectF(Actividad_Principal.x+Actividad_Principal.z, Actividad_Principal.y+Actividad_Principal.z, Actividad_Principal.x + width, Actividad_Principal.y + height);
Paint p = new Paint();
p.setColor(Color.BLUE);
canvas.drawOval(oval, p);
invalidate();
}
}
}
Это все, я надеюсь помочь нам.
Вы делаете ошибку. Вы добавляете значение ускорения к стоимости позиции. Вместо этого вы должны продолжать добавлять значение ускорения, через которое вы получите значение скорости. Теперь, если вы продолжите добавлять значение скорости, вы получите значение позиции. Теперь вам нужно добавить это значение позиции в функцию updateZoga