📄 sprite.java
字号:
if (!intersectRect(tLx1, tLy1, tLx2, tLy2, sx1, sy1, sx2, sy2)) { return (false); } // we have an intersection between the Sprite and // one or more cells of the tiledlayer // note sx1 < sx2, tLx1 < tLx2, sx2 > tLx1 from intersectRect() // use <= for comparison as this saves us some // computation - the result will be 0 startCol = (sx1 <= tLx1) ? 0 : (sx1 - tLx1)/tW; startRow = (sy1 <= tLy1) ? 0 : (sy1 - tLy1)/tH; // since tLx1 < sx2 < tLx2, the computation will yield // a result between 0 and tNumCols - 1 // subtract by 1 because sx2,sy2 represent // the enclosing bounds of the sprite, not the // locations in the coordinate system. endCol = (sx2 < tLx2) ? ((sx2 - 1 - tLx1)/tW) : tNumCols - 1; endRow = (sy2 < tLy2) ? ((sy2 - 1 - tLy1)/tH) : tNumRows - 1; // current cell coordinates int cellTop = startRow * tH + tLy1; int cellBottom = cellTop + tH; // the index of the current tile. int tileIndex; // = 0; for (int row = startRow; row <= endRow; row++, cellTop += tH, cellBottom += tH) { // current cell coordinates int cellLeft = startCol * tW + tLx1; int cellRight = cellLeft + tW; for (int col = startCol; col <= endCol; col++, cellLeft += tW, cellRight += tW) { tileIndex = t.getCell(col, row); if (tileIndex != 0) { // current cell/sprite intersection coordinates // in painter coordinate system. // find intersecting region, int intersectLeft = (sx1 < cellLeft) ? cellLeft : sx1; int intersectTop = (sy1 < cellTop) ? cellTop : sy1; // used once, optimize. int intersectRight = (sx2 < cellRight) ? sx2 : cellRight; int intersectBottom = (sy2 < cellBottom) ? sy2 : cellBottom; if (intersectLeft > intersectRight) { int temp = intersectRight; intersectRight = intersectLeft; intersectLeft = temp; } if (intersectTop > intersectBottom) { int temp = intersectBottom; intersectBottom = intersectTop; intersectTop = temp; } int intersectWidth = intersectRight - intersectLeft; int intersectHeight = intersectBottom - intersectTop; int image1XOffset = getImageTopLeftX(intersectLeft, intersectTop, intersectRight, intersectBottom); int image1YOffset = getImageTopLeftY(intersectLeft, intersectTop, intersectRight, intersectBottom); int image2XOffset = t.tileSetX[tileIndex] + (intersectLeft - cellLeft); int image2YOffset = t.tileSetY[tileIndex] + (intersectTop - cellTop); if (doPixelCollision(image1XOffset, image1YOffset, image2XOffset, image2YOffset, this.sourceImage, this.t_currentTransformation, t.sourceImage, TRANS_NONE, intersectWidth, intersectHeight)) { // intersection found with this tile return true; } } } // end of for col }// end of for row // worst case! we scanned through entire // overlapping region and // no pixels collide! return false; } } /** * Checks for a collision between this Sprite and the specified Image * with its upper left corner at the specified location. If pixel-level * detection is used, a collision is detected only if opaque pixels * collide. That is, an opaque pixel in the Sprite would have to collide * with an opaque pixel in Image for a collision to be detected. Only * those pixels within the Sprite's collision rectangle are checked. * <P> * If pixel-level detection is not used, this method simply checks if the * Sprite's collision rectangle intersects with the Image's bounds. * <P> * Any transform applied to the Sprite is automatically accounted for. * <P> * The Sprite must be visible in order for a collision to be * detected. * <P> * @param image the <code>Image</code> to test for collision * @param x the horizontal location of the <code>Image</code>'s * upper left corner * @param y the vertical location of the <code>Image</code>'s * upper left corner * @param pixelLevel <code>true</code> to test for collision on a * pixel-by-pixel basis, <code>false</code> to test using simple * bounds checking * @return <code>true</code> if this <code>Sprite</code> has * collided with the <code>Image</code>, otherwise * <code>false</code> * @throws NullPointerException if <code>image</code> is * <code>null</code> */ public final boolean collidesWith(Image image, int x, int y, boolean pixelLevel) { // check if this Sprite is not visible if (!(this.visible)) { return false; } // if image is null // image.getWidth() will throw NullPointerException int otherLeft = x; int otherTop = y; int otherRight = x + image.getWidth(); int otherBottom = y + image.getHeight(); int left = this.x + this.t_collisionRectX; int top = this.y + this.t_collisionRectY; int right = left + this.t_collisionRectWidth; int bottom = top + this.t_collisionRectHeight; // first check if the collision rectangles of the two sprites intersect if (intersectRect(otherLeft, otherTop, otherRight, otherBottom, left, top, right, bottom)) { // collision rectangles intersect if (pixelLevel) { // find intersecting region, // we need to check pixel level collision detection. // use only the coordinates within the Sprite frame if // the collision rectangle is larger than the Sprite // frame if (this.t_collisionRectX < 0) { left = this.x; } if (this.t_collisionRectY < 0) { top = this.y; } if ((this.t_collisionRectX + this.t_collisionRectWidth) > this.width) { right = this.x + this.width; } if ((this.t_collisionRectY + this.t_collisionRectHeight) > this.height) { bottom = this.y + this.height; } // recheck if the updated collision area rectangles intersect if (!intersectRect(otherLeft, otherTop, otherRight, otherBottom, left, top, right, bottom)) { // if they don't intersect, return false; return false; } // within the collision rectangles int intersectLeft = (left < otherLeft) ? otherLeft : left; int intersectTop = (top < otherTop) ? otherTop : top; // used once, optimize. int intersectRight = (right < otherRight) ? right : otherRight; int intersectBottom = (bottom < otherBottom) ? bottom : otherBottom; int intersectWidth = Math.abs(intersectRight - intersectLeft); int intersectHeight = Math.abs(intersectBottom - intersectTop); // have the coordinates in painter space, // need coordinates of top left and width, height // in source image of Sprite. int thisImageXOffset = getImageTopLeftX(intersectLeft, intersectTop, intersectRight, intersectBottom); int thisImageYOffset = getImageTopLeftY(intersectLeft, intersectTop, intersectRight, intersectBottom); int otherImageXOffset = intersectLeft - x; int otherImageYOffset = intersectTop - y; // check if opaque pixels intersect. return doPixelCollision(thisImageXOffset, thisImageYOffset, otherImageXOffset, otherImageYOffset, this.sourceImage, this.t_currentTransformation, image, Sprite.TRANS_NONE, intersectWidth, intersectHeight); } else { // collides! return true; } } return false; } // ----- // ----- private ----- /** * create the Image Array. * * @param image Image to use for Sprite * @param fWidth width, in pixels, of the individual raw frames * @param fHeight height, in pixels, of the individual raw frames * @param maintainCurFrame true if Current Frame is maintained */ private void initializeFrames(Image image, int fWidth, int fHeight, boolean maintainCurFrame) { int imageW = image.getWidth(); int imageH = image.getHeight(); int numHorizontalFrames = imageW / fWidth; int numVerticalFrames = imageH / fHeight; sourceImage = image; srcFrameWidth = fWidth; srcFrameHeight = fHeight; numberFrames = numHorizontalFrames*numVerticalFrames; frameCoordsX = new int[numberFrames]; frameCoordsY = new int[numberFrames]; if (!maintainCurFrame) { sequenceIndex = 0; } if (!customSequenceDefined) { frameSequence = new int[numberFrames]; } int currentFrame = 0; for (int yy = 0; yy < imageH; yy += fHeight) { for (int xx = 0; xx < imageW; xx += fWidth) { frameCoordsX[currentFrame] = xx; frameCoordsY[currentFrame] = yy; if (!customSequenceDefined) { frameSequence[currentFrame] = currentFrame; } currentFrame++; } } } /** * initialize the collision rectangle */ private void initCollisionRectBounds() { // reset x and y of collision rectangle collisionRectX = 0; collisionRectY = 0; // intialize the collision rectangle bounds to that of the sprite collisionRectWidth = this.width; collisionRectHeight = this.height; } /** * Detect rectangle intersection * * @param r1x1 left co-ordinate of first rectangle * @param r1y1 top co-ordinate of first rectangle * @param r1x2 right co-ordinate of first rectangle * @param r1y2 bottom co-ordinate of first rectangle * @param r2x1 left co-ordinate of second rectangle * @param r2y1 top co-ordinate of second rectangle * @param r2x2 right co-ordinate of second rectangle * @param r2y2 bottom co-ordinate of second rectangle * @return True if there is rectangle intersection */ private boolean intersectRect(int r1x1, int r1y1, int r1x2, int r1y2, int r2x1, int r2y1, int r2x2, int r2y2) { if (r2x1 >= r1x2 || r2y1 >= r1y2 || r2x2 <= r1x1 || r2y2 <= r1y1) { return false; } else { return true; } } /** * Detect opaque pixel intersection between regions of two images * * @param image1XOffset left coordinate in the first image * @param image1YOffset top coordinate in the first image * @param image2XOffset left coordinate in the second image * @param image2YOffset top coordinate in the second image * @param image1 first source image * @param transform1 The transform for the first image * @param image2 second source image * @param transform2 transform set on the second image * @param width width of overlapping region, when transformed * @param height height of overlapping region, when transformed * * Clarification required on parameters: * XOffset and YOffset are the offsets from the top left * hand corner of the image. * width, height is the dimensions of the intersecting regions * in the two transformed images. * there fore appropriate conversions have to be made on these * dimensions when using the values, according to the transformation * that has been set. * * @return True if there is a pixel level collision */ private static boolean doPixelCollision(int image1XOffset, int image1YOffset, int image2XOffset, int image2YOffset, Image image1, int transform1, Image image2, int transform2, int width, int height) { // starting point of comparison int startY1; // x and y increments
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -