📄 sprite.java
字号:
/*
* 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();
}
this.frame = frame;
}
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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -