Android(Java)开发双ImageView找茬游戏如何判断用户触摸点是否为正确差异位置
找茬游戏触摸位置获取与校验方案
1. 获取ImageView上的实际触摸坐标
要注意不能直接用触摸点相对于屏幕/View的坐标,需要转换为图片本身的像素坐标,避免图片缩放、内边距、对齐方式导致的坐标偏移,实现代码如下:
// 给展示的ImageView设置触摸监听器 targetImageView.setOnTouchListener((v, event) -> { // 只处理抬起事件,避免滑动过程中多次触发 if (event.getAction() == MotionEvent.ACTION_UP) { float viewX = event.getX(); float viewY = event.getY(); Drawable showDrawable = targetImageView.getDrawable(); if (showDrawable == null) return true; // 计算图片在ImageView中的缩放比例 float scaleX = (float) showDrawable.getIntrinsicWidth() / targetImageView.getWidth(); float scaleY = (float) showDrawable.getIntrinsicHeight() / targetImageView.getHeight(); // 去除内边距影响,转换为图片实际像素坐标 float actualImgX = (viewX - targetImageView.getPaddingLeft()) * scaleX; float actualImgY = (viewY - targetImageView.getPaddingTop()) * scaleY; // 执行点位校验 checkIfCorrectPoint(actualImgX, actualImgY); return true; } // 触摸事件消费,避免和点击事件冲突 return true; });
2. 校验触摸点是否为正确差异点位
提供两种常用实现方案,可根据你的游戏场景选择:
2.1 预标记差异区域(推荐固定关卡使用)
- 提前为每个关卡的两张图片标记所有差异的范围,用RectF存储每个差异区域的左上角、右下角实际像素坐标,同时维护对应区域是否已被找到的状态列表
- 校验时直接判断触摸坐标是否落在任意未被找到的差异区域内即可,性能开销极低,无感知误差
实现代码示例:
// 预存当前关卡的所有差异区域、已找到状态 private List<RectF> diffAreaList = new ArrayList<>(); private List<Boolean> foundList = new ArrayList<>(); private void checkIfCorrectPoint(float x, float y) { for (int i = 0; i < diffAreaList.size(); i++) { if (!foundList.get(i) && diffAreaList.get(i).contains(x, y)) { // 找到正确差异点,标记为已找到,执行加分、显示标记逻辑 foundList.set(i, true); return; } } // 点击错误,执行扣生命值、错误提示逻辑 }
可以根据需求把RectF替换为自定义圆形区域类,判断坐标到中心的距离是否小于半径即可,容错率更高
2.2 实时像素比对(适合动态生成差异的场景)
如果你的游戏差异是动态生成无法提前标记,可以通过两张图片对应坐标的像素色差判断:
- 提前将两张比对图片转为相同分辨率的Bitmap对象
- 判断触摸坐标对应位置的两张图片像素色差,超过设定阈值则判定为差异点,建议额外判断坐标周围3*3范围的平均色差,避免单像素噪点导致误判
实现代码示例:
// 提前准备好两张分辨率相同的比对Bitmap private Bitmap imgBitmapA, imgBitmapB; // 色差阈值,可根据需求调整,数值越大判断越不敏感 private static final int COLOR_DIFF_THRESHOLD = 35; private boolean isDiffPoint(float x, float y) { // 坐标越界直接返回错误 if (x < 0 || x >= imgBitmapA.getWidth() || y < 0 || y >= imgBitmapA.getHeight()) { return false; } int pixelA = imgBitmapA.getPixel((int) x, (int) y); int pixelB = imgBitmapB.getPixel((int) x, (int) y); // 计算RGB三色差值的平均值 int rDiff = Math.abs(Color.red(pixelA) - Color.red(pixelB)); int gDiff = Math.abs(Color.green(pixelA) - Color.green(pixelB)); int bDiff = Math.abs(Color.blue(pixelA) - Color.blue(pixelB)); return (rDiff + gDiff + bDiff) / 3 > COLOR_DIFF_THRESHOLD; }
注意实时像素比对性能开销更高,高分辨率图片建议先压缩到合适尺寸再做比对
内容的提问来源于stack exchange,提问作者Harnis Testing
相关产品推荐
相关产品推荐

