Android 加速度计移动球

2024-02-21

我在网络上发布的教程的帮助下开发了一个示例应用程序。我的目标是访问加速计并根据手机方向移动球。我在某种程度上是成功的。但我有两个问题

  1. 球超出屏幕范围
  2. 球的运动不顺畅(看起来它消失并重新出现在屏幕上)

这是我的代码。我需要做些什么改变才能让球像我们在很多比赛中看到的那样平滑而准确地移动吗?

public class Accelerometer extends Activity implements SensorEventListener{
    /** Called when the activity is first created. */
    CustomDrawableView mCustomDrawableView = null;
    ShapeDrawable mDrawable = new ShapeDrawable();
    public static int x;
    public static int y;
       private Bitmap mBitmap;
       private Bitmap mWood;
    private SensorManager sensorManager = null;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {

        super.onCreate(savedInstanceState);
        // Get a reference to a SensorManager
        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        mCustomDrawableView = new CustomDrawableView(this);
        setContentView(mCustomDrawableView);
        // setContentView(R.layout.main);

    }

    // This method will update the UI on new sensor events
    public void onSensorChanged(SensorEvent sensorEvent)
    {
        {
           /* if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                // the values you were calculating originally here were over 10000!
                x = (int) Math.pow(sensorEvent.values[0], 2); 
                y = (int) Math.pow(sensorEvent.values[1], 2);

            }*/

            if (sensorEvent.sensor.getType() == Sensor.TYPE_ORIENTATION) {
                  Display display = getWindowManager().getDefaultDisplay(); 
                  int xmax = display.getWidth();
                  int ymax = display.getHeight();
                  x = (int) Math.pow(sensorEvent.values[1], 2); 
                  y = (int) Math.pow(sensorEvent.values[2], 2);
                  if (x > xmax) {
                      x = xmax;
                  } else if (x < -xmax) {
                      x = -xmax;
                  }
                  if (y > ymax) { 
                      y = ymax;
                  } else if (y < -ymax) {
                      y = -ymax;
                  }

            }
        }
    }

    // I've chosen to not implement this method
    public void onAccuracyChanged(Sensor arg0, int arg1)
    {
        // TODO Auto-generated method stub

    }

    @Override
    protected void onResume()
    {
        super.onResume();
        // Register this class as a listener for the accelerometer sensor
        sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                SensorManager.SENSOR_DELAY_GAME);
        // ...and the orientation sensor
        sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                SensorManager.SENSOR_DELAY_NORMAL); 
    }

    @Override
    protected void onStop()
    {
        // Unregister the listener
        sensorManager.unregisterListener(this);
        super.onStop();
    }

    public class CustomDrawableView extends View
    {


        public CustomDrawableView(Context context)
        {
            super(context);

          Bitmap ball = BitmapFactory.decodeResource(getResources(), R.drawable.ball);
          final int dstWidth = 50; 
          final int dstHeight = 50; 
          mBitmap = Bitmap.createScaledBitmap(ball, dstWidth, dstHeight, true);
          mWood = BitmapFactory.decodeResource(getResources(), R.drawable.wood);

        }

        protected void onDraw(Canvas canvas)
        {

            final Bitmap bitmap = mBitmap;

            canvas.drawBitmap(mWood, 0, 0, null);
            canvas.drawBitmap(bitmap, x, y, null);

            invalidate();
        }
    }
}

这和你上一个问题不是同一个问题吗here?! https://stackoverflow.com/questions/6457768/moving-an-image-using-accelerometer-of-anroid您应该只编辑/扩展您原来的问题,而不是开始一个新问题!

但基本上,为了使其更真实,您需要使用 x/y 速度来移动球,而不仅仅是改变位置。因此,您想要一个绘制球的循环,并且想知道当前循环与前一个循环之间的时间差,然后您可以使用简单的运动学方程来计算位置变化。

例如:

newspeed = oldSpeed + (acceleration * time)
distance = (original speed*time) + (0.5 * acceleration * time^2).

您使用传感器输入来设置加速度,然后只需将计算出的距离添加到球位置即可。


编辑-按要求编码。

你很幸运,找到了一个无聊的游戏程序员!无论如何,它并不完美,但它对你有用。您应该给自己买一本游戏开发书籍,并看看如何使用 Open GL,因为它会好得多!

public class test2 extends Activity implements SensorEventListener{

CustomDrawableView mCustomDrawableView = null;
ShapeDrawable mDrawable = new ShapeDrawable();
public float xPosition, xAcceleration,xVelocity = 0.0f;
public float yPosition, yAcceleration,yVelocity = 0.0f;
public float xmax,ymax;
private Bitmap mBitmap;
private Bitmap mWood;
private SensorManager sensorManager = null;
public float frameTime = 0.666f;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{

    super.onCreate(savedInstanceState);

    //Set FullScreen & portrait
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

    // Get a reference to a SensorManager
    sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
            SensorManager.SENSOR_DELAY_GAME);

    mCustomDrawableView = new CustomDrawableView(this);
    setContentView(mCustomDrawableView);
    // setContentView(R.layout.main);

    //Calculate Boundry
    Display display = getWindowManager().getDefaultDisplay();
    xmax = (float)display.getWidth() - 50;
    ymax = (float)display.getHeight() - 50;
}

// This method will update the UI on new sensor events
public void onSensorChanged(SensorEvent sensorEvent)
{
    {
        if (sensorEvent.sensor.getType() == Sensor.TYPE_ORIENTATION) {
            //Set sensor values as acceleration
            yAcceleration = sensorEvent.values[1]; 
            xAcceleration = sensorEvent.values[2];
            updateBall();
        }
    }
}

private void updateBall() {


    //Calculate new speed
    xVelocity += (xAcceleration * frameTime);
    yVelocity += (yAcceleration * frameTime);

    //Calc distance travelled in that time
    float xS = (xVelocity/2)*frameTime;
    float yS = (yVelocity/2)*frameTime;

    //Add to position negative due to sensor 
    //readings being opposite to what we want!
    xPosition -= xS; 
    yPosition -= yS;

    if (xPosition > xmax) {
        xPosition = xmax;
    } else if (xPosition < 0) {
        xPosition = 0;
    }
    if (yPosition > ymax) { 
        yPosition = ymax;
    } else if (yPosition < 0) {
        yPosition = 0;
    }
}

// I've chosen to not implement this method
public void onAccuracyChanged(Sensor arg0, int arg1)
{
    // TODO Auto-generated method stub
}

@Override
protected void onResume()
{
    super.onResume();
    sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
            SensorManager.SENSOR_DELAY_GAME); 
}

@Override
protected void onStop()
{
    // Unregister the listener
    sensorManager.unregisterListener(this);
    super.onStop();
}

public class CustomDrawableView extends View
{
    public CustomDrawableView(Context context)
    {
        super(context);
        Bitmap ball = BitmapFactory.decodeResource(getResources(), R.drawable.ball);
        final int dstWidth = 50; 
        final int dstHeight = 50; 
        mBitmap = Bitmap.createScaledBitmap(ball, dstWidth, dstHeight, true);
        mWood = BitmapFactory.decodeResource(getResources(), R.drawable.wood);

    }

    protected void onDraw(Canvas canvas)
    {
        final Bitmap bitmap = mBitmap;
        canvas.drawBitmap(mWood, 0, 0, null);
        canvas.drawBitmap(bitmap, xPosition, yPosition, null);
        invalidate();
    }
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    // TODO Auto-generated method stub
    super.onConfigurationChanged(newConfig);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android 加速度计移动球 的相关文章

  • 如何在 Flutter 中为 Button 添加渐变?

    有没有办法改变ElevatedButton背景颜色渐变 如果没有一些小瑕疵或问题 例如缺少涟漪效应 不需要的边框 不尊重主题的内容 上述所有解决方案都无法真正发挥作用minWidth对于按钮 The 下面的解决方案没有上述问题 关键部分是使
  • 启动画面反应本机后出现白屏

    编辑 似乎是因为 MainActivity 加载太重而生成白屏 我设法首先使用本机启动屏幕来解决 然后在本机被杀死后立即基于下一个插件的 js 实现 我做了一些修改完美匹配两个启动画面https github com crazycodebo
  • Android 的 GCM 推送通知[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 最近 我尝试学习 GCM 并制作一个测试应用程序 该应用程序将通过 androids 官方网站获取 an
  • Gson.toString() 给出错误“IllegalArgumentException:多个名为 mPaint 的 JSON 字段”

    我想将自定义对象转换为字符串并保存在 SharedPreferences 中 这是我的最终目标 我尝试了下面的行但失败了 String matchString gson toJson userMatches Logcat 10 11 15
  • 如何防止 Activity 在后退操作时重新加载

    我有连接到互联网以获取数据的应用程序 我可以多层次访问数据 假设我从第 3 级开始 在第 4 级我决定返回 每当我按回之前的活动时 就会从互联网重新加载数据 有可能阻止这种情况吗 我尝试以单顶模式运行该活动 将数据加载代码移至 single
  • 尝试使用掩码裁剪位图会抛出 IllegalArgumentException:

    我正在使用以下代码 public void cropSelection Bitmap bitmap annotationBitmap copy annotationBitmap getConfig true Canvas canvas ne
  • 使用反向无限滚动添加到 ListView 时保持滚动位置

    我正在构建一个类似聊天的 Android 应用程序 类似于环聊 为此 我使用垂直 ListViewstackFromBottom true and transcriptMode normal 该列表按从较旧的消息 顶部 到较新的消息 底部
  • 使用 appcelerator titan 在 android 中后退按钮退出应用程序

    我是钛开发的新手 在本机 android 中 如果我们按下后退按钮 则仅当前活动将被关闭 并且它将返回到上一个活动 但是当我使用 Titanium 在 Android 中按下后退按钮时 它会从应用程序退出 我怎样才能改变这种行为 有两种类型
  • 无法解析配置“:app:debugRuntimeClasspath”的所有文件。问题

    我的 android studio 遇到了下一个问题 导致 org gradle api internal artifacts ivyservice DefaultLenientConfiguration ArtifactResolveEx
  • 如何使用RecyclerView.State保存RecyclerView滚动位置?

    我有一个关于 Android 的问题RecyclerView State http developer android com reference android support v7 widget RecyclerView State h
  • Android 可检查子菜单选项

    所以我有一个用于选项菜单项的子菜单 我想要一个可检查条目的列表 用户可以根据需要选择 取消选择多个条目 我无法解决的唯一问题是如何防止单击其中一个复选框时关闭选项菜单 我看到 PerformShortcut 有一个 FLAG PERFORM
  • 如何在android中的应用程序小部件中找到哪个按钮被点击?

    我想设计一个简单的应用程序小部件 它有两个文本视图和两个用于上一个 下一个的按钮 我很难处理应用程序小部件中的按钮单击 实际上我的愿望是 如果用户单击上一个按钮 我想显示以前的值 如果用户单击下一个按钮 我想显示数据库中的下一个值 如何知道
  • Android 连接有时会被拒绝(并非所有时候)

    我编写了一个 WiFi Direct 代码连接并在它们之间创建了一个连接 然后我创建了一个ServerSocket在第一面和一个Socket在客户端并开始在它们之间发送数据 第一次启动应用程序时它工作成功 但是当我关闭应用程序并再次启动它时
  • Android Youtube API 可用吗? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有适用于 Android 的 YouTube API 吗 如果不是 除了通过网络浏览器之外 如何从 Yo
  • 日志记录在 Android 设备上实际上有什么作用?

    我一直在 Android 示例中看到这样的代码 try catch Exception e Log e Error e getMessage 什么是Log e实际上在物理设备上做什么 它进入系统日志 开发人员可以通过 SDK 工具访问该日志
  • Android - 保持用户登录状态

    我正在尝试使用 PHP 和 MySQLi for Android 进行登录 我不明白的是如何保持用户登录状态 我看到一个简单的教程 其中有人使用 SQLite 来保护信息 但我不知道这是否真的安全 如何保存用户信息以保持用户登录状态 谢谢
  • Android应用程序中的模式输入

    我想知道是否有其他替代方案可以替代 Android 上平庸的 EditText 密码输入 是否有 API 或开源代码可以集成到我的应用程序中 类似于锁屏图案解锁 Intent 可能会返回哈希值 数字 字符串或代表用户输入的模式的任何内容 我
  • RecyclerView 适配器的 Kotlin 泛型

    我正在尝试编写一个通用的 recyclerview 适配器 我找到了几个例子 然而 仍然无法弄清楚如何实现通用适配器 我写的代码是 open abstract class BaseAdapter
  • 更改 Android 中突出显示文本的颜色

    我不确定这是否可能 也许有人可以纠正我 我在 Android 应用程序中有一个 EditText 视图 该视图在蓝色背景上有白色文本 当选择文本时 通过长按和编辑对话框 我希望突出显示为白色并将文本颜色更改为黑色 令人烦恼的是 似乎没有办法
  • 如何检测文本是否可读?

    我想知道是否有一种方法可以告诉给定的文本是人类可读的 我所说的人类可读的意思是 它有一些含义 格式就像某人写的文章 或者至少是由软件翻译器生成的供人类阅读的文章 这是背景故事 最近我正在制作一个应用程序 允许用户将短文本上传到数据库 在部署

随机推荐