【问题标题】:Android Canvas ScaleFocus causing jumping positionAndroid Canvas ScaleFocus 导致跳跃位置
【发布时间】:2016-02-05 03:56:37
【问题描述】:

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

在初始缩放之后,如果我再次捏缩放,屏幕跳跃(就像在其他地方滑动并立即移动到那里一样)然后平滑缩放。我已将此行为范围缩小到 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;
}

【问题讨论】:

    标签: android android-canvas scale


    【解决方案1】:

    首先,而不是使用 float[] coordinates = {x, y};你最好使用PointF coordinates = new PointF(x, y);,然后你可以得到xycoordinates.xcoordinates.y

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

    我们需要一个全局变量来告诉我们是否正在缩放: boolean scaling = false

    所以,在 OnTouchEvent 中你应该检查它:

    @Override
        public boolean onTouchEvent(@NonNull MotionEvent event) { 
            detector.onTouchEvent(event);
            if (detector.isInProgress()) 
                scaling = true;
    

    发布: if (event.getAction() == MotionEvent.ACTION_UP) { 缩放=假;

    onTouchEvent 中所有与点击一起使用的代码都应该用

    包围
    if (!scaling) { ... }
    

    【讨论】:

    • “你的问题是,缩放时你仍然处理触摸事件(所以触摸被处理了两次)。”只是在同样的问题上帮助了我很多。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-24
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多