📄 imageset.java
字号:
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Graphics;
import java.io.IOException;
/**
* A container for sets of image frames; typically sprites. A single set
* is made up of one or more states. Each state represents an animation sequence
* including Image objects for the frames, animation timing and frame
* dimensions. An example use of this class would be to animate a little dude.
* If he had two states of existence, standing (which has short breathing
* animation) and walking (which has a much longer animation). This would be
* implemented by creating an ImageSet object and then adding two states, each
* with their own Image array for all the animation frames (use the static
* methods at the end of this class to load a clipped file image and then
* extract the image frame array from it). You can then use a Sprite class
* associated with this ImageSet to draw the character to the screen as well as
* keep track of animation frames.
* @author Martin J. Wells
*/
public class ImageSet
{
private int totalStates; // incremented by addState method only
private Image[][] stateFrames;
private int[] stateAnimTime, stateFrameWidth, stateFrameHeight;
/**
* Constructor for a new image. You will need to call addState to add the
* various states (and their associated images and animation data) before
* the object is really usable.
* @param numStates The initial number of states (since ImageSet uses an
* array internally (for speed) it costs a lot to expand the internal size
* beyond this number -- typically you'll know the exact number of states
* beforehand anyway. If not, the addState code will expand the array when
* required.
*/
public ImageSet(int numStates)
{
stateAnimTime = new int[numStates];
stateFrameWidth = new int[numStates];
stateFrameHeight = new int[numStates];
stateFrames = new Image[numStates][];
}
/**
* Adds a new state to the ImageSet including an array of images and the
* number of milliseconds to animate the entire state (NOT each frame). If
* this is not an animating set then just use 0 for the animtime. To animate
* you will need to create a Sprite object linked to this ImageSet.
* @param frames An array of javax.microedition.lcdui.Image objects.
* @param animTime The number of milliseconds delay to animate ALL frames.
*/
public final void addState(Image frames[], int animTime)
{
int state = totalStates++;
if (state >= stateFrames.length)
{
// expand the number of states
stateAnimTime = Tools.expandArray(stateAnimTime, 1);
stateFrameWidth = Tools.expandArray(stateFrameWidth, 1);
stateFrameHeight = Tools.expandArray(stateFrameHeight, 1);
stateFrames = Tools.expandArray(stateFrames, 1);
}
stateAnimTime[state] = animTime;
stateFrameWidth[state] = frames[0].getWidth();
stateFrameHeight[state] = frames[0].getHeight();
stateFrames[state] = frames;
}
/**
* Gets the number of frames for a particular state in the ImageSet.
* @param state The state you want to know about.
* @return The number of frames in that state.
*/
public final int getTotalFrames(int state)
{
return stateFrames[state].length;
}
/**
* Gets the total amount time to animate all the frames of a given state.
* Note this is not the delay per frame.
* @param state The state you want to know about.
* @return The animation delay (in milliseconds) corresponding to the given
* state.
*/
public final int getAnimTime(int state)
{
return stateAnimTime[state];
}
/**
* Gets the amount of time to spend on each frame of a set to animate it.
* This is just a convenience method that returns the animation time for
* a state divided by the total number of frames.
* @param state The state you want to know about.
* @return The number of milliseconds delay for each frame of a given state.
*/
public final int getAnimTimePerFrame(int state)
{
return stateAnimTime[state] / stateFrames[state].length;
}
/**
* Draws a specific frame of this sprite onto a graphics context.
* @param target The target graphics context to draw on.
* @param state The state corresponding to the frame being drawn.
* @param frame The number of the frame you want to draw.
* @param targetX The x-position to draw the frame.
* @param targetY The y-position to draw the frame.
*/
public final void draw(Graphics target, int state, int frame, int targetX, int targetY)
{
if (stateFrames[state][frame] != null)
target.drawImage(stateFrames[state][frame],
targetX, targetY, Tools.GRAPHICS_TOP_LEFT);
}
/**
* Extract an Image corresponding to a particular state and frame.
* @param state The state you're after.
* @param frame The frame you're after.
* @return The image corresponding to the given frame in the given state.
*/
public final Image getFrame(int state, int frame)
{
return stateFrames[state][frame];
}
//
// STATIC IMAGE TOOLS
//
/**
* Static utility method to loap up a portion of an image from a file. Note
* that the file must be in your JAR (or otherwise accessible) by the MID in
* order to be loaded.
* @param filename The name of the resource file to load.
* @param originX The starting x position of the file image you want to load.
* @param originY The starting y position of the file image you want to load.
* @param width The width of the image you want to clip to.
* @param height The height of the image you want to clip to.
* @return A new Image object containing only the rectangle of originX,
* originY, width and depth.
*/
public final static Image loadClippedImage(String filename, int originX, int originY, int width,
int height)
{
try
{
// load full image from file and create a mutable version
Image fileImage = Image.createImage(filename);
// use the getImageRegion method to extract out only the bit we want.
return getImageRegion(fileImage, originX, originY, width, height);
}
catch (IOException ioe)
{
System.out.println("can't load file: " + filename);
return null;
}
}
/**
* Static utility method to loap up a portion of an image from a file. Note
* that the file must be in your JAR (or otherwise accessible) by the MID in
* order to be loaded. The width and height of the portion is assumed to be
* the size of the file image.
* @param filename The name of the resource file to load.
* @param originX The starting x position of the file image you want to load.
* @param originY The starting y position of the file image you want to load.
* @return A new Image object containing only the rectangle starting at
* originX, originY.
*/
public final static Image loadClippedImage(String filename, int originX, int originY)
{
try
{
// load full image from file and create a mutable version
Image fileImage = Image.createImage(filename);
// shortcut out of here so we can avoid creating another image if they
// are just using this method to load an image normally (no clipping).
if (originX == 0 && originY == 0) return fileImage;
// use the getImageRegion method to extract out only the bit we want.
return getImageRegion(fileImage, originX, originY, fileImage.getWidth(), fileImage.getHeight());
}
catch (IOException ioe)
{
System.out.println("can't load file: " + filename);
return null;
}
}
/**
* Extracts a portion of an image using clipping.
* @param source The source image.
* @param x The starting x position of the clipping rectangle.
* @param y The starting y position of the clipping rectangle.
* @param width The width of the clipping rectangle.
* @param height The height of the clipping rectangle.
* @return A new Image object containing only the portion of the image
* withing the x, y, width, height rectangle.
*/
public final static Image getImageRegion(Image source, int x, int y, int width, int height)
{
// create a placeholder for our resulting image region
Image result = Image.createImage(width, height);
if (x + width > source.getWidth() || y + height > source.getHeight())
System.out.println("Warning: attempting extract using (" +
x + "," + y + "," + width + "," + height + ") when image is " +
"(" + source.getWidth() + "," + source.getHeight() + ")");
// draw the image, offset by the region starting position
result.getGraphics().drawImage(source, -x, -y, Tools.GRAPHICS_TOP_LEFT);
return result;
}
/**
* Gets an array of images by breaking a larger image into smaller frames.
* @param sourceImage The image to extract the frames from.
* @param sourceX The starting x position in the source image to use.
* @param sourceY The starting y position in the source image to use.
* @param framesWide The number of frames across the source image to extract.
* @param framesHigh The number of frames down the source image to extract.
* @param frameWidth The width of each of those frames.
* @param frameHeight The height of each of those frames.
* @return An array containing an image for each frame.
*/
public final static Image[] extractFrames(Image sourceImage, int sourceX,
int sourceY,
int framesWide, int framesHigh,
int frameWidth, int frameHeight)
{
// extract all the frames from the source image
Image[] frames = new Image[framesWide * framesHigh];
int frameCount = 0;
for (int fy = 0; fy < framesHigh; fy++)
for (int fx = 0; fx < framesWide; fx++)
frames[frameCount++] =
getImageRegion(sourceImage, sourceX + (fx * frameWidth),
sourceY + (fy * frameHeight),
frameWidth, frameHeight);
return frames;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -