代码之家  ›  专栏  ›  技术社区  ›  Jake Marzen

Android Canvas ScaleFocus导致跳跃位置

  •  0
  • Jake Marzen  · 技术社区  · 10 年前

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

    初始缩放后,如果我再次缩小缩放,屏幕 跳跃 (这就像是在别的地方滑动,它立刻移动到那里),然后平滑地缩放。我已经将这种行为缩小到scale函数的scaleFocus变量

    canvas.scale(scaleFactor, scaleFactor, scaleFocusX, scaleFocusY);
    

    如果我将scaleFocusX和scaleFoFocusY设置为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 回复  |  直到 10 年前
        1
  •  2
  •   Timur    10 年前

    首先,不要使用 float[] coordinates = {x, y}; 你最好用 PointF coordinates = new PointF(x, y); ,然后你可以得到 x y 具有 coordinates.x coordinates.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) { ... }
    
    推荐文章