/*
Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
и других спецификаций для функционирования компактных приложений на языке
Java (мидлетов) в среде программного обеспечения Малик Эмулятор.
Copyright © 2016–2017, 2019–2023 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package javax.microedition.lcdui.game;
import javax.microedition.lcdui.*;
public class Sprite extends Layer
{
public static final int TRANS_NONE = 0;
public static final int TRANS_MIRROR_ROT180 = 1;
public static final int TRANS_MIRROR = 2;
public static final int TRANS_ROT180 = 3;
public static final int TRANS_MIRROR_ROT270 = 4;
public static final int TRANS_ROT90 = 5;
public static final int TRANS_ROT270 = 6;
public static final int TRANS_MIRROR_ROT90 = 7;
private static final int MAX_SIZE = 0x7fff;
private static boolean isPixelCollision(int width, int height, Image image1, int left1, int top1, int transform1, Image image2, int left2, int top2, int transform2) {
int area;
int xinc1;
int xinc2;
int yinc1;
int yinc2;
int start1;
int start2;
int[] pixels1 = new int[area = width * height];
int[] pixels2 = new int[area];
if((transform1 & 0x04) != 0)
{
if((transform1 & 0x01) != 0)
{
xinc1 = -height;
start1 = area - height;
} else
{
xinc1 = height;
start1 = 0;
}
if((transform1 & 0x02) != 0)
{
yinc1 = -1;
start1 += height - 1;
} else
{
yinc1 = 1;
}
image1.getRGB(pixels1, 0, height, left1, top1, height, width);
} else
{
if((transform1 & 0x01) != 0)
{
yinc1 = -width;
start1 = area - width;
} else
{
yinc1 = width;
start1 = 0;
}
if((transform1 & 0x02) != 0)
{
xinc1 = -1;
start1 += width - 1;
} else
{
xinc1 = 1;
}
image1.getRGB(pixels1, 0, width, left1, top1, width, height);
}
if((transform2 & 0x04) != 0)
{
if((transform2 & 0x01) != 0)
{
xinc2 = -height;
start2 = area - height;
} else
{
xinc2 = height;
start2 = 0;
}
if((transform2 & 0x02) != 0)
{
yinc2 = -1;
start2 += height - 1;
} else
{
yinc2 = 1;
}
image2.getRGB(pixels2, 0, height, left2, top2, height, width);
} else
{
if((transform2 & 0x01) != 0)
{
yinc2 = -width;
start2 = area - width;
} else
{
yinc2 = width;
start2 = 0;
}
if((transform2 & 0x02) != 0)
{
xinc2 = -1;
start2 += width - 1;
} else
{
xinc2 = 1;
}
image2.getRGB(pixels2, 0, width, left2, top2, width, height);
}
for(int startx1 = start1, startx2 = start2, j = height; j-- > 0; startx1 += yinc1, startx2 += yinc2) for(int x1 = startx1, x2 = startx2, i = width; i-- > 0; x1 += xinc1, x2 += xinc2)
{
if((pixels1[x1] & 0xff000000) != 0 && (pixels2[x2] & 0xff000000) != 0) return true;
}
return false;
}
private static boolean isRectIntersection(int left1, int top1, int right1, int bottom1, int left2, int top2, int right2, int bottom2) {
return left1 < right2 && left2 < right1 && top1 < bottom2 && top2 < bottom1;
}
private int referencePointX;
private int referencePointY;
private int collisionRectLeft;
private int collisionRectTop;
private int collisionRectWidth;
private int collisionRectHeight;
private int transformedCollisionRectLeft;
private int transformedCollisionRectTop;
private int transformedCollisionRectWidth;
private int transformedCollisionRectHeight;
private int transformation;
private int frameIndex;
private int frameSetFrameWidth;
private int frameSetFrameHeight;
private int frameSetFramesCount;
private int frameSetFramesPerRow;
private int[] frameSequenceDefault;
private int[] frameSequence;
private Image frameSet;
public Sprite(Sprite source) {
if(source == null)
{
throw new NullPointerException("Sprite: аргумент source равен нулевой ссылке.");
}
synchronized(source.monitor)
{
this.visibility = source.visibility;
this.left = source.left;
this.top = source.top;
this.width = source.width;
this.height = source.height;
this.referencePointX = source.referencePointX;
this.referencePointY = source.referencePointY;
this.collisionRectLeft = source.collisionRectLeft;
this.collisionRectTop = source.collisionRectTop;
this.collisionRectWidth = source.collisionRectWidth;
this.collisionRectHeight = source.collisionRectHeight;
this.transformedCollisionRectLeft = source.transformedCollisionRectLeft;
this.transformedCollisionRectTop = source.transformedCollisionRectTop;
this.transformedCollisionRectWidth = source.transformedCollisionRectWidth;
this.transformedCollisionRectHeight = source.transformedCollisionRectHeight;
this.transformation = source.transformation;
this.frameIndex = source.frameIndex;
this.frameSetFrameWidth = source.frameSetFrameWidth;
this.frameSetFrameHeight = source.frameSetFrameHeight;
this.frameSetFramesCount = source.frameSetFramesCount;
this.frameSetFramesPerRow = source.frameSetFramesPerRow;
this.frameSequenceDefault = source.frameSequenceDefault;
this.frameSequence = source.frameSequence;
this.frameSet = source.frameSet;
}
}
public Sprite(Image frame) {
int frameWidth;
int frameHeight;
int[] frameSequence;
if(frame == null)
{
throw new NullPointerException("Sprite: аргумент frame равен нулевой ссылке.");
}
this.width = frameWidth = frame.getWidth();
this.height = frameHeight = frame.getHeight();
this.collisionRectWidth = frameWidth;
this.collisionRectHeight = frameHeight;
this.transformedCollisionRectWidth = frameWidth;
this.transformedCollisionRectHeight = frameHeight;
this.frameSetFrameWidth = frameWidth;
this.frameSetFrameHeight = frameHeight;
this.frameSetFramesCount = 1;
this.frameSetFramesPerRow = 1;
this.frameSequenceDefault = frameSequence = new int[1];
this.frameSequence = frameSequence;
this.frameSet = frame;
}
public Sprite(Image frameSet, int frameWidth, int frameHeight) {
int framesCount;
int framesPerRow;
int frameSetWidth;
int frameSetHeight;
int[] frameSequence;
if(frameSet == null)
{
throw new NullPointerException("Sprite: аргумент frameSet равен нулевой ссылке.");
}
if(frameWidth < 1 || frameWidth > MAX_SIZE)
{
throw new IllegalArgumentException("Sprite: аргумент frameWidth не может быть меньше 1 или больше " + MAX_SIZE + ".");
}
if(frameHeight < 1 || frameHeight > MAX_SIZE)
{
throw new IllegalArgumentException("Sprite: аргумент frameHeight не может быть меньше 1 или больше " + MAX_SIZE + ".");
}
if((frameSetWidth = frameSet.getWidth()) % frameWidth != 0 || (frameSetHeight = frameSet.getHeight()) % frameHeight != 0)
{
throw new IllegalArgumentException("Sprite: размеры кадров оба должны быть делителями размеров набора кадров.");
}
this.width = frameWidth;
this.height = frameHeight;
this.collisionRectWidth = frameWidth;
this.collisionRectHeight = frameHeight;
this.transformedCollisionRectWidth = frameWidth;
this.transformedCollisionRectHeight = frameHeight;
this.frameSetFrameWidth = frameWidth;
this.frameSetFrameHeight = frameHeight;
this.frameSetFramesCount = framesCount = (framesPerRow = frameSetWidth / frameWidth) * (frameSetHeight / frameHeight);
this.frameSetFramesPerRow = framesPerRow;
this.frameSequenceDefault = frameSequence = new int[framesCount];
this.frameSequence = frameSequence;
this.frameSet = frameSet;
for(int i = framesCount; i-- > 1; frameSequence[i] = i);
}
public void nextFrame() {
synchronized(monitor)
{
frameIndex = (frameIndex + 1) % frameSequence.length;
}
}
public void prevFrame() {
synchronized(monitor)
{
int len = frameSequence.length;
frameIndex = (frameIndex + len - 1) % len;
}
}
public void defineReferencePixel(int x, int y) {
synchronized(monitor)
{
referencePointX = x;
referencePointY = y;
}
}
public void defineCollisionRectangle(int left, int top, int width, int height) {
if(width < 0)
{
throw new IllegalArgumentException("Sprite.defineCollisionRectangle: аргумент width не может быть отрицательным.");
}
if(height < 0)
{
throw new IllegalArgumentException("Sprite.defineCollisionRectangle: аргумент height не может быть отрицательным.");
}
synchronized(monitor)
{
collisionRectLeft = left;
collisionRectTop = top;
collisionRectWidth = width;
collisionRectHeight = height;
computeTransformedBounds(transformation);
}
}
public void setRefPixelPosition(int x, int y) {
synchronized(monitor)
{
int transform = transformation;
left = x - getTransformedReferencePointX(transform);
top = y - getTransformedReferencePointY(transform);
}
}
public void setTransform(int transform) {
if((transform & (-8)) != 0)
{
throw new IllegalArgumentException("Sprite.setTransform: аргумент transform имеет недопустимое значение.");
}
synchronized(monitor)
{
int oldTransform = transformation;
if(transform != oldTransform)
{
this.left += getTransformedReferencePointX(oldTransform) - getTransformedReferencePointX(transform);
this.top += getTransformedReferencePointY(oldTransform) - getTransformedReferencePointY(transform);
this.computeTransformedBounds(transform);
this.transformation = transform;
}
}
}
public void setImage(Image frameSet, int frameWidth, int frameHeight) {
int framesCount;
int framesPerRow;
int frameSetWidth;
int frameSetHeight;
if(frameSet == null)
{
throw new NullPointerException("Sprite.setImage: аргумент frameSet равен нулевой ссылке.");
}
if(frameWidth < 1 || frameWidth > MAX_SIZE)
{
throw new IllegalArgumentException("Sprite.setImage: аргумент frameWidth не может быть меньше 1 или больше " + MAX_SIZE + ".");
}
if(frameHeight < 1 || frameHeight > MAX_SIZE)
{
throw new IllegalArgumentException("Sprite.setImage: аргумент frameHeight не может быть меньше 1 или больше " + MAX_SIZE + ".");
}
if((frameSetWidth = frameSet.getWidth()) % frameWidth != 0 || (frameSetHeight = frameSet.getHeight()) % frameHeight != 0)
{
throw new IllegalArgumentException("Sprite.setImage: размеры кадров оба должны быть делителями размеров набора кадров.");
}
framesCount = (framesPerRow = frameSetWidth / frameWidth) * (frameSetHeight / frameHeight);
synchronized(monitor)
{
int oldFramesCount;
int[] frameSequence;
if(frameWidth != frameSetFrameWidth || frameHeight != frameSetFrameHeight)
{
int transform = transformation;
int x = left + getTransformedReferencePointX(transform);
int y = top + getTransformedReferencePointY(transform);
collisionRectLeft = 0;
collisionRectTop = 0;
collisionRectWidth = frameWidth;
collisionRectHeight = frameHeight;
transformedCollisionRectLeft = 0;
transformedCollisionRectTop = 0;
if((transform & 4) != 0)
{
transformedCollisionRectWidth = width = frameHeight;
transformedCollisionRectHeight = height = frameWidth;
} else
{
transformedCollisionRectWidth = width = frameWidth;
transformedCollisionRectHeight = height = frameHeight;
}
left = x - getTransformedReferencePointX(transform);
top = y - getTransformedReferencePointY(transform);
frameSetFrameWidth = frameWidth;
frameSetFrameHeight = frameHeight;
}
oldFramesCount = frameSetFramesCount;
frameSetFramesPerRow = framesPerRow;
frameSetFramesCount = framesCount;
if(oldFramesCount == framesCount)
{
frameSequence = null;
} else
{
frameSequence = new int[framesCount];
for(int i = framesCount; i-- > 1; frameSequence[i] = i);
}
if(framesCount < oldFramesCount)
{
this.frameIndex = 0;
this.frameSequence = frameSequence;
}
else if(framesCount > oldFramesCount && this.frameSequence == this.frameSequenceDefault)
{
this.frameSequence = frameSequence;
}
this.frameSequenceDefault = frameSequence;
this.frameSet = frameSet;
}
}
public void setFrameSequence(int[] sequence) {
int len;
int error;
int[] frameSequence;
if(sequence == null)
{
len = 0;
frameSequence = null;
} else
{
if((len = sequence.length) < 1)
{
throw new IllegalArgumentException("Sprite.setFrameSequence: аргумент sequence не может иметь длину меньше 1.");
}
Array.copy(sequence, 0, frameSequence = new int[len], 0, len);
}
error = 0;
synchronized(monitor)
{
label0:
{
if(frameSequence == null)
{
frameSequence = this.frameSequenceDefault;
} else
{
int framesCount = this.frameSetFramesCount;
for(int i = len; i-- > 0; )
{
int frame;
if((frame = frameSequence[i]) < 0 || frame >= framesCount)
{
error = 1;
break label0;
}
}
}
this.frameIndex = 0;
this.frameSequence = frameSequence;
}
}
if(error == 1)
{
throw new ArrayIndexOutOfBoundsException("Sprite.setFrameSequence: один из элементов аргумента sequence выходит из диапазона.");
}
}
public void setFrame(int frameIndex) {
int error = 0;
synchronized(monitor)
{
label0:
{
if(frameIndex < 0 || frameIndex >= frameSequence.length)
{
error = 1;
break label0;
}
this.frameIndex = frameIndex;
}
}
if(error == 1)
{
throw new IndexOutOfBoundsException("Sprite.setFrame: аргумент frameIndex выходит из диапазона.");
}
}
public int getRefPixelX() {
int result;
synchronized(monitor)
{
result = left + getTransformedReferencePointX(transformation);
}
return result;
}
public int getRefPixelY() {
int result;
synchronized(monitor)
{
result = top + getTransformedReferencePointY(transformation);
}
return result;
}
public int getRawFrameCount() {
return frameSetFramesCount;
}
public int getFrameSequenceLength() {
return frameSequence.length;
}
public final void paint(Graphics render) {
int x;
int y;
int frame;
int transform;
int frameWidth;
int frameHeight;
int framesPerRow;
Image frameSetImage;
if(render == null)
{
throw new NullPointerException("Sprite.paint: аргумент render равен нулевой ссылке.");
}
if(!visibility) return;
synchronized(monitor)
{
x = left;
y = top;
frame = frameSequence[frameIndex];
transform = transformation;
frameWidth = frameSetFrameWidth;
frameHeight = frameSetFrameHeight;
framesPerRow = frameSetFramesPerRow;
frameSetImage = frameSet;
}
render.drawRegion(frameSetImage, (frame % framesPerRow) * frameWidth, (frame / framesPerRow) * frameHeight, frameWidth, frameHeight, transform, x, y, 0);
}
public final boolean collidesWith(Sprite sprite, boolean pixelLevel) {
boolean result;
if(sprite == null)
{
throw new NullPointerException("Sprite.collidesWith: аргумент sprite равен нулевой ссылке.");
}
if(!this.visibility || !sprite.visibility) return false;
synchronized(this.monitor)
{
synchronized(sprite.monitor)
{
label0:
{
int layer1Left = this.left;
int layer1Top = this.top;
int layer1Right = layer1Left + this.width;
int layer1Bottom = layer1Top + this.height;
int thisLeft = layer1Left + this.transformedCollisionRectLeft;
int thisTop = layer1Top + this.transformedCollisionRectTop;
int thisRight = thisLeft + this.transformedCollisionRectWidth;
int thisBottom = thisTop + this.transformedCollisionRectHeight;
int layer2Left = sprite.left;
int layer2Top = sprite.top;
int layer2Right = layer2Left + sprite.width;
int layer2Bottom = layer2Top + sprite.height;
int spriteLeft = layer2Left + sprite.transformedCollisionRectLeft;
int spriteTop = layer2Top + sprite.transformedCollisionRectTop;
int spriteRight = spriteLeft + sprite.transformedCollisionRectWidth;
int spriteBottom = spriteTop + sprite.transformedCollisionRectHeight;
int resultLeft;
int resultTop;
int resultRight;
int resultBottom;
int resultWidth;
int resultHeight;
int thisFrameSetLeft;
int thisFrameSetTop;
int spriteFrameSetLeft;
int spriteFrameSetTop;
if(!isRectIntersection(thisLeft, thisTop, thisRight, thisBottom, spriteLeft, spriteTop, spriteRight, spriteBottom))
{
result = false;
break label0;
}
if(!pixelLevel)
{
result = true;
break label0;
}
resultLeft = Math.max(Math.max(layer1Left, thisLeft), Math.max(layer2Left, spriteLeft));
resultTop = Math.max(Math.max(layer1Top, thisTop), Math.max(layer2Top, spriteTop));
resultRight = Math.min(Math.min(layer1Right, thisRight), Math.min(layer2Right, spriteRight));
resultBottom = Math.min(Math.min(layer1Bottom, thisBottom), Math.min(layer2Bottom, spriteBottom));
if((resultWidth = resultRight - resultLeft) <= 0 || (resultHeight = resultBottom - resultTop) <= 0)
{
result = false;
break label0;
}
thisFrameSetLeft = this.getFrameSetLeft(resultLeft, resultTop, resultRight, resultBottom);
thisFrameSetTop = this.getFrameSetTop(resultLeft, resultTop, resultRight, resultBottom);
spriteFrameSetLeft = sprite.getFrameSetLeft(resultLeft, resultTop, resultRight, resultBottom);
spriteFrameSetTop = sprite.getFrameSetTop(resultLeft, resultTop, resultRight, resultBottom);
result = isPixelCollision(
resultWidth, resultHeight,
this.frameSet, thisFrameSetLeft, thisFrameSetTop, this.transformation,
sprite.frameSet, spriteFrameSetLeft, spriteFrameSetTop, sprite.transformation
);
}
}
}
return result;
}
public final boolean collidesWith(TiledLayer tiles, boolean pixelLevel) {
boolean result;
if(tiles == null)
{
throw new NullPointerException("Sprite.collidesWith: аргумент tiles равен нулевой ссылке.");
}
if(!this.visibility || !tiles.visibility) return false;
synchronized(this.monitor)
{
synchronized(tiles.monitor)
{
label0:
{
int layer1Left = this.left;
int layer1Top = this.top;
int layer1Right = layer1Left + this.width;
int layer1Bottom = layer1Top + this.height;
int thisLeft = layer1Left + this.transformedCollisionRectLeft;
int thisTop = layer1Top + this.transformedCollisionRectTop;
int thisRight = thisLeft + this.transformedCollisionRectWidth;
int thisBottom = thisTop + this.transformedCollisionRectHeight;
int layer2Left = tiles.left;
int layer2Top = tiles.top;
int layer2Right = layer2Left + tiles.width;
int layer2Bottom = layer2Top + tiles.height;
int resultLeft;
int resultTop;
int resultRight;
int resultBottom;
int cellsWidth;
int cellsHeight;
int cellLeft;
int cellTop;
int cellRight;
int cellBottom;
int cellsPerRow;
int transform;
Image frameSet;
Image tileSet;
if(!isRectIntersection(thisLeft, thisTop, thisRight, thisBottom, layer2Left, layer2Top, layer2Right, layer2Bottom))
{
result = false;
break label0;
}
resultLeft = Math.max(Math.max(layer1Left, thisLeft), layer2Left);
resultTop = Math.max(Math.max(layer1Top, thisTop), layer2Top);
resultRight = Math.min(Math.min(layer1Right, thisRight), layer2Right);
resultBottom = Math.min(Math.min(layer1Bottom, thisBottom), layer2Bottom);
if(resultRight - resultLeft <= 0 || resultBottom - resultTop <= 0)
{
result = false;
break label0;
}
cellsWidth = tiles.tileSetCellWidth;
cellsHeight = tiles.tileSetCellHeight;
cellLeft = (resultLeft - layer2Left) / cellsWidth;
cellTop = (resultTop - layer2Top) / cellsHeight;
cellRight = (resultRight - layer2Right - 1) / cellsWidth;
cellBottom = (resultBottom - layer2Bottom - 1) / cellsHeight;
if(!pixelLevel)
{
for(int row = cellTop; row <= cellBottom; row++) for(int col = cellLeft; col <= cellRight; col++) if(tiles.getTileIndex(col, row) != 0)
{
result = true;
break label0;
}
result = false;
break label0;
}
cellsPerRow = tiles.tileSetCellsPerRow;
transform = this.transformation;
frameSet = this.frameSet;
tileSet = tiles.tileSet;
for(int row = cellTop; row <= cellBottom; row++) for(int col = cellLeft; col <= cellRight; col++)
{
int cell;
int tileX;
int tileY;
int spriteLeft;
int spriteTop;
int spriteWidth;
int spriteHeight;
int delta;
int spriteRight;
int spriteBottom;
int frameSetLeft;
int frameSetTop;
if((cell = tiles.getTileIndex(col, row)) == 0) continue;
cell--;
tileX = (cell % cellsPerRow) * cellsWidth;
tileY = (cell / cellsPerRow) * cellsHeight;
spriteLeft = layer2Left + col * cellsWidth;
spriteTop = layer2Top + row * cellsHeight;
spriteWidth = cellsWidth;
spriteHeight = cellsHeight;
if((delta = resultLeft - spriteLeft) > 0)
{
tileX += delta;
spriteLeft += delta;
spriteWidth -= delta;
}
if((delta = spriteLeft + spriteWidth - resultRight) > 0) spriteWidth -= delta;
if((delta = resultTop - spriteTop) > 0)
{
tileY += delta;
spriteTop += delta;
spriteHeight -= delta;
}
if((delta = spriteTop + spriteHeight - resultBottom) > 0) spriteHeight -= delta;
spriteRight = spriteLeft + spriteWidth;
spriteBottom = spriteTop + spriteHeight;
frameSetLeft = getFrameSetLeft(spriteLeft, spriteTop, spriteRight, spriteBottom);
frameSetTop = getFrameSetTop(spriteLeft, spriteTop, spriteRight, spriteBottom);
if(isPixelCollision(spriteWidth, spriteHeight, frameSet, frameSetLeft, frameSetTop, transform, tileSet, tileX, tileY, TRANS_NONE))
{
result = true;
break label0;
}
}
result = false;
}
}
}
return result;
}
public final boolean collidesWith(Image image, int left, int top, boolean pixelLevel) {
boolean result;
if(image == null)
{
throw new NullPointerException("Sprite.collidesWith: аргумент image равен нулевой ссылке.");
}
if(!visibility) return false;
synchronized(monitor)
{
label0:
{
int layerLeft = this.left;
int layerTop = this.top;
int layerRight = layerLeft + this.width;
int layerBottom = layerTop + this.height;
int thisLeft = layerLeft + transformedCollisionRectLeft;
int thisTop = layerTop + transformedCollisionRectTop;
int thisRight = thisLeft + transformedCollisionRectWidth;
int thisBottom = thisTop + transformedCollisionRectHeight;
int srcLeft = left;
int srcTop = top;
int srcRight = srcLeft + image.getWidth();
int srcBottom = srcTop + image.getHeight();
int resultLeft;
int resultTop;
int resultRight;
int resultBottom;
int resultWidth;
int resultHeight;
int frameSetLeft;
int frameSetTop;
if(!isRectIntersection(thisLeft, thisTop, thisRight, thisBottom, srcLeft, srcTop, srcRight, srcBottom))
{
result = false;
break label0;
}
if(!pixelLevel)
{
result = true;
break label0;
}
resultLeft = Math.max(Math.max(layerLeft, thisLeft), srcLeft);
resultTop = Math.max(Math.max(layerTop, thisTop), srcTop);
resultRight = Math.min(Math.min(layerRight, thisRight), srcRight);
resultBottom = Math.min(Math.min(layerBottom, thisBottom), srcBottom);
if((resultWidth = resultRight - resultLeft) <= 0 || (resultHeight = resultBottom - resultTop) <= 0)
{
result = false;
break label0;
}
frameSetLeft = getFrameSetLeft(resultLeft, resultTop, resultRight, resultBottom);
frameSetTop = getFrameSetTop(resultLeft, resultTop, resultRight, resultBottom);
result = isPixelCollision(resultWidth, resultHeight, frameSet, frameSetLeft, frameSetTop, transformation, image, resultLeft - srcLeft, resultTop - srcTop, TRANS_NONE);
}
}
return result;
}
public final int getFrame() {
return frameIndex;
}
private void computeTransformedBounds(int transform) {
int fw;
int fh;
int crw;
int crh;
switch(transform)
{
default:
width = frameSetFrameWidth;
height = frameSetFrameHeight;
transformedCollisionRectLeft = collisionRectLeft;
transformedCollisionRectTop = collisionRectTop;
transformedCollisionRectWidth = collisionRectWidth;
transformedCollisionRectHeight = collisionRectHeight;
break;
case TRANS_ROT90:
fh = frameSetFrameHeight;
crh = collisionRectHeight;
width = fh;
height = frameSetFrameWidth;
transformedCollisionRectLeft = fh - crh - collisionRectTop;
transformedCollisionRectTop = collisionRectLeft;
transformedCollisionRectWidth = crh;
transformedCollisionRectHeight = collisionRectWidth;
break;
case TRANS_ROT180:
fw = frameSetFrameWidth;
fh = frameSetFrameHeight;
crw = collisionRectWidth;
crh = collisionRectHeight;
width = fw;
height = fh;
transformedCollisionRectLeft = fw - crw - collisionRectLeft;
transformedCollisionRectTop = fh - crh - collisionRectTop;
transformedCollisionRectWidth = crw;
transformedCollisionRectHeight = crh;
break;
case TRANS_ROT270:
fw = frameSetFrameWidth;
crw = collisionRectWidth;
width = frameSetFrameHeight;
height = fw;
transformedCollisionRectLeft = collisionRectTop;
transformedCollisionRectTop = fw - crw - collisionRectLeft;
transformedCollisionRectWidth = collisionRectHeight;
transformedCollisionRectHeight = crw;
break;
case TRANS_MIRROR:
fw = frameSetFrameWidth;
crw = collisionRectWidth;
width = fw;
height = frameSetFrameHeight;
transformedCollisionRectLeft = fw - crw - collisionRectLeft;
transformedCollisionRectTop = collisionRectTop;
transformedCollisionRectWidth = crw;
transformedCollisionRectHeight = collisionRectHeight;
break;
case TRANS_MIRROR_ROT90:
fw = frameSetFrameWidth;
fh = frameSetFrameHeight;
crw = collisionRectWidth;
crh = collisionRectHeight;
width = fh;
height = fw;
transformedCollisionRectLeft = fh - crh - collisionRectTop;
transformedCollisionRectTop = fw - crw - collisionRectLeft;
transformedCollisionRectWidth = crh;
transformedCollisionRectHeight = crw;
break;
case TRANS_MIRROR_ROT180:
fh = frameSetFrameHeight;
crh = collisionRectHeight;
width = frameSetFrameWidth;
height = fh;
transformedCollisionRectLeft = collisionRectLeft;
transformedCollisionRectTop = fh - crh - collisionRectTop;
transformedCollisionRectWidth = collisionRectWidth;
transformedCollisionRectHeight = crh;
break;
case TRANS_MIRROR_ROT270:
width = frameSetFrameHeight;
height = frameSetFrameWidth;
transformedCollisionRectLeft = collisionRectTop;
transformedCollisionRectTop = collisionRectLeft;
transformedCollisionRectWidth = collisionRectHeight;
transformedCollisionRectHeight = collisionRectWidth;
break;
}
}
private int getTransformedReferencePointX(int transform) {
switch(transform)
{
default:
return referencePointX;
case TRANS_ROT90:
case TRANS_MIRROR_ROT90:
return frameSetFrameHeight - referencePointY - 1;
case TRANS_ROT180:
case TRANS_MIRROR:
return frameSetFrameWidth - referencePointX - 1;
case TRANS_ROT270:
case TRANS_MIRROR_ROT270:
return referencePointY;
}
}
private int getTransformedReferencePointY(int transform) {
switch(transform)
{
default:
return referencePointY;
case TRANS_ROT90:
case TRANS_MIRROR_ROT270:
return referencePointX;
case TRANS_ROT180:
case TRANS_MIRROR_ROT180:
return frameSetFrameHeight - referencePointY - 1;
case TRANS_ROT270:
case TRANS_MIRROR_ROT90:
return frameSetFrameWidth - referencePointX - 1;
}
}
private int getFrameSetLeft(int left, int top, int right, int bottom) {
int result;
switch(transformation)
{
default:
result = left - this.left;
break;
case TRANS_ROT90:
case TRANS_MIRROR_ROT270:
result = top - this.top;
break;
case TRANS_ROT180:
case TRANS_MIRROR:
result = this.left + this.width - right;
break;
case TRANS_ROT270:
case TRANS_MIRROR_ROT90:
result = this.top + this.height - bottom;
break;
}
return result + (frameSequence[frameIndex] % frameSetFramesPerRow) * frameSetFrameWidth;
}
private int getFrameSetTop(int left, int top, int right, int bottom) {
int result;
switch(transformation)
{
default:
result = top - this.top;
break;
case TRANS_ROT90:
case TRANS_MIRROR_ROT90:
result = this.left + this.width - right;
break;
case TRANS_ROT180:
case TRANS_MIRROR_ROT180:
result = this.top + this.height - bottom;
break;
case TRANS_ROT270:
case TRANS_MIRROR_ROT270:
result = left - this.left;
break;
}
return result + (frameSequence[frameIndex] / frameSetFramesPerRow) * frameSetFrameHeight;
}
}