Android Canvas ScaleFocus导致跳跃位置

时间:2016-02-05 03:56:38

标签: android android-canvas scale

我正在制作一款游戏,它将俯视一个移动的网格(类似于国际象棋)。我希望用户能够平移和缩放地图。我一直在转换矩阵,然后将这些更改连接到画布矩阵。虽然它主要起作用,但我有一个奇怪的错误:

在初始比例之后,如果我再次缩放比例,屏幕会跳(就像在其他地方滑动一样,然后立即移动到那里),然后平滑地缩放。我已将此行为缩小到缩放函数

的scaleFocus变量
canvas.scale(scaleFactor, scaleFactor, scaleFocusX, scaleFocusY);

如果我将scaleFocusX和scaleFocusY设置为0,则始终使用原点作为比例焦点,并且不会发生跳跃。但是,使用原点是不实际的,因为您滚动距离较远。以下是我的代码摘要。

public void onDraw(Canvas canvas) {
  ...
  canvas.translate(-mPosX, -mPosY);
  canvas.scale(scaleFactor, scaleFactor, scaleFocusX, scaleFocusY);

  //Create an inverse of the tranformation matrix, to be used when determining click location.
  canvas.getMatrix().invert(canvasMatrix);
  ... }


public class MyOnScaleGestureListener extends
        ScaleGestureDetector.SimpleOnScaleGestureListener {

    @Override
    public boolean onScale(ScaleGestureDetector detector) {

        scaleFactor *= detector.getScaleFactor();
        // Don't let the object get too small or too large.
        scaleFactor = Math.max(MIN_SCALE, Math.min(scaleFactor, MAX_SCALE));
        return true;
    }

    @Override
    public boolean onScaleBegin(ScaleGestureDetector detector) {
        Point scaleFocus = calculateClickAbsoluteLocation
                (detector.getFocusX(), detector.getFocusY());
        scaleFocusX = scaleFocus.x;
        scaleFocusY = scaleFocus.y;
        return true;
    }

    @Override
    public void onScaleEnd(ScaleGestureDetector detector) {

    }


//This method will take point on the phone screen, and convert it to be
//a point on the canvas (since the canvas area is larger than the screen).
public Point calculateClickAbsoluteLocation(float x, float y) {
    Point result = new Point();
    float[] coordinates = {x, y};

    //MapPoints will essentially convert the click coordinates from "screen pixels" into
    //"canvas pixels", so you can determine what tile was clicked.
    canvasMatrix.mapPoints(coordinates);

    result.set((int)coordinates[0], (int)coordinates[1]);
    return result;
}

1 个答案:

答案 0 :(得分:2)

首先,而不是使用 PointF coordinates = new PointF(x, y);您最好使用x,然后使用ycoordinates.x获取coordinates.yboolean scaling = false

您的问题是,缩放时仍然可以处理触摸事件(因此触摸处理两次)。

我们需要一个全局变量来告诉我们是否正在缩放: @Override public boolean onTouchEvent(@NonNull MotionEvent event) { detector.onTouchEvent(event); if (detector.isInProgress()) scaling = true;

因此,在OnTouchEvent中你应该检查它:

onTouchEvent

发布时间:     if(event.getAction()== MotionEvent.ACTION_UP){                 scaling = false;

if (!scaling) { ... } 中与点击有关的所有代码都应该用

包围
theme-function.php