点游戏失败,无法正确识别和绘制图像周围的点
Dot game failed , cannot identify and draw dots around image correctly
我想要实现的是在与图像中已经存在的黑点完全相同的位置绘制点,但是我必须面对关于图像的问题:
- 图像可以在多个屏幕上更改其密度(因此没有固定大小)
- 给定的图像可以是任意大小,我必须将其转换为适当的大小才能在自定义视图上显示。
- 以及如何在自定义视图中显示图像以使其密度保持不变?
现在关于点画的问题:
- 我如何动态识别黑点 x,y 轴以绘制在自定义视图图像中绘制的完全相同的黑点上。
- 是否有动态实现问题 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"/>
我通过 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;
在我记下所有绘制的点之后,我将 class 返回相同的绘制点,方法是调用:
public void setPoints(List<Point> points) {
this.mPoints = points;
}
现在最大的问题[我认为仍然存在],屏幕 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;
}
我想要实现的是在与图像中已经存在的黑点完全相同的位置绘制点,但是我必须面对关于图像的问题:
- 图像可以在多个屏幕上更改其密度(因此没有固定大小)
- 给定的图像可以是任意大小,我必须将其转换为适当的大小才能在自定义视图上显示。
- 以及如何在自定义视图中显示图像以使其密度保持不变?
现在关于点画的问题:
- 我如何动态识别黑点 x,y 轴以绘制在自定义视图图像中绘制的完全相同的黑点上。
- 是否有动态实现问题 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"/>
我通过 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;
在我记下所有绘制的点之后,我将 class 返回相同的绘制点,方法是调用:
public void setPoints(List<Point> points) { this.mPoints = points; }
现在最大的问题[我认为仍然存在],屏幕 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;
}