?? sprite.java
字號:
/* * @(#)Sprite.java 1.110 02/10/01 @(#) * * Copyright (c) 2002 Sun Microsystems, Inc. All rights reserved. * PROPRIETARY/CONFIDENTIAL * Use is subject to license terms. */package javax.microedition.lcdui.game;import javax.microedition.lcdui.Image;import javax.microedition.lcdui.Graphics;/** * A Sprite is a basic visual element that can be rendered with one of * several frames stored in an Image; different frames can be shown to * animate the Sprite. Several transforms such as flipping and rotation * can also be applied to a Sprite to further vary its appearance. As with * all Layer subclasses, a Sprite's location can be changed and it can also * be made visible or invisible. * <P> * <h3>Sprite Frames</h3> * The raw frames used to render a Sprite are provided in a single Image * object, which may be mutable or immutable. If more than one frame is used, * the Image is broken up into a series of equally-sized frames of a specified * width and height. As shown in the figure below, the same set of frames may * be stored in several different arrangements depending on what is the most * convenient for the game developer. * <br> * <center><img src="doc-files/frames.gif" width=777 height=402 * ALT="Sprite Frames"></center> * <br> * <p> * Each frame is assigned a unique index number. The frame located in the * upper-left corner of the Image is assigned an index of 0. The remaining * frames are then numbered consecutively in row-major order (indices are * assigned across the first row, then the second row, and so on). The method * {@link #getRawFrameCount()} returns the total number of raw frames. * <P> * <h3>Frame Sequence</h3> * A Sprite's frame sequence defines an ordered list of frames to be displayed. * The default frame sequence mirrors the list of available frames, so * there is a direct mapping between the sequence index and the corresponding * frame index. This also means that the length of the default frame sequence * is equal to the number of raw frames. For example, if a Sprite has 4 * frames, its default frame sequence is {0, 1, 2, 3}. * <center><img src="doc-files/defaultSequence.gif" width=182 height=269 * ALT="Default Frame Sequence"></center> * <P> * The developer must manually switch the current frame in the frame sequence. * This may be accomplished by calling {@link #setFrame}, * {@link #prevFrame()}, or {@link #nextFrame()}. Note that these methods * always operate on the sequence index, they do not operate on frame indices; * however, if the default frame sequence is used, then the sequence indices * and the frame indices are interchangeable. * <P> * If desired, an arbitrary frame sequence may be defined for a Sprite. * The frame sequence must contain at least one element, and each element must * reference a valid frame index. By defining a new frame sequence, the * developer can conveniently display the Sprite's frames in any order * desired; frames may be repeated, omitted, shown in reverse order, etc. * <P> * For example, the diagram below shows how a special frame sequence might be * used to animate a mosquito. The frame sequence is designed so that the * mosquito flaps its wings three times and then pauses for a moment before * the cycle is repeated. * <center><img src="doc-files/specialSequence.gif" width=346 height=510 * ALT="Special Frame Sequence"></center> * By calling {@link #nextFrame} each time the display is updated, the * resulting animation would like this: * <br> * <center><img src="doc-files/sequenceDemo.gif" width=96 height=36></center> * <P> * <h3>Reference Pixel</h3> * Being a subclass of Layer, Sprite inherits various methods for setting and * retrieving its location such as {@link #setPosition setPosition(x,y)}, * {@link #getX getX()}, and {@link #getY getY()}. These methods all define * position in terms of the upper-left corner of the Sprite's visual bounds; * however, in some cases, it is more convenient to define the Sprite's position * in terms of an arbitrary pixel within its frame, especially if transforms * are applied to the Sprite. * <P> * Therefore, Sprite includes the concept of a <em>reference pixel</em>. * The reference pixel is defined by specifying its location in the * Sprite's untransformed frame using * {@link #defineReferencePixel defineReferencePixel(x,y)}. * By default, the reference pixel is defined to be the pixel at (0,0) * in the frame. If desired, the reference pixel may be defined outside * of the frame's bounds. * <p> * In this example, the reference pixel is defined to be the pixel that * the monkey appears to be hanging from: * <p> * <center><img src="doc-files/refpixel.gif" width=304 height=199 * ALT="Defining The Reference Pixel"></center> * <p> * {@link #getRefPixelX getRefPixelX()} and {@link #getRefPixelY getRefPixelY()} * can be used to query the location of the reference pixel in the painter's * coordinate system. The developer can also use * {@link #setRefPixelPosition setRefPixelPosition(x,y)} to position the Sprite * so that reference pixel appears at a specific location in the painter's * coordinate system. These methods automatically account for any transforms * applied to the Sprite. * <p> * In this example, the reference pixel's position is set to a point at the end * of a tree branch; the Sprite's location changes so that the reference pixel * appears at this point and the monkey appears to be hanging from the branch: * <p> * <center><img src="doc-files/setrefposition.gif" width=332 height=350 * ALT="Setting The Reference Pixel Position"></center> * <p> * <a name="transforms"></a> * <h3>Sprite Transforms</h3> * Various transforms can be applied to a Sprite. The available transforms * include rotations in multiples of 90 degrees, and mirrored (about * the vertical axis) versions of each of the rotations. A Sprite's transform * is set by calling {@link #setTransform setTransform(transform)}. * <p> * <center><img src="doc-files/transforms.gif" width=355 height=575 * ALT="Transforms"></center> * <br> * When a transform is applied, the Sprite is automatically repositioned * such that the reference pixel appears stationary in the painter's * coordinate system. Thus, the reference pixel effectively becomes the * center of the transform operation. Since the reference pixel does not * move, the values returned by {@link #getRefPixelX()} and * {@link #getRefPixelY()} remain the same; however, the values returned by * {@link #getX getX()} and {@link #getY getY()} may change to reflect the * movement of the Sprite's upper-left corner. * <p> * Referring to the monkey example once again, the position of the * reference pixel remains at (48, 22) when a 90 degree rotation * is applied, thereby making it appear as if the monkey is swinging * from the branch: * <p> * <center><img src="doc-files/transcenter.gif" width=333 height=350 * ALT="Transform Center"></center> * <p> * <h3>Sprite Drawing</h3> * Sprites can be drawn at any time using the {@link #paint(Graphics)} method. * The Sprite will be drawn on the Graphics object according to the current * state information maintained by the Sprite (i.e. position, frame, * visibility). Erasing the Sprite is always the responsibility of code * outside the Sprite class.<p> * <p> * Sprites can be implemented using whatever techniques a manufacturers * wishes to use (e.g hardware acceleration may be used for all Sprites, for * certain sizes of Sprites, or not at all). * <p> * For some platforms, certain Sprite sizes may be more efficient than others; * manufacturers may choose to provide developers with information about * device-specific characteristics such as these. * <p> * @since MIDP 2.0 */public class Sprite extends Layer{ // ----- definitions for the various transformations possible ----- /** * No transform is applied to the Sprite. * This constant has a value of <code>0</code>. */ public static final int TRANS_NONE = 0; /** * Causes the Sprite to appear rotated clockwise by 90 degrees. * This constant has a value of <code>5</code>. */ public static final int TRANS_ROT90 = 5; /** * Causes the Sprite to appear rotated clockwise by 180 degrees. * This constant has a value of <code>3</code>. */ public static final int TRANS_ROT180 = 3; /** * Causes the Sprite to appear rotated clockwise by 270 degrees. * This constant has a value of <code>6</code>. */ public static final int TRANS_ROT270 = 6; /** * Causes the Sprite to appear reflected about its vertical * center. * This constant has a value of <code>2</code>. */ public static final int TRANS_MIRROR = 2; /** * Causes the Sprite to appear reflected about its vertical * center and then rotated clockwise by 90 degrees. * This constant has a value of <code>7</code>. */ public static final int TRANS_MIRROR_ROT90 = 7; /** * Causes the Sprite to appear reflected about its vertical * center and then rotated clockwise by 180 degrees. * This constant has a value of <code>1</code>. */ public static final int TRANS_MIRROR_ROT180 = 1; /** * Causes the Sprite to appear reflected about its vertical * center and then rotated clockwise by 270 degrees. * This constant has a value of <code>4</code>. */ public static final int TRANS_MIRROR_ROT270 = 4; // ----- Constructors ----- /** * Creates a new non-animated Sprite using the provided Image. * This constructor is functionally equivalent to calling * <code>new Sprite(image, image.getWidth(), image.getHeight())</code> * <p> * By default, the Sprite is visible and its upper-left * corner is positioned at (0,0) in the painter's coordinate system. * <br> * @param image the <code>Image</code> to use as the single frame * for the </code>Sprite * @throws NullPointerException if <code>img</code> is <code>null</code> */ public Sprite(Image image) { super(image.getWidth(), image.getHeight()); initializeFrames(image, image.getWidth(), image.getHeight(), false); // initialize collision rectangle initCollisionRectBounds(); // current transformation is TRANS_NONE this.setTransformImpl(TRANS_NONE); } /** * Creates a new animated Sprite using frames contained in * the provided Image. The frames must be equally sized, with the * dimensions specified by <code>frameWidth</code> and * <code>frameHeight</code>. They may be laid out in the image * horizontally, vertically, or as a grid. The width of the source * image must be an integer multiple of the frame width, and the height * of the source image must be an integer multiple of the frame height. * The values returned by {@link Layer#getWidth} and * {@link Layer#getHeight} will reflect the frame width and frame height * subject to the Sprite's current transform. * <p> * Sprites have a default frame sequence corresponding to the raw frame * numbers, starting with frame 0. The frame sequence may be modified * with {@link #setFrameSequence(int[])}. * <p> * By default, the Sprite is visible and its upper-left corner is * positioned at (0,0) in the painter's coordinate system. * <p> * @param image the <code>Image</code> to use for <code>Sprite</code> * @param frameWidth the <code>width</code>, in pixels, of the * individual raw frames * @param frameHeight the <code>height</code>, in pixels, of the * individual raw frames * @throws NullPointerException if <code>img</code> is <code>null</code> * @throws IllegalArgumentException if <code>frameHeight</code> or * <code>frameWidth</code> is less than <code>1</code> * @throws IllegalArgumentException if the <code>image</code> * width is not an integer multiple of the <code>frameWidth</code> * @throws IllegalArgumentException if the <code>image</code> * height is not an integer multiple of the <code>frameHeight</code> */ public Sprite(Image image, int frameWidth, int frameHeight) { super(frameWidth, frameHeight); // if img is null img.getWidth() will throw NullPointerException if ((frameWidth < 1 || frameHeight < 1) || ((image.getWidth() % frameWidth) != 0) || ((image.getHeight() % frameHeight) != 0)) { throw new IllegalArgumentException(); } // construct the array of images that // we use as "frames" for the sprite. // use default frame , sequence index = 0 initializeFrames(image, frameWidth, frameHeight, false); // initialize collision rectangle initCollisionRectBounds(); // current transformation is TRANS_NONE this.setTransformImpl(TRANS_NONE); } /** * Creates a new Sprite from another Sprite. <p> * * All instance attributes (raw frames, position, frame sequence, current * frame, reference point, collision rectangle, transform, and visibility) * of the source Sprite are duplicated in the new Sprite. * * @param s the <code>Sprite</code> to create a copy of * @throws NullPointerException if <code>s</code> is <code>null</code> * */ public Sprite(Sprite s) { super(s != null ? s.getWidth() : 0, s != null ? s.getHeight() : 0); if (s == null) { throw new NullPointerException(); } this.sourceImage = Image.createImage(s.sourceImage); this.numberFrames = s.numberFrames; this.frameCoordsX = new int[this.numberFrames]; this.frameCoordsY = new int[this.numberFrames]; System.arraycopy(s.frameCoordsX, 0, this.frameCoordsX, 0, s.getRawFrameCount()); System.arraycopy(s.frameCoordsY, 0, this.frameCoordsY, 0, s.getRawFrameCount()); this.x = s.getX(); this.y = s.getY(); // these fields are set by defining a reference point this.dRefX = s.dRefX; this.dRefY = s.dRefY; // these fields are set when defining a collision rectangle this.collisionRectX = s.collisionRectX; this.collisionRectY = s.collisionRectY; this.collisionRectWidth = s.collisionRectWidth; this.collisionRectHeight = s.collisionRectHeight; // these fields are set when creating a Sprite from an Image this.srcFrameWidth = s.srcFrameWidth; this.srcFrameHeight = s.srcFrameHeight; // the above fields are used in setTransform() // which is why we set them first, then call setTransformImpl() // to set up internally used data structures. setTransformImpl(s.t_currentTransformation); this.setVisible(s.isVisible()); this.frameSequence = new int[s.getFrameSequenceLength()]; this.setFrameSequence(s.frameSequence); this.setFrame(s.getFrame()); this.setRefPixelPosition(s.getRefPixelX(), s.getRefPixelY()); } // ----- public methods ----- /** * Defines the reference pixel for this Sprite. The pixel is * defined by its location relative to the upper-left corner of * the Sprite's un-transformed frame, and it may lay outside of * the frame's bounds. * <p> * When a transformation is applied, the reference pixel is * defined relative to the Sprite's initial upper-left corner
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -