/**
* This method allows spiral searchs for a color. Set withing a bounds and
* with a setable x,y. Thus searchs can begin in corners, center. top
* center, ect.
*
* @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 rgb
* The RGB to search for
* @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 startX
* The x to spiral out from
* @param startY
* The y to spiral out from
*
* @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
* @return the first match XY or null if no matches found
*/
public static final XY findXYspiral(short[][][] colorMap, RGB rgb,
Rectangle bounds, Rectangle ignore[], int startX, int startY,
int redTolerance, int greenTolerance, int blueTolerance) {
int redChange, greenChange, blueChange;
int dx = 0;
int dy = 0;
int tempRec = 0;
// Ignore Rectangles
boolean ignoreENULL = ignore != null;
int relX, relY;
relX = startX + dx;
relY = startY + dy;
boolean valid = true;
int r = rgb.r, g = rgb.g, b = rgb.b;
if (ignoreENULL) {
for (tempRec = 0; tempRec < ignore.length; tempRec++) {
if (ignore[tempRec].contains(relX, relY)) {
valid = false;
}
}
}
redChange = colorMap[relX][relY][0] - r;
if ((redChange >= 0 ? redChange : -redChange) > redTolerance) {
valid = false;
}
greenChange = colorMap[relX][relY][1] - g;
if ((greenChange >= 0 ? greenChange : -greenChange) > greenTolerance) {
valid = false;
}
blueChange = colorMap[relX][relY][2] - b;
if ((blueChange >= 0 ? blueChange : -blueChange) > blueTolerance) {
valid = false;
}
int size = 0;
int bX = bounds.x;
int bY = bounds.y;
int bW = bounds.width;
int bH = bounds.height;
int maxsize = 0;
if (maxsize < startX - bX) {
maxsize = startX - bX;
}
if (maxsize < bX + bW - startX) {
maxsize = bX + bW - startX;
}
if (maxsize < startY - bY) {
maxsize = startY - bY;
}
if (maxsize < bY + bH - startY) {
maxsize = bY + bH - startY;
}
while (size < maxsize && !valid) {
if (dy == size && dx < size && dx > 0)
dx++;
else if (dx == 0 && dy >= 0) {
dy++;
dx++;
size++;
} else if (dy == size && dx < 0)
dx++;
else if (dy == (-1 * size) && dx > (-1 * size))
dx--;
else if (dx == size)
dy--;
else if (dx == -1 * size)
dy++;
relX = startX + dx;
relY = startY + dy;
if (bX < relX && relX < bX + bW && bY < relY && relY < bY + bH) {
valid = true;
if (ignoreENULL) {
for (tempRec = 0; tempRec < ignore.length; tempRec++) {
if (ignore[tempRec].contains(relX, relY)) {
valid = false;
break;
}
}
if (!valid) {
continue;
}
}
redChange = colorMap[relX][relY][0] - r;
if ((redChange >= 0 ? redChange : -redChange) > redTolerance) {
valid = false;
continue;
}
greenChange = colorMap[relX][relY][1] - g;
if ((greenChange >= 0 ? greenChange : -greenChange) > greenTolerance) {
valid = false;
continue;
}
blueChange = colorMap[relX][relY][2] - b;
if ((blueChange >= 0 ? blueChange : -blueChange) > blueTolerance) {
valid = false;
continue;
}
}
}
if (valid) {
return new XY(relX, startY + dy);
}
return null;
}