MotionEvent坐标到场景坐标

时间:2012-04-27 12:48:13

标签: touch andengine multi-touch

我正在AndEngine中使用多点触控开发应用程序。为了获得触摸手指的坐标,我使用pSceneTouchEvent.getMotionEvent().getX([pointer index])因为TouchEvent没有等效的getter,只有pSceneTouchEvent.getX()

问题是当TouchEvent返回Scene上的坐标时,MotionEvent会在屏幕上返回坐标。当我放大或缩小时,屏幕和场景坐标不匹配,因此我需要将屏幕坐标转换为场景坐标。我怎么能这样做?

3 个答案:

答案 0 :(得分:1)

面对同样的问题,并有一个解决方案。首先,我想解释一下,然后粘贴转换方法。

问题

您希望拥有的坐标是场景坐标,它们与您的场景起点(0,0)相关(即AndEngine anchorCenter在左下角)。界限:从(0,0)到[Camera.getSurfaceWidth(),Camera.getSurfaceHeight()]。

你从MotionEvent得到的坐标是屏幕坐标,界限从(0,0)到[displayMetrix.widthPixels,displayMetrix.heightPixels],它们与变焦或相机无关。场景的位置。

解决方案说明

对于横坐标(通常为 x ),您必须将 screen corrdinates 转换为相关的场景坐标(有界)使用相机宽度)并将相机相加到相机左角位置(在场景中)。在公式中它看起来像:

x = cameraStartX + screenX * camera.width / display.width

cameraStartX - the camera left corner x position on the scene
screenX - x you get from MotionEvent
camera.width - just getWidth() from your camera method
display.width - display width from DisplayMetrics

对于纵坐标(通常 y ),您必须做与横坐标相同的操作,但请记住它有不同的方向。所以公式会有所改变:

y = cameraStartY+(display.heigth-screenY)*camera.height/display.heigth

cameraStartY - camera left corner y position on the scene
screenX - y you get from MotionEvent
camera.height - just getHeight() from your camera method
display.height - display height from DisplayMetrics

方法实施示例

public static void convertScreenToSurfaceCoordinates(
        final Camera camera,
        final Context context,
        final float[] screenCoordinates,
        final float[] surfaceCoordinates) {
    //you may want to have a separate methods and fields for display metrics
    //and no Context as a method param
    WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = windowManager.getDefaultDisplay();
    DisplayMetrics metrics = new DisplayMetrics();
    display.getMetrics(metrics);
    float displayWidth = Math.max(metrics.widthPixels, metrics.heightPixels);
    loat displayHeight = Math.min(metrics.widthPixels, metrics.heightPixels); 

    //abscissa
    surfaceCoordinates[Constants.VERTEX_INDEX_X] = camera.getXMin()
            + screenCoordinates[Constants.VERTEX_INDEX_X] * camera.getWidth()
            / displayWidth;
    //ordinate
    surfaceCoordinates[Constants.VERTEX_INDEX_Y] = camera.getYMin()
            + (displayHeight - screenCoordinates[Constants.VERTEX_INDEX_Y])
            * camera.getHeight() / displayHeight;
}

答案 1 :(得分:0)

找到解决方案。 Andengine以与Android不同的方式处理触摸事件,因此没有触摸坐标的历史记录。在处理事件之前,我只是将它们存储在私有变量中:

if (pSceneTouchEvent.getPointerID() == 0) {
    pointer0LastX = pSceneTouchEvent.getX();
    pointer0LastY = pSceneTouchEvent.getY();
}
if (pSceneTouchEvent.getPointerID() == 1) {
    pointer1LastX = pSceneTouchEvent.getX();
    pointer1LastY = pSceneTouchEvent.getY();
}

然后我只是访问这些而不是从TouchEvent获取值。

答案 2 :(得分:0)

您可以从TouchEvent访问原始MotionEvent。