📄 sprite.java
字号:
int numberOfRows = this.rawFrameCount / this.numberOfColumns;
this.column = c;
this.row = r;
switch (this.transform ) {
case TRANS_NONE:
this.column = c;
this.row = r;
break;
case TRANS_MIRROR_ROT180:
this.column = c;
this.row = (numberOfRows-1) - r;
break;
case TRANS_MIRROR:
this.column = (this.numberOfColumns -1) - c;
this.row = r;
break;
case TRANS_ROT180:
this.column = (this.numberOfColumns -1) - c;
this.row = (numberOfRows-1) - r;
break;
case TRANS_MIRROR_ROT270:
this.column = c;
this.row = r;
break;
case TRANS_ROT90:
this.column = (numberOfRows -1) - r;
this.row = c;
break;
case TRANS_ROT270:
this.column = r;
this.row = (this.numberOfColumns -1) - c;
break;
case TRANS_MIRROR_ROT90:
this.row = (numberOfRows-1) - r;
this.row = (this.numberOfColumns -1) - c;
break;
}
//#endif
}
//#endif
//#ifndef polish.api.siemens-color-game-api
/**
* Draws the Sprite.
* <P>
* Draws current frame of Sprite using the provided Graphics object.
* The Sprite's upper left corner is rendered at the Sprite's current
* position relative to the origin of the Graphics object. The current
* position of the Sprite's upper-left corner can be retrieved by
* calling <A HREF="../../../../javax/microedition/lcdui/game/Layer.html#getX()"><CODE>Layer.getX()</CODE></A> and <A HREF="../../../../javax/microedition/lcdui/game/Layer.html#getY()"><CODE>Layer.getY()</CODE></A>.
* <P>
* Rendering is subject to the clip region of the Graphics object.
* The Sprite will be drawn only if it is visible.
* <p>
* If the Sprite's Image is mutable, the Sprite is rendered using the
* current contents of the Image.
*
* @param g the graphics object to draw Sprite on
* @throws NullPointerException - if g is null
* @see Layer#paint(Graphics) in class Layer
*/
public final void paint( Graphics g)
{
if (this.isSingleFrame && this.transform == 0) {
g.drawImage( this.image, this.xPosition, this.yPosition, Graphics.TOP | Graphics.LEFT );
return;
}
//#ifdef polish.api.nokia-ui
//# // just draw and rotate the current frame:
//# DirectGraphics dg = DirectUtils.getDirectGraphics( g );
//# dg.drawImage(this.nokiaFrame, this.xPosition, this.yPosition, Graphics.TOP | Graphics.LEFT, this.nokiaTransform );
//# /*
//# * uncomment this code for visualising the reference pixel
//# * and collision rectangle:
//# g.setColor( 0xFFFFFF );
//# g.drawLine( this.xPosition + this.transformedCollisionX, this.yPosition + this.transformedCollisionY, this.xPosition + this.transformedCollisionX + this.transformedCollisionWidth, this.yPosition + this.transformedCollisionY );
//# g.drawLine( this.xPosition + this.transformedCollisionX, this.yPosition + this.transformedCollisionY, this.xPosition + this.transformedCollisionX, this.yPosition + this.transformedCollisionY + this.transformedCollisionHeight );
//# g.setColor( 0xFF0000 );
//# g.drawLine( this.xPosition + this.transformedRefX - 4, this.yPosition + this.transformedRefY, this.xPosition + this.transformedRefX + 4, this.yPosition + this.transformedRefY );
//# g.drawLine( this.xPosition + this.transformedRefX, this.yPosition + this.transformedRefY - 4, this.xPosition + this.transformedRefX, this.yPosition + this.transformedRefY + 4 );
//# */
//#else
if (this.rawFrameCount == 1) {
g.drawImage( this.image, this.xPosition, this.yPosition, Graphics.TOP | Graphics.LEFT );
} else {
// there are several frames contained in the base-image:
int x = this.xPosition;
int y = this.yPosition;
//System.out.print("painting sprite at " + x + ", " + y );
//save the current clip position:
int clipX = g.getClipX();
int clipY = g.getClipY();
int clipWidth = g.getClipWidth();
int clipHeight = g.getClipHeight();
g.clipRect( x, y, this.width, this.height );
x -= this.column * this.width;
y -= this.row * this.height;
g.drawImage( this.image, x, y, Graphics.TOP | Graphics.LEFT );
// reset original clip:
g.setClip( clipX, clipY, clipWidth, clipHeight );
}
//#endif
}
//#endif
//#ifndef polish.api.siemens-color-game-api
/**
* Set the frame sequence for this Sprite.
*
* All Sprites have a default sequence that displays the Sprites
* frames in order. This method allows for the creation of an
* arbitrary sequence using the available frames. The current
* index in the frame sequence is reset to zero as a result of
* calling this method.
* <p>
* The contents of the sequence array are copied when this method
* is called; thus, any changes made to the array after this method
* returns have no effect on the Sprite's frame sequence.
* <P>
* Passing in <code>null</code> causes the Sprite to revert to the
* default frame sequence.<p>
*
* @param sequence an array of integers, where each integer represents a frame index
* @throws ArrayIndexOutOfBoundsException if seq is non-null and any member of the array has a value less than 0 or greater than or equal to the number of frames as reported by getRawFrameCount()
* @throws IllegalArgumentException if the array has less than 1 element
* @see #nextFrame()
* @see #prevFrame()
* @see #setFrame(int)
* @see #getFrame()
*/
public void setFrameSequence(int[] sequence)
{
int frameIndex = 0;
this.frameSequence = null;
if (sequence != null) {
int[] newSequence = new int[ sequence.length ];
System.arraycopy( sequence, 0, newSequence, 0, sequence.length );
this.frameSequence = newSequence;
frameIndex = this.frameSequence[ 0 ];
}
this.frameSequenceIndex = 0;
this.column = frameIndex % this.numberOfColumns;
this.row = frameIndex / this.numberOfColumns;
}
//#endif
//#ifndef polish.api.siemens-color-game-api
/**
* Changes the Image containing the Sprite's frames.
* <p>
* Replaces the current raw frames of the Sprite with a new set of raw
* frames. See the constructor <A HREF="../../../../javax/microedition/lcdui/game/Sprite.html#Sprite(javax.microedition.lcdui.Image, int, int)"><CODE>Sprite(Image, int, int)</CODE></A> for
* information on how the frames are created from the image. The
* values returned by <A HREF="../../../../javax/microedition/lcdui/game/Layer.html#getWidth()"><CODE>Layer.getWidth()</CODE></A> and <A HREF="../../../../javax/microedition/lcdui/game/Layer.html#getHeight()"><CODE>Layer.getHeight()</CODE></A>
* will reflect the new frame width and frame height subject to the
* Sprite's current transform.
* <p>
* Changing the image for the Sprite could change the number of raw
* frames. If the new frame set has as many or more raw frames than the
* previous frame set, then:
* <ul>
* <li>The current frame will be unchanged
* <li>If a custom frame sequence has been defined (using
* <A HREF="../../../../javax/microedition/lcdui/game/Sprite.html#setFrameSequence(int[])"><CODE>setFrameSequence(int[])</CODE></A>), it will remain unchanged. If no
* custom frame sequence is defined (i.e. the default frame
* sequence
* is in use), the default frame sequence will be updated to
* be the default frame sequence for the new frame set. In other
* words, the new default frame sequence will include all of the
* frames from the new raw frame set, as if this new image had been
* used in the constructor.
* </ul>
* <p>
* If the new frame set has fewer frames than the previous frame set,
* then:
* <ul>
* <li>The current frame will be reset to entry 0
* <li>Any custom frame sequence will be discarded and the frame sequence
* will revert to the default frame sequence for the new frame
* set.
* </ul>
* <p>
* The reference point location is unchanged as a result of calling this
* method, both in terms of its defined location within the Sprite and its
* position in the painter's coordinate system. However, if the frame
* size is changed and the Sprite has been transformed, the position of
* the Sprite's upper-left corner may change such that the reference
* point remains stationary.
* <p>
* If the Sprite's frame size is changed by this method, the collision
* rectangle is reset to its default value (i.e. it is set to the new
* bounds of the untransformed Sprite).
* <p>
*
* @param image the Image to use for Sprite
* @param frameWidth the width in pixels of the individual raw frames
* @param frameHeight the height in pixels of the individual raw frames
* @throws NullPointerException if img is null
* @throws IllegalArgumentException if frameHeight or frameWidth is less than 1
* or if the image width is not an integer multiple of the frameWidth
* or if the image height is not an integer multiple of the frameHeight
*/
public void setImage( Image image, int frameWidth, int frameHeight)
{
this.image = image;
this.frameWidth = frameWidth;
this.frameHeight = frameHeight;
this.numberOfColumns = image.getWidth() / frameWidth;
int rows = image.getHeight() / frameHeight;
int oldRawFrameCount = this.rawFrameCount;
this.rawFrameCount = this.numberOfColumns * rows;
this.isSingleFrame = (this.rawFrameCount == 1);
if (this.rawFrameCount < oldRawFrameCount) {
this.frameSequenceIndex = 0;
// set default frame sequence:
this.frameSequence = null;
this.column = 0;
this.row = 0;
} else {
int frameIndex = (this.frameSequence == null) ? this.frameSequenceIndex : this.frameSequence[this.frameSequenceIndex];
this.column = frameIndex % this.numberOfColumns;
this.column = frameIndex / this.numberOfColumns;
}
this.collisionX = 0;
this.collisionY = 0;
this.collisionWidth = frameWidth;
this.collisionHeight = frameHeight;
// computes tranformed* values and reposition the sprite.
int oldRefX = this.transformedRefX, oldRefY = this.transformedRefY;
applyTransform();
this.xPosition += oldRefX - this.transformedRefX;
this.yPosition += oldRefY - this.transformedRefY;
//#ifdef polish.api.nokia-ui
//# if (!this.isSingleFrame) {
//# this.nokiaFrame = DirectUtils.createImage( frameWidth, frameHeight, 0x00FFFFFF );
//# Graphics g = this.nokiaFrame.getGraphics();
//# // when creating an transparent image, one must not "touch"
//# // that image with an ordinary Graphics-object --- instead
//# // ALWAYS a DirectGraphics-object needs to be used. Sigh!
//# //g.drawImage(this.image, 0, 0, Graphics.TOP | Graphics.LEFT );
//# DirectGraphics dg = DirectUtils.getDirectGraphics(g);
//# dg.drawImage(this.image, 0, 0, Graphics.TOP | Graphics.LEFT, 0 );
//# }
//# this.nokiaFrames = new Image[ this.rawFrameCount ];
//#endif
}
//#endif
/**
* Defines the Sprite's bounding rectangle that is used for collision
* detection purposes. This rectangle is specified relative to the
* un-transformed Sprite's upper-left corner and defines the area that is
* checked for collision detection. For pixel-level detection, only those
* pixels within the collision rectangle are checked.
*
* By default, a Sprite's collision rectangle is located at 0,0 as has the
* same dimensions as the Sprite. The collision rectangle may be
* specified to be larger or smaller than the default rectangle; if made
* larger, the pixels outside the bounds of the Sprite are considered to be
* transparent for pixel-level collision detection.
*
* @param leftX the horizontal location of the collision rectangle relative to the untransformed Sprite's left edge
* @param topY the vertical location of the collision rectangle relative to the untransformed Sprite's top edge
* @param cWidth the width of the collision rectangle
* @param cHeight the height of the collision rectangle
* @throws IllegalArgumentException if the specified width or height is less than 0
*/
public void defineCollisionRectangle(int leftX, int topY, int cWidth, int cHeight)
{
this.collisionX = leftX;
this.collisionY = topY;
this.collisionWidth = cWidth;
this.collisionHeight = cHeight;
this.applyTransform();
}
/*
* Applies the current transformation to the collision rectangle and reference pixel.
*
* Carefully look at the image in the "Sprite Transforms" section of the doc
* and report the number values of the symbols next to each sample image.
* We can notive the following:
* - "x = width - x" if transform is 2 or 3
* (that is, (transform & 2) != 0 and (transform & 4) == 0)
* - "y = height - y" if transform is 1 or 3
* (that is, (transform & 1) != 0 and (transform & 4) == 0)
* - width and height are switched if transform >= 4 (that is, (transform & 4) != 0)
* - "x = y" if transform is 4 or 6
* (that is, (transform & 1) == 0 and (transform & 4) != 0)
* - "y = x" if transform is 4 or 5
* (that is, (transform & 2) == 0 and (transform & 4) != 0)
* - "x = height - y" if transform is 5 or 7
* (that is, (transform & 1) != 0 and (transform & 4) != 0)
* - "y = width - x" if transform is 6 or 7
* (that is, (transform & 2) != 0 and (transform & 4) != 0)
*
* So:
* - if (transform & 1) == 0, use "y", else use "height - y"
* - if (transform & 2) == 0, use "x", else use "width - x"
* - if (transform & 4) != 0, switch width and height, and x and y
* (after you've applied the previous rules for x and y computation)
*/
private void applyTransform() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -