/*
* @(#)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 com.amaker.game;
import android.graphics.Bitmap;
import android.graphics.Canvas;
/**
* A Sprite is a basic visual element that can be rendered with one of
* several frames stored in an Bitmap; 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 Bitmap
* object, which may be mutable or immutable. If more than one frame is used,
* the Bitmap 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 Bitmap 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(Canvas)} method.
* The Sprite will be drawn on the Canvas 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 Sp