decluttermatrix.java
来自「OpenMap是一个基于JavaBeansTM的开发工具包。利用OpenMap你」· Java 代码 · 共 1,032 行 · 第 1/3 页
JAVA
1,032 行
/** * Test to see if the object is on the matrix. Assumes that the matrix * is not null. * * @return true if object is on matrix. */ public boolean objOnMatrix(int objXIndex, int objYIndex, int objIndexLength, int objIndexHeight) { if (objXIndex + objIndexLength < 0 || // left off-matrix objYIndex + objIndexHeight < 0 || // below matrix // right off-matrix and above matrix objXIndex > maxx || objYIndex > maxy) { return false; } return true; } } /** * Set whether names can appear partially on/off the map. True means they * can, i.e., the spaces off the map are by default, clear. */ public void setAllowPartials(boolean value) { allowPartials = value; } /** * Find out whether the spaces off the map are counted as clear and * available. If they are, then objects can appear partially on the map. */ public boolean isAllowPartials() { return allowPartials; } /** ******************************************************************* */ /** * Construct a new DeclutterMatrix, given the screen dimensions and the size * of the matrix cells */ public DeclutterMatrix(int width, int height, int x_pix_interval, int y_pix_interval) { this.width = width; this.height = height; if (x_pix_interval != 0) { this.x_pix_interval = x_pix_interval; } else { x_pix_interval = 1; } if (y_pix_interval != 0) { this.y_pix_interval = y_pix_interval; } else { y_pix_interval = 1; } this.matrix = null; this.maxx = (this.width / this.x_pix_interval) - 1; this.maxy = (this.height / this.y_pix_interval) - 1; create(); Debug.message("declutter", "Decluttering matrix created." + " Width = " + width + " Height = " + height); } /** * Construct a new matrix, given the screen dimensions, and using the * default matrix cell size */ public DeclutterMatrix(int width, int height) { this(width, height, 1, 1); } /** Create a new matrix, with null dimensions */ public DeclutterMatrix() { this(0, 0); } /* * Any of these delete the current matrix if it exists and resets the * variable. create() needs to be called to recreate a new matrix after all * the changes. */ public void setXInterval(int x_pix_interval) { if (x_pix_interval != 0) { this.x_pix_interval = x_pix_interval; } else { this.x_pix_interval = 1; // To avoid DBZ error? } this.maxx = (this.width / this.x_pix_interval) - 1; needToRecreate = true; Debug.message("declutter", "Decluttering matrix: x_pix_interval changed to " + x_pix_interval); } public void setYInterval(int y_pix_interval) { if (y_pix_interval != 0) { this.y_pix_interval = y_pix_interval; } else { this.y_pix_interval = 1; } this.maxy = (this.height / this.y_pix_interval) - 1; needToRecreate = true; Debug.message("declutter", "Decluttering matrix: y_pix_interval changed to " + y_pix_interval); } public void setWidth(int width) { this.width = width; this.maxx = (this.width / this.x_pix_interval) - 1; needToRecreate = true; Debug.message("declutter", "Decluttering matrix: Width reset to " + width); } public void setHeight(int height) { this.height = height; this.maxy = (this.height / this.y_pix_interval) - 1; needToRecreate = true; Debug.message("declutter", "Decluttering matrix: height reset to " + height); } /** * Allocate the matrix. * * @return true if successful, and if the height and width settings were * valid (>0). */ public boolean create() { if ((height > 0) && (width > 0)) { matrix = new boolean[maxx + 1][maxy + 1]; needToRecreate = false; return true; } needToRecreate = true; return false; } /** * Query whether the matrix is clear, given a set of indexes. * * @param indexes the set of indexes * @param markAsTaken mark the spaces as used if they are previously clear. * @return true if they were clear previously. */ protected boolean isClear(MatrixIndexes indexes, boolean markAsTaken) { Debug.message("declutterdetail", "DeclutterMatrix: Checking space for clear."); if (this.matrix == null) { return false; } if (!indexes.withinMatrix) { // But, withinMatrix doesn't tell you if there is a // partial. It only tells you if any part of the object // is over the matrix. So, if it's not within the Matrix, // the answer should be yes, all the time, because you // don't have to declutter what you can't see... // return allowPartials; return true; } if (!allowPartials && indexes.partial) { return false; } // OK - the above check should verify that some part of the // object is on the matrix - so there is a reason to set the // limits for the matrix search below, and not worry about // dealing with funky index values. boolean notClear = false; // Since we have the matrix index limits, have two loops, the // first to check for the open cells, the other to mark the // cells as occupied. The second loop only gets run if the // markAsTaken flag is set by the caller. for (int taken = 0; taken < 2; taken++) { // Check to see if the horizontal indexes are on the // matrix - i should be at least greater than zero here, // as should j. for (int i = indexes.xStart; i <= indexes.xEnd; i++) { // Check for loop - the first loop is to see if // the spaces are open. if (taken == 0) { notClear = isMatrixLocationTaken(i, indexes.yStart, indexes.yEnd - indexes.yStart + 1); if (notClear) { return false; } } else { // The second loop is to mark the cells as // taken setTaken(i, indexes.yStart, indexes.yEnd - indexes.yStart + 1); } } // This will prevent the second loop from occuring if it's // not supposed to - the caller just wanted to check the // spaces, rather than check and mark. if (!markAsTaken) { return true; } } return true; } /** * Check a vertical portion of the matrix, to see if it has already been * taken. If a query occurs that is outside the matrix, this returns false. * * @param horizontalIndex the horizontal index of the matrix to check. * @param verticalIndex the vertical starting index of the matrix to check. * @param numCellsToCheck the number of matrix cells to check for taken. * @return true if taken, false if available. */ protected boolean isMatrixLocationTaken(int horizontalIndex, int verticalIndex, int numCellsToCheck) { try { for (int i = numCellsToCheck - 1; i >= 0; i--) { if (matrix[horizontalIndex][verticalIndex + i]) { return true; } } } catch (ArrayIndexOutOfBoundsException aioobe) { return allowPartials; } return false; } /** * Mark a vertical portion of the matrix as taken. * * @param horizontalIndex the horizontal index of the matrix to mark. * @param verticalIndex the vertical starting index of the matrix to mark. * @param numCellsToMark the number of matrix cells to mark as taken. */ protected void setTaken(int horizontalIndex, int verticalIndex, int numCellsToMark) { try { for (int i = numCellsToMark - 1; i >= 0; i--) { matrix[horizontalIndex][verticalIndex + i] = true; } } catch (ArrayIndexOutOfBoundsException aioobe) { } } /** * SetTaken returns true if the space was clear before the it was taken, * false if it was not. Either way, the spaces are marked. Except if the * matrix is not built, in which case false is returned anyway. * * @param indexes the start and end matrix indexes for an object. * @return true if successful. */ protected boolean setTaken(MatrixIndexes indexes) { if (this.matrix == null) { return false; } if (!indexes.withinMatrix) { return allowPartials; } for (int i = indexes.xStart; i < indexes.xEnd; i++) { setTaken(i, indexes.yStart, indexes.yEnd - indexes.yStart + 1); } return true; } /** * Set an area as taken, given a point and a length of pixels. The length is * checked from left to right. */ public boolean setTaken(Point point, int pixelLength) { return setTaken(point, pixelLength, y_pix_interval); } /** * Set an area as taken, given a point, a length of pixels and a height of * pixels. The length is from left to right, the height from the bottom to * top (NOT like screen coordinates) */ public boolean setTaken(Point point, int pixelLength, int pixelHeight) { if (needToRecreate) create(); indexes.setFromPixels(point.x, point.y, pixelLength, pixelHeight); return setTaken(indexes); } /** * The method to call if you are trying to set something in an open place, * anywhere on the map. * * @param point the window point * @param pixelLength the pixel length of space from left to right. * @param pixelHeight the pixel height from bottom to top. * @return Point of closest open space. */ public Point setNextOpen(Point point, int pixelLength, int pixelHeight) { return setNextOpen(point, pixelLength, pixelHeight, -1); } /** * The method to call if you are trying to set something in an open place, * but want to limit how far away the object could be placed. * * @param point the window point * @param pixelLength the pixel length of space from left to right. * @param pixelHeight the pixel height from bottom to top. * @param pixelAwayLimit the pixel distance away from the original location * that where an object will be discarded if it's not at least that * close. -1 means find anywhere on the map where the object will * fit. * @return Point of closest open space. */ public Point setNextOpen(Point point, int pixelLength, int pixelHeight, int pixelAwayLimit) { Debug.message("declutterdetail", "DeclutterMatrix: Trying to find an open space."); if (needToRecreate) create(); boolean set = false; // mark the original spot. These are indexes, not pixels. int windex = point.x / x_pix_interval;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?