点游戏失败,无法正确识别和绘制图像周围的点

Dot game failed , cannot identify and draw dots around image correctly

我想要实现的是在与图像中已经存在的黑点完全相同的位置绘制点,但是我必须面对关于图像的问题:

  1. 图像可以在多个屏幕上更改其密度(因此没有固定大小)
  2. 给定的图像可以是任意大小,我必须将其转换为适当的大小才能在自定义视图上显示。
  3. 以及如何在自定义视图中显示图像以使其密度保持不变?

现在关于点画的问题:

  1. 我如何动态识别黑点 x,y 轴以绘制在自定义视图图像中绘制的完全相同的黑点上。
  2. 是否有动态实现问题 1 的好方法,或者我应该对点进行硬编码。

到目前为止我做了什么:

  1. 我已将所有图像移动到 drawable 文件夹并完成 layout_width = wrap_content 并且高度与宽度相同。

    <com.jutt.dotbot.ConnectDotsView
    android:id="@+id/gfxImage"
    android:layout_width="500dpi"
    android:layout_height="600dpi"
    android:layout_marginTop="100dip"
    android:layout_centerHorizontal="true"/>
    
  2. 我通过 Toast 在 onTouchEvent 中的每个 ACTION_DOWN 上查看了硬编码点,然后记录下来并提供给 class ConnectDotsView.

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        touch_start(x, y);
        invalidate();
        L.s(getContext(), "x = "+x+"y = "+y);
        break;
    
  3. 在我记下所有绘制的点之后,我将 class 返回相同的绘制点,方法是调用:

    public void setPoints(List<Point> points) {
        this.mPoints = points;
    }
    
  4. 现在最大的问题[我认为仍然存在],屏幕 1152w*720h 上的 (x,y) 在 480w*600h 上可能不一样,所以我所做的是一个函数实际转换这些点数。

    private static final int OLDSCREENX = 1152;
    private static final int OLDSCREENY = 720;
    
    private int[] makeDimentionGeneric(float oldScreenX, float oldScreenY,
            float oldX, float oldY) {
        // get screen size
        DisplayMetrics displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        final float y = displaymetrics.heightPixels;
        final float x = displaymetrics.widthPixels;
        int[] i = new int[] { (int) ((oldX / oldScreenX) * x),
                (int) ((oldY / oldScreenY) * y) };
        return i;
    }
    

我在设置 makeDimentionGeneric(OLDSCREENX, OLDSCREENY, p.x, p.y); 之类的点时调用它,而 p.x and p.y 是来自屏幕的硬编码存储值。

现在当我尝试在不同的设备上 运行 时会发生什么。

我什么时候做错了,我怎样才能正确地实现它?伙计们,我努力学习但似乎找不到比我提到的更好的方法。

[更新] 根据要求(2015 年 7 月 21 日):

private int[] makeDimentionGeneric(float oldScreenX, float oldScreenY,
        float oldX, float oldY) {
    // convert all px to dp
    oldScreenY = convertPixelsToDp(oldScreenY, this);
    oldScreenX = convertPixelsToDp(oldScreenX,this);
    oldX = convertPixelsToDp(oldX,this);
    oldY = convertPixelsToDp(oldY,this);

    // get screen size
    DisplayMetrics displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    final float y = convertPixelsToDp(displaymetrics.heightPixels, this);
    final float x = convertPixelsToDp(displaymetrics.widthPixels, this);

    int[] i = new int[] { (int)((oldX / oldScreenX) * x),
            (int) ((oldY / oldScreenY) * y) };

    return i;

}

由于您的图像因 DPI 而异,您的像素计算也必须因 DPI 而异。考虑以下问题:

Converting pixels to dp

在你的情况下(从上面问题的答案复制)你可能想使用这个方法:

/**
 * This method converts device specific pixels to density independent pixels.
 *
 * @param px A value in px (pixels) unit. Which we need to convert into db
 * @param context Context to get resources and device specific display metrics
 * @return A float value to represent dp equivalent to px value
 */
public static float convertPixelsToDp(float px, Context context){
    Resources resources = context.getResources();
    DisplayMetrics metrics = resources.getDisplayMetrics();
    float dp = px / (metrics.densityDpi / 160f);
    return dp;
}