/** * * This method returns all the Valid XY's from a color Array That are within * the tolerances of the RGB. "deformed" accuracy 1.0 == 100% have to match * (Exact) accuracy 0.1 == 10% have to match * * @author Eric * @param colorMap * the colors of the game screen sorted as short's in an array * [x][y][0-2] where 0 is red, 1 is blue, 2 is green * @param maxMatches * The maximum number of matches to find. * @param colorMapToFind * the colors a image sorted as short's in an array [x][y][0-2] * where 0 is red, 1 is blue, 2 is green * @param bounds * The Rectange to search, specifies which part of the * colorArray2d to search * @param ignore * The Rectangles to ignore in the search, specifies which parts * of the bounds to ignore, example searching game screen but * ignoring your character * @param accuracy * range should be between 0.0-1.0 * @param redTolerance * The maximum difference for the red color value * @param greenTolerance * The maximum difference for the green color value * @param blueTolerance * The maximum difference for the blue color value * @param bitmaskOverRide * The Color that all the bitmasks in the image should be matched * against. * * @return An array of XY matches or null if none found */ public static final XY[] findXYs(short[][][] colorMap, int maxMatches, short[][][] colorMapToFind, Rectangle bounds, Rectangle ignore[], double accuracy, int redTolerance, int greenTolerance, int blueTolerance, RGB bitmaskOverRide) { // temp varibles int x, y, ix, iy, redChange, greenChange, blueChange; // image int iW = colorMapToFind.length; int iL = colorMapToFind[0].length; // deformed bitmap double temp = (1 - accuracy) * (iW * iL); int maxWrong = (int) temp; int wrong; // search zone int minX = bounds.x; int maxX = minX + bounds.width - iW + 1; int minY = bounds.y; int maxY = minY + bounds.height - iL + 1; // results ArrayList list = null; if (maxMatches < 10) { list = new ArrayList(10); } else { list = new ArrayList(maxMatches); } // masks, bitmask definition ; int BITMASK_MATCH = BitMapInfo.BITMASK_MATCH; int BITMASK_NOMATCH = BitMapInfo.BITMASK_NOMATCH; boolean bitmaskOverRideENULL = bitmaskOverRide == null; int bitMaskR = 0, bitMaskG = 0, bitMaskB = 0; int firstBitMaskXOffSet = -1, firstBitMaskYOffSet = -1; if (bitmaskOverRideENULL) { boolean found = false; for (x = 0; !found && x < iW; x++) for (y = 0; !found && y < iL; y++) if (colorMapToFind[x][y][0] == BITMASK_MATCH) { firstBitMaskXOffSet = x; firstBitMaskYOffSet = y; found = true; } } else { bitMaskR = bitmaskOverRide.r; bitMaskG = bitmaskOverRide.g; bitMaskB = bitmaskOverRide.b; } // Ignore Rectangles boolean ignoreENULL = ignore != null; boolean ignoreSpot; boolean valid = false; boolean firstMask = false; int relX, relY; for (x = minX; x < maxX; x++) { for (y = minY; y < maxY; y++) { wrong = 0; valid = true; if (bitmaskOverRideENULL) firstMask = true; for (ix = 0; valid && ix < iW; ix++) { for (iy = 0; iy < iL; iy++) { if (wrong > maxWrong) { valid = false; break; } relX = x + ix; relY = y + iy; if (ignoreENULL) { ignoreSpot = false; for (int i = 0; i < ignore.length; i++) { if (ignore[i].contains(relX, relY)) { ignoreSpot = true; break; } } if (ignoreSpot) { valid = false; break; } } if (colorMapToFind[ix][iy][0] < 0) { if (firstMask) { if (firstBitMaskXOffSet != -1 && firstBitMaskYOffSet != -1) { bitMaskR = colorMap[relX + firstBitMaskXOffSet][relY + firstBitMaskYOffSet][0]; bitMaskG = colorMap[relX + firstBitMaskXOffSet][relY + firstBitMaskYOffSet][1]; bitMaskB = colorMap[relX + firstBitMaskXOffSet][relY + firstBitMaskYOffSet][2]; firstMask = false; } } if (colorMapToFind[ix][iy][0] == BITMASK_MATCH) { redChange = bitMaskR - colorMap[relX][relY][0]; if ((redChange >= 0 ? redChange : -redChange) > redTolerance) { wrong++; continue; } greenChange = bitMaskG - colorMap[relX][relY][1]; if ((greenChange >= 0 ? greenChange : -greenChange) > greenTolerance) { wrong++; continue; } blueChange = bitMaskB - colorMap[relX][relY][2]; if ((blueChange >= 0 ? blueChange : -blueChange) > blueTolerance) { wrong++; continue; } } else if (colorMapToFind[ix][iy][0] == BITMASK_NOMATCH && !firstMask) { redChange = bitMaskR - colorMap[relX][relY][0]; greenChange = bitMaskG - colorMap[relX][relY][1]; blueChange = bitMaskB - colorMap[relX][relY][2]; if ((greenChange >= 0 ? greenChange : -greenChange) < greenTolerance && (redChange >= 0 ? redChange : -redChange) < redTolerance && (blueChange >= 0 ? blueChange : -blueChange) < blueTolerance) { wrong++; continue; } } continue; } redChange = colorMapToFind[ix][iy][0] - colorMap[relX][relY][0]; if ((redChange >= 0 ? redChange : -redChange) > redTolerance) { wrong++; continue; } greenChange = colorMapToFind[ix][iy][1] - colorMap[relX][relY][1]; if ((greenChange >= 0 ? greenChange : -greenChange) > greenTolerance) { wrong++; continue; } blueChange = colorMapToFind[ix][iy][2] - colorMap[relX][relY][2]; if ((blueChange >= 0 ? blueChange : -blueChange) > blueTolerance) { wrong++; continue; } } } if (valid) { list.add(new XY(x, y)); if (list.size() >= maxMatches) { XY resultXY[] = new XY[list.size()]; for (int i = 0; i < resultXY.length; i++) { resultXY[i] = list.get(i); } return resultXY; } } } } XY resultXY[] = new XY[list.size()]; for (int i = 0; i < resultXY.length; i++) { resultXY[i] = list.get(i); } list = null; return resultXY; }