安卓:如何缩放、平移(滚动)井字棋棋盘视图

3
所以,我有一个自定义的BoardView类扩展了View。我实现了绘制面板、线和在用户按下单元格时绘制“O”可绘制对象。
但是,我无法正确地实现以下问题:
1. 当用户进行捏合(多点触摸)时缩放BoardView。 2. 如果BoardView大于BoardView初始宽度或高度,则将其滚动到左侧、右侧、顶部或底部。 3. 在缩放或滚动后找到用户按下单元格时的正确单元格坐标。
这是我的第一个游戏项目,请帮忙解决这个问题。我已经尝试过但没有正常工作。BoardView的宽度等于屏幕宽度,BoardView的高度等于BoardView的宽度。它是正方形看板视图。
我会给予200奖金来实现这个问题。
这是我的项目,所有人都可以下载和编辑:https://drive.google.com/file/d/0BxNIUTd_m1x8cUQ2NGpSMDBuVVE/view?usp=sharing Github: https://github.com/boyfox/GameTicTacToe BoardView代码: http://pastie.org/10109253 或者 http://pastebin.com/TRU8Ybds 我自己找到了解决方案,但需要改进代码,你可以用你的解决方案回答我的问题!

首先:我在这里没有看到任何赏金。其次:我怀疑有人会为你编写代码,你应该尝试自己编写代码,并在此发布一个问题,其中包含你无法解决的问题清单。 - aga
我并没有让你给我写代码,但需要代码来解决问题。赏金功能将在两天后出现,届时我会发布赏金。感谢 @aga 的评论。 - SBotirov
我查看了你的Github项目,它立即崩溃了。在寻求其他帮助之前,我建议你先解决这个问题。 - Paul Burke
@PaulBurke 这不是崩溃,我使用了GestureDetectorCompat,请将support4库和v7-appcompact添加到项目中。 - SBotirov
2个回答

1

您能将您的代码移动到GitHub上吗?这样下载、编辑和提出修改意见就会更加容易。

如果您正在寻找双指缩放/旋转的通用实现,请查看我的游戏(https://github.com/ZieIony/Gravity)。最有趣的部分是GamePanel视图和dispatchTouchEvent方法:

private PointF prevPos = new PointF(), prevPos2 = new PointF();
float scale = 1;
final float MIN_SCALE = 0.2f, MAX_SCALE = 2.0f;
float rotation = 0;
Matrix matrix = new Matrix();
private float prevDist;

public boolean dispatchTouchEvent(android.view.MotionEvent event) {
        if (event.getPointerCount() == 2) {
            float d = dist(event.getX(0), event.getY(0), event.getX(1),
                    event.getY(1));
            float pivotX = (event.getX(0) + event.getX(1)) / 2;
            float pivotY = (event.getY(0) + event.getY(1)) / 2;
            float prevPivotX = (prevPos.x + prevPos2.x) / 2;
            float prevPivotY = (prevPos.y + prevPos2.y) / 2;
            if (event.getAction() == MotionEvent.ACTION_MOVE) {
                float newScale = scale * d / prevDist;
                newScale = Math.max(MIN_SCALE,
                        Math.min(newScale, MAX_SCALE));
                float scaleFactor = newScale / scale;
                scale = newScale;

                matrix.postScale(scaleFactor, scaleFactor, pivotX, pivotY);
                float prevAngle = (float) Math.atan2(
                        prevPos.x - prevPos2.x, prevPos.y - prevPos2.y);
                float angle = (float) Math.atan2(
                        event.getX(0) - event.getX(1), event.getY(0)
                                - event.getY(1));
                rotation += prevAngle - angle;
                matrix.postRotate(
                        (float) ((prevAngle - angle) * 180.0f / Math.PI),
                        pivotX, pivotY);

                matrix.postTranslate(-prevPivotX + pivotX, -prevPivotY
                        + pivotY);
            }
            prevPos.x = event.getX(0);
            prevPos.y = event.getY(0);
            prevPos2.x = event.getX(1);
            prevPos2.y = event.getY(1);
            prevDist = d;
        }
        return true;
}

这个方法会生成一个变换矩阵,你应该用它来进行绘制。
protected void dispatchDraw(Canvas canvas) {
    canvas.save();
    canvas.setMatrix(matrix);

    // do your drawing here

    canvas.restore();
}

我需要在用户进行单点触控时只滚动,如果用户进行多点触控则需要缩放。我编辑了我的问题,请有时间的话看一下。 - SBotirov
我添加了悬赏,您可以全面回答我的问题。 - SBotirov
这简直是疯了 - 为什么不使用GestureDetector呢? - Paul Burke
我不知道有ScaleGestureDetector。发现得好 :) - Zielony

1
请看我的答案这里。如果答案看起来令人满意,请查看我的github代码。我认为实现你的第三点不难,因为MyView.java中提供了scaleFactor,而滚动偏移量可以通过getScrollX()getScrollY()获得,只需要进行简单的数学计算即可找到正确的单元格坐标。

谢谢您的回答,但是我尝试运行您的项目时,在MyView.java和View类中都找不到initializeScrollbars(a)方法,为什么呢? - SBotirov
我已经对这个方法进行了注释并查看了你的项目,但是你的滚动实现非常好,但缩放逻辑不太好。我已经找到了解决方案,并希望改进我的代码或找到新的最佳解决方案。 - SBotirov
@mr.boyfox,也许我对我的缩放逻辑不太确定。无论如何,谢谢你的回复。 - Durgadass S
谢谢你,我也感谢你!如果我没有得到其他更好的解决方案,那么我将在本周接受你的答案。 - SBotirov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接