Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* MicroEmulator
* Copyright (C) 2005 Andres Navarro
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package javax.microedition.lcdui.game;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
/**
*
* @author Andres Navarro
*
*/
// TODO add more synchronization
public class Sprite extends Layer {
// transform constants
public static final int TRANS_NONE = 0;
public static final int TRANS_ROT90 = 5;
public static final int TRANS_ROT180 = 3;
public static final int TRANS_ROT270 = 6;
public static final int TRANS_MIRROR = 2;
public static final int TRANS_MIRROR_ROT90 = 7;
public static final int TRANS_MIRROR_ROT180 = 1;
public static final int TRANS_MIRROR_ROT270 = 4;
// current frame index (within the sequence, not the absolut index)
private int frame;
// the frame sequence
// null if the default is used
private int [] sequence;
// coordinate of the reference pixel
private int refX;
private int refY;
// number of cols and rows within the image
private int cols;
private int rows;
// the transform aplied to this sprite
private int transform;
// the image containg the frames
private Image img;
// the collision rectangle
private int collX;
private int collY;
private int collWidth;
private int collHeight;
// arrays for the collision detection at pixel level
private int []rgbData;
private int []rgbDataAux;
public Sprite(Image img) {
this(img, img.getWidth(), img.getHeight());
}
public Sprite(Image img, int frameWidth, int frameHeight) {
// initial state is visible, positioned at 0, 0
// with a bound rectangle the same as the frame
super(0, 0, frameWidth, frameHeight, true);
// implicit check for null img
if (img.getWidth() % frameWidth != 0 ||
img.getHeight() % frameHeight != 0)
throw new IllegalArgumentException();
this.img = img;
cols = img.getWidth() / frameWidth;
rows = img.getHeight() / frameHeight;
collX = collY = 0;
collWidth = frameWidth;
collHeight = frameHeight;
}
public Sprite(Sprite otherSprite) {
// copy the otherSprite
super(otherSprite.getX(), otherSprite.getY(),
otherSprite.getWidth(), otherSprite.getHeight(),
otherSprite.isVisible());
this.frame = otherSprite.frame;
this.sequence = otherSprite.sequence;
this.refX = otherSprite.refX;
this.refY = otherSprite.refY;
this.cols = otherSprite.cols;
this.rows = otherSprite.rows;
this.transform = otherSprite.transform;
this.img = otherSprite.img;
this.collX = otherSprite.collX;
this.collY = otherSprite.collY;
this.collWidth = otherSprite.collWidth;
this.collHeight = otherSprite.collHeight;
}
public final boolean collidesWith(Image image, int iX, int iY, boolean pixelLevel) {
if (image == null)
throw new IllegalArgumentException();
// only check collision if visible
if (!this.isVisible())
return false;
if (pixelLevel)
return collidesWithPixelLevel(image, iX, iY);
else
return collidesWith(image, iX, iY);
}
public final boolean collidesWith(TiledLayer layer, boolean pixelLevel) {
int sX, sY;
int sW, sH;
if (layer == null) {
throw new NullPointerException();
}
// only check collision if visible
if (!this.isVisible())
return false;
// only check collision if both are visible
if (!layer.isVisible() || !this.isVisible())
return false;
if (pixelLevel) // second and third parameters are dont care
return collidesWithPixelLevel(layer, 0, 0);
else
return collidesWith(layer, 0, 0);
}
public final boolean collidesWith(Sprite otherSprite, boolean pixelLevel) {
int sX, sY;
int sW, sH;
if (otherSprite == null) {
throw new NullPointerException();
}
// only check collision if both are visible
if (!otherSprite.isVisible() || !this.isVisible())
return false;
if (pixelLevel) // second and third parameters are dont care
return collidesWithPixelLevel(otherSprite, 0, 0);
else
return collidesWith(otherSprite, 0, 0);
}
public void defineReferencePixel(int x, int y) {
refX = x;
refY = y;
}
public int getRefPixelX() {
return getX() + refX;
}
public int getRefPixelY() {
return getY() + refY;
}
public void setRefPixelPosition(int x, int y) {
int curRefX, curRefY;
int width = getWidth();
int height = getHeight();
switch(transform) {
case TRANS_NONE:
curRefX = refX;
curRefY = refY;
break;
case TRANS_MIRROR_ROT180:
curRefX = width - refX;
curRefY = height - refY;
break;
case TRANS_MIRROR:
curRefX = width - refX;
curRefY = refY;
break;
case TRANS_ROT180:
curRefX = refX;
curRefY = height - refY;
break;
case TRANS_MIRROR_ROT270:
curRefX = height - refY;
curRefY = refX;
break;
case TRANS_ROT90:
curRefX = height - refY;
curRefY = width - refX;
break;
case TRANS_ROT270:
curRefX = refY;
curRefY = refX;
break;
case TRANS_MIRROR_ROT90:
curRefX = refY;
curRefY = width - refX;
break;
default: // cant really happen, but the return keeps the
// compiler happy (otherwise it'll report variable
// may not be initialized)
return;
}
setPosition(x - curRefX, y - curRefY);
}
public void defineCollisionRectangle(int x, int y, int width, int height) {
if (width < 0 || height < 0)
throw new IllegalArgumentException();
collX = x;
collY = y;
collWidth = width;
collHeight = height;
}
public void setFrameSequence(int []sequence) {
if (sequence == null) {
// return to default sequence
this.sequence = null;
return;
}
int max = (rows*cols)-1;
int l = sequence.length;
if (l == 0)
throw new IllegalArgumentException();
for (int i = 0; i < l; i++) {
int value = sequence[i];
if (value > max || value < 0)
throw new ArrayIndexOutOfBoundsException();
}
this.sequence = sequence;
// the frame number has to be reseted
this.frame = 0;
}
public final int getFrame() {
return frame;
}
public int getFrameSequenceLength() {
return (sequence == null) ? rows*cols : sequence.length;
}
public void setFrame(int frame) {
int l = (sequence == null)? rows*cols : sequence.length;
if (frame < 0 || frame >= l)
throw new IndexOutOfBoundsException();
}
public void nextFrame() {
if (frame == ((sequence == null)? rows*cols : sequence.length) - 1)
frame = 0;
else
frame++;
}
public void prevFrame() {
if (frame == 0)
frame = ((sequence == null)? rows*cols : sequence.length) - 1;
else
frame--;
}
public void setImage(Image img, int frameWidth, int frameHeight) {
synchronized (this) {
int oldW = getWidth();
int oldH = getHeight();
int newW = img.getWidth();
int newH = img.getHeight();
// implicit size check
setSize(frameWidth, frameHeight);
if (img.getWidth() % frameWidth != 0 ||
img.getHeight() % frameHeight != 0)
throw new IllegalArgumentException();
this.img = img;
int oldFrames = cols*rows;
cols = img.getWidth() / frameWidth;
rows = img.getHeight() / frameHeight;
if (rows*cols < oldFrames) {
// there are fewer frames
// reset frame number and sequence
sequence = null;
frame = 0;
}
if (frameWidth != getWidth() || frameHeight != getHeight()) {
// size changed
// reset collision rectangle and collision detection array
defineCollisionRectangle(0, 0, frameWidth, frameHeight);
rgbData = rgbDataAux = null;
// if necessary change position to keep the reference pixel in place
if (transform != TRANS_NONE) {
int dx, dy;
switch(transform) {
case TRANS_MIRROR_ROT180:
dx = newW - oldW;
dy = newH - oldH;
break;
case TRANS_MIRROR:
dx = newW - oldW;
dy = 0;
break;
case TRANS_ROT180:
dx = 0;
dy = newH - oldH;
break;
case TRANS_MIRROR_ROT270:
dx = newH - oldH;
dy = 0;
break;
case TRANS_ROT90:
dx = newH - oldH;
dy = newW - oldW;
break;
case TRANS_ROT270:
dx = 0;
dy = 0;
break;
case TRANS_MIRROR_ROT90:
dx = 0;
dy = newW - oldW;
break;
default: // cant really happen, but the return keeps the
// compiler happy (otherwise it'll report variable
// may not be initialized)
return;
}
// now change position to keep the refPixel in place
move(dx, dy);
}
}
}
}
public final void paint(Graphics g) {
if (!isVisible())
return;
int f = (sequence == null)? frame : sequence[frame];
int w = getWidth();
int h = getHeight();
int fx = w * (f % cols);
int fy = h * (f / cols);
g.drawRegion(img, fx, fy, w, h, transform, getX(), getY(), Graphics.TOP | Graphics.LEFT);
}
public int getRawFrameCount() {
return cols * rows;
}
public void setTransform (int transform) {
if (this.transform == transform)
return;
int width = getWidth();
int height = getHeight();
int currentTransform = this.transform;
// calculate the coordinates of refPixel in the new transform
// relative to x, y
int newRefX, newRefY;
switch(transform) {
case TRANS_NONE:
newRefX = refX;
newRefY = refY;
break;
case TRANS_MIRROR_ROT180:
newRefX = width - refX;
newRefY = height - refY;
break;
case TRANS_MIRROR:
newRefX = width - refX;
newRefY = refY;
break;
case TRANS_ROT180:
newRefX = refX;
newRefY = height - refY;
break;
case TRANS_MIRROR_ROT270:
newRefX = height - refY;
newRefY = refX;
break;
case TRANS_ROT90:
newRefX = height - refY;
newRefY = width - refX;
break;
case TRANS_ROT270:
newRefX = refY;
newRefY = refX;
break;
case TRANS_MIRROR_ROT90:
newRefX = refY;
newRefY = width - refX;
break;
default:
throw new IllegalArgumentException();
}
// calculate the coordinates of refPixel in the current transform
// relative to x, y
int curRefX, curRefY;
switch(currentTransform) {
case TRANS_NONE:
curRefX = refX;
curRefY = refY;
break;
case TRANS_MIRROR_ROT180:
curRefX = width - refX;
curRefY = height - refY;
break;
case TRANS_MIRROR:
curRefX = width - refX;
curRefY = refY;
break;
case TRANS_ROT180:
curRefX = refX;
curRefY = height - refY;
break;
case TRANS_MIRROR_ROT270:
curRefX = height - refY;
curRefY = refX;
break;
case TRANS_ROT90:
curRefX = height - refY;
curRefY = width - refX;
break;
case TRANS_ROT270:
curRefX = refY;
curRefY = refX;
break;
case TRANS_MIRROR_ROT90:
curRefX = refY;
curRefY = width - refX;
break;
default: // cant really happen, but the return keeps the
// compiler happy (otherwise it'll report variable
// may not be initialized)
return;
}
// now change position to keep the refPixel in place
move(curRefX - newRefX, curRefY - newRefY);
this.transform = transform;
}
/**
* Helper methods that check for collisions
* They are at the end of the file because of the
* length of the code
*
* For both methods, the second and third parameters
* are significant only if o is an Image,
* otherwise they are ignored
*/
private synchronized boolean collidesWith(Object o,
int oX, int oY) {
int tX = 0, tY = 0, tW = 0, tH = 0;
int oW = 0, oH = 0;
Sprite t = this;
boolean another = true;
while (another) {
int sX, sY, sW, sH;
int cX = t.collX;
int cY = t.collY;
int cW = t.collWidth;
int cH = t.collHeight;
// if there is a zero in a dimension
// then it cannot intersect with anything!
if (cW == 0 || cH == 0) {
return false;
}
switch(t.transform) {
case TRANS_NONE:
sX = t.getX() + cX;
sY = t.getY() + cY;
sW = cW;
sH = cH;
break;
case TRANS_MIRROR_ROT180:
sX = t.getX() + cX;
sY = t.getY() + (t.getHeight() - cY - 1) - cH;
sW = cW;
sH = cH;
break;
case TRANS_MIRROR:
sX = t.getX() + (t.getWidth() - cX - 1) - cW;
sY = t.getY() + cY;
sW = cW;
sH = cH;
break;
case TRANS_ROT180:
sX = t.getX() + (t.getWidth() - cX - 1) - cW;
sY = t.getY() + (t.getHeight() - cY - 1) - cH;
sW = cW;
sH = cH;
break;
case TRANS_MIRROR_ROT270:
sX = t.getX() + cY;
sY = t.getY() + cX;
sW = cH;
sH = cW;
break;
case TRANS_ROT90:
sX = t.getX() + (t.getHeight() - cY - 1) - cH;
sY = t.getY() + cX;
sW = cH;
sH = cW;
break;
case TRANS_MIRROR_ROT90:
sX = t.getX() + (t.getHeight() - cY - 1) - cH;
sY = t.getY() + (t.getWidth() - cX - 1) - cW;
sW = cH;
sH = cW;
break;
case TRANS_ROT270:
sX = t.getX() + cY;
sY = t.getY() + (t.getWidth() - cX - 1) - cW;
sW = cH;
sH = cW;
break;
default: // cant really happen, but the return keeps the
// compiler happy (otherwise it'll report variable
// may not be initialized)
return false;
}
if (o != t) {
tX = sX;
tY = sY;
tW = sW;
tH = sH;
if (o instanceof Sprite) {
// two sprites first round
// another = true;
t = (Sprite) o;
} else if (o instanceof TiledLayer) {
another = false;
TiledLayer layer = (TiledLayer) o;
oX = layer.getX();
oY = layer.getY();
oW = layer.getWidth();
oH = layer.getHeight();
} else { // o instanceof lcdui.Image
another = false;
Image img = (Image) o;
oW = img.getWidth();
oH = img.getHeight();
}
} else {
another = false;
// two sprites
// second round
oX = sX;
oY = sY;
oW = sW;
oH = sH;
}
}
// if there is no intersection
// we know there is no collision
if (tX > oX && tX >= oX + oW)
return false;
else if (tX < oX && tX + tW <= oX)
return false;
else if (tY > oY && tY >= oY + oH)
return false;
else if (tY < oY && tY + tH <= oY)
return false;
if (o instanceof TiledLayer) {
// if o is a tiledLayer then
// it is possible to have not a
// collision if every intersection tile
// has a zero value
TiledLayer layer = (TiledLayer) o;
// this is the intersection of the two rectangles
int rX, rY, rW, rH;
if (oX > tX) {
rX = oX;
rW = ((oX + oW < tX + tW)? oX + oW : tX + tW) - rX;
} else {
rX = tX;
rW = ((tX + tW < oX + oW)? tX + tW : oX + oW) - rX;
}
if (oY > tY) {
rY = oY;
rH = ((oY + oH < tY + tH)? oY + oH : tY + tH) - rY;
} else {
rY = tY;
rH = ((tY + tH < oY + oH)? tY + tH : oY + oH) - rY;
}
Image img = layer.img;
int lW = layer.getCellWidth();
int lH = layer.getCellHeight();
int minC = (rX - oX) / lW;
int minR = (rY - oY) / lH;
int maxC = (rX - oX + rW - 1) / lW;
int maxR = (rY - oY + rH - 1) / lH;
// travel across all cells in the collision
// rectangle
for (int row = minR; row <= maxR; row++) {
for (int col = minC; col <= maxC; col++) {
int cell = layer.getCell(col, row);
// if cell is animated get current
// associated static tile
if (cell < 0)
cell = layer.getAnimatedTile(cell);
if (cell != 0)
return true;
}
}
// if no non zero cell was found
// there is no collision
return false;
} else {
// if the other object is an image or sprite
// collision happened
return true;
}
}
private synchronized boolean collidesWithPixelLevel(Object o,
int oX, int oY) {
boolean another = true;
Sprite t = this;
// the compiler bitchs if we dont initialize this
int tX = 0, tY = 0, tW = 0, tH = 0;
int oW = 0, oH = 0;
while (another) {
// first calculate the actual rectangle we must check
// for this sprite
// this are for the reduced collision rectangle
int cX, cY, cW, cH;
// this are for the intersection of the bounds rectangle
// and collision rectangle, taking into account
// position and transform
int sX, sY, sW, sH;
// take the collision rectangle in account
// but since the pixels outside the frame are
// considered transparent, first we have to
// take the intersection between the collision
// rectangle and the frame bounds
if (t.collX >= t.getWidth() || t.collX + t.collWidth <= 0
|| t.collY >= t.getHeight() || t.collY + t.collHeight <= 0)
// collision rectangle outside frame bounds
return false;
cX = (t.collX >= 0)? t.collX : 0;
cY = (t.collY >= 0)? t.collY : 0;
cW = (t.collX + t.collWidth < t.getWidth())? t.collX + t.collWidth - cX : t.getWidth() - cX;
cH = (t.collY + t.collHeight < t.getHeight())? t.collY + t.collHeight - cY : t.getHeight() - cY;
switch(t.transform) {
case TRANS_NONE:
sX = t.getX() + cX;
sY = t.getY() + cY;
sW = cW;
sH = cH;
break;
case TRANS_MIRROR_ROT180:
sX = t.getX() + cX;
sY = t.getY() + (t.getHeight() - cY - 1) - cH;
sW = cW;
sH = cH;
break;
case TRANS_MIRROR:
sX = t.getX() + (t.getWidth() - cX - 1) - cW;
sY = t.getY() + cY;
sW = cW;
sH = cH;
break;
case TRANS_ROT180:
sX = t.getX() + (t.getWidth() - cX - 1) - cW;
sY = t.getY() + (t.getHeight() - cY - 1) - cH;
sW = cW;
sH = cH;
break;
case TRANS_MIRROR_ROT270:
sX = t.getX() + cY;
sY = t.getY() + cX;
sW = cH;
sH = cW;
break;
case TRANS_ROT90:
sX = t.getX() + (t.getHeight() - cY) - cH;
sY = t.getY() + cX;
sW = cH;
sH = cW;
break;
case TRANS_MIRROR_ROT90:
sX = t.getX() + (t.getHeight() - cY) - cH;
sY = t.getY() + (t.getWidth() - cX) - cW;
sW = cH;
sH = cW;
break;
case TRANS_ROT270:
sX = t.getX() + cY;
sY = t.getY() + (t.getWidth() - cX) - cW;
sW = cH;
sH = cW;
break;
default: // cant really happen, but the return keeps the
// compiler happy (otherwise it'll report variable
// may not be initialized)
return false;
}
if (o != t) {
tX = sX;
tY = sY;
tW = sW;
tH = sH;
if (o instanceof Sprite) {
// two sprites first round
// another = true;
t = (Sprite) o;
} else if (o instanceof TiledLayer) {
another = false;
TiledLayer layer = (TiledLayer) o;
oX = layer.getX();
oY = layer.getY();
oW = layer.getWidth();
oH = layer.getHeight();
} else { // o instanceof lcdui.Image
another = false;
Image img = (Image) o;
oW = img.getWidth();
oH = img.getHeight();
}
} else {
another = false;
// two sprites
// second round
oX = sX;
oY = sY;
oW = sW;
oH = sH;
}
}
// if there is no intersection
// we know there is no collision
if (tX > oX && tX >= oX + oW)
return false;
else if (tX < oX && tX + tW <= oX)
return false;
else if (tY > oY && tY >= oY + oH)
return false;
else if (tY < oY && tY + tH <= oY)
return false;
// variables keep popping out of nowhere...
// this is the intersection of the two rectangles
int rX, rY, rW, rH;
if (oX > tX) {
rX = oX;
rW = ((oX + oW < tX + tW)? oX + oW : tX + tW) - rX ;
} else {
rX = tX;
rW = ((tX + tW < oX + oW)? tX + tW : oX + oW) - rX;
}
if (oY > tY) {
rY = oY;
rH = ((oY + oH < tY + tH)? oY + oH : tY + tH) - rY ;
} else {
rY = tY;
rH = ((tY + tH < oY + oH)? tY + tH : oY + oH) - rY;
}
// ...and a lot more..
int tColIncr = 0, tRowIncr = 0, tOffset = 0;
int oColIncr = 0, oRowIncr = 0, oOffset = 0;
int f = (sequence == null)? frame : sequence[frame];
int fW = getWidth();
int fH = getHeight();
int fX = fW * (f % rows);
int fY = fH * (f / rows);
if (rgbData == null) {
rgbData = new int[fW*fH];
rgbDataAux = new int[fW*fH];
}
t = this;
another = true;
int[] tRgbData = this.rgbData;
while (another) {
int sOffset;
int sColIncr;
int sRowIncr;
switch(t.transform) {
case TRANS_NONE:
t.img.getRGB(tRgbData, 0, rW, fX + rX - t.getX(), fY + rY - t.getY(), rW, rH);
sOffset = 0;
sColIncr = 1;
sRowIncr = 0;
break;
case TRANS_ROT180:
t.img.getRGB(tRgbData, 0, rW, fX + fW - (rX - t.getX()) - rW - 1, fY + fH - (rY - t.getY()) - rH - 1, rW, rH);
sOffset = (rH * rW) - 1;
sColIncr = -1;
sRowIncr = 0;
break;
case TRANS_MIRROR:
t.img.getRGB(tRgbData, 0, rW, fX + fW - (rX - t.getX()) - rW - 1, fY + rY - t.getY(), rW, rH);
sOffset = rW - 1;
sColIncr = -1;
sRowIncr = rW << 1;
break;
case TRANS_MIRROR_ROT180:
t.img.getRGB(tRgbData, 0, rW, fX + rX - t.getX(), fY + fH - (rY - t.getY()) - rH - 1, rW, rH);
sOffset = (rH - 1) * rW;
sColIncr = 1;
sRowIncr = -(rW << 1);
break;
case TRANS_ROT90:
t.img.getRGB(tRgbData, 0, rH, fX + rY - t.getY(), fY + fH - (rX - t.getX()) - rW, rH, rW);
sOffset = (rW - 1) * rH;
sColIncr = -rH;
sRowIncr = (rH * rW) + 1;
break;
case TRANS_MIRROR_ROT90:
t.img.getRGB(tRgbData, 0, rH, fX + fW - (rY - t.getY()) - rH, fY + fH - (rX - t.getX()) - rW, rH, rW);
sOffset = (rH * rW) - 1;
sColIncr = -rH;
sRowIncr = (rH * rW) - 1;
break;
case TRANS_MIRROR_ROT270:
t.img.getRGB(tRgbData, 0, rH, fX + rY - t.getY(), fY + rX - t.getX(), rH, rW);
sOffset = 0;
sColIncr = rH;
sRowIncr = -(rH * rW) + 1;
break;
case TRANS_ROT270:
t.img.getRGB(tRgbData, 0, rH, fX + fW - (rY - t.getY()) - rH, fY + rX - t.getX(), rH, rW);
sOffset = rH - 1;
sColIncr = rH;
sRowIncr = -(rH * rW) - 1;
break;
default: // cant really happen, but the return keeps the
// compiler happy (otherwise it'll report variable
// may not be initialized)
return false;
}
if (o != t) {
tOffset = sOffset;
tRowIncr = sRowIncr;
tColIncr = sColIncr;
if (o instanceof Sprite) {
// two sprites first round
// another = true;
t = (Sprite) o;
tRgbData = this.rgbDataAux;
f = (t.sequence == null)? t.frame : t.sequence[t.frame];
fW = t.getWidth();
fH = t.getHeight();
fX = fW * (f % t.rows);
fY = fH * (f / t.rows);
} else if (o instanceof TiledLayer) {
another = false;
TiledLayer layer = (TiledLayer) o;
Image img = layer.img;
oOffset = 0;
oColIncr = 1;
oRowIncr = 0;
int lW = layer.getCellWidth();
int lH = layer.getCellHeight();
int minC = (rX - oX) / lW;
int minR = (rY - oY) / lH;
int maxC = (rX - oX + rW - 1) / lW;
int maxR = (rY - oY + rH - 1) / lH;
// travel across all cells in the collision
// rectangle
for (int row = minR; row <= maxR; row++) {
for (int col = minC; col <= maxC; col++) {
int cell = layer.getCell(col, row);
// if cell is animated get current
// associated static tile
if (cell < 0)
cell = layer.getAnimatedTile(cell);
int minX = (col == minC)? (rX - oX) % lW : 0;
int minY = (row == minR)? (rY - oY) % lH : 0;
int maxX = (col == maxC)? (rX + rW - oX - 1) % lW : lW-1;
int maxY = (row == maxR)? (rY + rH - oY - 1) % lH : lH-1;
int c = (row - minR) * lH * rW + (col - minC) * lW -
((col == minC)? 0 : (rX - oX) % lW) -
((row == minR)? 0 : (rY - oY) % lH) * rW;
// if cell is invisible we should still set
// all points as transparent to prevent
// fake positives caused by residual data
// on the rgb array
if (cell == 0) {
for (int y = minY; y <= maxY; y++,
c += rW - (maxX - minX + 1)) {
for (int x = minX; x <= maxX; x++, c++) {
rgbDataAux[c] = 0;
}
}
} else {
// make cell 0-based
cell--;
int imgCols = img.getWidth() / layer.getCellWidth();
int xSrc = lW * (cell % imgCols);
int ySrc = (cell / imgCols) * lH;
img.getRGB(rgbDataAux, c, rW, xSrc + minX,
ySrc + minY, maxX - minX + 1,
maxY - minY + 1);
}
}
}
} else { // o instanceof lcdui.Image
another = false;
Image img = (Image) o;
// get the image rgb data, and the increments
img.getRGB(rgbDataAux, 0, rW, rX - oX, rY - oY, rW, rH);
oOffset = 0;
oColIncr = 1;
oRowIncr = 0;
}
} else {
// two sprites
// second round, exit the loop
another = false;
oOffset = sOffset;
oRowIncr = sRowIncr;
oColIncr = sColIncr;
}
}
for (int row = 0; row < rH; row++, tOffset += tRowIncr, oOffset += oRowIncr) {
for (int col = 0; col < rW; col++, tOffset += tColIncr, oOffset += oColIncr) {
int rgb = rgbData[tOffset];
int rgbA = rgbDataAux[oOffset];
// look for two opaque pixels
if (((rgb & rgbA) >> 24) == -1)
return true;
}
}
return false;
}
}