📄 sprite.java
字号:
throw new IllegalArgumentException();
}
for (int i = 0; i < sequence.length; ++i) {
if (sequence[i] < 0 || sequence[i] >= numberFrames) {
throw new ArrayIndexOutOfBoundsException();
}
}
customSequenceDefined = true;
frameSequence = new int[sequence.length];
System.arraycopy(sequence, 0, frameSequence, 0, sequence.length);
sequenceIndex = 0;
}
public void setImage(Image img, int frameWidth, int frameHeight) {
// if image is null image.getWidth() will throw NullPointerException
if ((frameWidth < 1 || frameHeight < 1)
|| ((img.getWidth() % frameWidth) != 0)
|| ((img.getHeight() % frameHeight) != 0)) {
throw new IllegalArgumentException();
}
int noOfFrames = (img.getWidth() / frameWidth)
* (img.getHeight() / frameHeight);
boolean maintainCurFrame = true;
if (noOfFrames < numberFrames) {
// use default frame , sequence index = 0
maintainCurFrame = false;
customSequenceDefined = false;
}
if (!((srcFrameWidth == frameWidth) && (srcFrameHeight == frameHeight))) {
// computing is the location
// of the reference pixel in the painter's coordinate system.
// and then use this to find x and y position of the Sprite
int oldX = this.x
+ getTransformedPtX(dRefX, dRefY,
this.t_currentTransformation);
int oldY = this.y
+ getTransformedPtY(dRefX, dRefY,
this.t_currentTransformation);
setWidthImpl(frameWidth);
setHeightImpl(frameHeight);
initializeFrames(img, frameWidth, frameHeight, maintainCurFrame);
// initialize collision rectangle
initCollisionRectBounds();
// set the new x and y position of the Sprite
this.x = oldX
- getTransformedPtX(dRefX, dRefY,
this.t_currentTransformation);
this.y = oldY
- getTransformedPtY(dRefX, dRefY,
this.t_currentTransformation);
// Calculate transformed sprites collision rectangle
// and transformed width and height
computeTransformedBounds(this.t_currentTransformation);
} else {
// just reinitialize the animation frames.
initializeFrames(img, frameWidth, frameHeight, maintainCurFrame);
}
}
public void defineCollisionRectangle(int x, int y, int width, int height) {
if (width < 0 || height < 0) {
throw new IllegalArgumentException();
}
collisionRectX = x;
collisionRectY = y;
collisionRectWidth = width;
collisionRectHeight = height;
// call set transform with current transformation to
// update transformed sprites collision rectangle
setTransformImpl(t_currentTransformation);
}
public void setTransform(int transform) {
setTransformImpl(transform);
}
public final boolean collidesWith(Sprite s, boolean pixelLevel) {
// check if either of the Sprite's are not visible
if (!(s.visible && this.visible)) {
return false;
}
// these are package private
// and can be accessed directly
int otherLeft = s.x + s.t_collisionRectX;
int otherTop = s.y + s.t_collisionRectY;
int otherRight = otherLeft + s.t_collisionRectWidth;
int otherBottom = otherTop + s.t_collisionRectHeight;
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;
// 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) {
// 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;
}
// similarly for the other Sprite
if (s.t_collisionRectX < 0) {
otherLeft = s.x;
}
if (s.t_collisionRectY < 0) {
otherTop = s.y;
}
if ((s.t_collisionRectX + s.t_collisionRectWidth) > s.width) {
otherRight = s.x + s.width;
}
if ((s.t_collisionRectY + s.t_collisionRectHeight) > s.height) {
otherBottom = s.y + s.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;
}
// the updated collision rectangles intersect,
// go ahead with collision detection
// find intersecting region,
// 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 = s.getImageTopLeftX(intersectLeft,
intersectTop, intersectRight, intersectBottom);
int otherImageYOffset = s.getImageTopLeftY(intersectLeft,
intersectTop, intersectRight, intersectBottom);
// check if opaque pixels intersect.
return doPixelCollision(thisImageXOffset, thisImageYOffset,
otherImageXOffset, otherImageYOffset, this.sourceImage,
this.t_currentTransformation, s.sourceImage,
s.t_currentTransformation, intersectWidth,
intersectHeight);
} else {
// collides!
return true;
}
}
return false;
}
public final boolean collidesWith(TiledLayer t, boolean pixelLevel) {
// check if either this Sprite or the TiledLayer is not visible
if (!(t.visible && this.visible)) {
return false;
}
// dimensions of tiledLayer, cell, and
// this Sprite's collision rectangle
// these are package private
// and can be accessed directly
int tLx1 = t.x;
int tLy1 = t.y;
int tLx2 = tLx1 + t.width;
int tLy2 = tLy1 + t.height;
int tW = t.getCellWidth();
int tH = t.getCellHeight();
int sx1 = this.x + this.t_collisionRectX;
int sy1 = this.y + this.t_collisionRectY;
int sx2 = sx1 + this.t_collisionRectWidth;
int sy2 = sy1 + this.t_collisionRectHeight;
// number of cells
int tNumCols = t.getColumns();
int tNumRows = t.getRows();
// temporary loop variables.
int startCol; // = 0;
int endCol; // = 0;
int startRow; // = 0;
int endRow; // = 0;
if (!intersectRect(tLx1, tLy1, tLx2, tLy2, sx1, sy1, sx2, sy2)) {
// if the collision rectangle of the sprite
// does not intersect with the dimensions of the entire
// tiled layer
return false;
}
// so there is an intersection
// 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;
if (!pixelLevel) {
// check for intersection with a non-empty cell,
for (int row = startRow; row <= endRow; row++) {
for (int col = startCol; col <= endCol; col++) {
if (t.getCell(col, row) != 0) {
return true;
}
}
}
// worst case! we scanned through entire
// overlapping region and
// all the cells are empty!
return false;
} else {
// do pixel level
// 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) {
sx1 = this.x;
}
if (this.t_collisionRectY < 0) {
sy1 = this.y;
}
if ((this.t_collisionRectX + this.t_collisionRectWidth) > this.width) {
sx2 = this.x + this.width;
}
if ((this.t_collisionRectY + this.t_collisionRectHeight) > this.height) {
sy2 = this.y + this.height;
}
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;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -