Extending the Sprite class
In the conclusion of the previous article, I said you could do really interesting thing if you understand the basic Sprite class well enough. Let's make a small sample on this. Up to now all bunnies look the same, we are going to add a "panic" bunny to the sprite list.
How does a "panic" bunny look like ? It face will turn red and it will be moving restlessly. Let make a reddish sprite first. How to make a sprite looks more reddish ? It is simple. For every pixel, we just reduce the green and blue component by half. This effectively increases the weighting of the red component in the image. And it will look reddish.
We don't have to rewrite the Sprite class. All we need is to extend it.
/******************************************************************************
* File : ReddishSprite.java
* Author : http://java.macteki.com/
* Description :
* A sprite which is more "reddish" than normal
* Tested with : JDK 1.6
******************************************************************************/
import java.awt.image.BufferedImage;
class ReddishSprite extends Sprite
{
public ReddishSprite(BufferedImage img)
{
super(img);
this.image = makeReddishImage(this.image);
}
// make it reddish
private BufferedImage makeReddishImage(BufferedImage tmpImage)
{
int h=tmpImage.getHeight(null);
int w=tmpImage.getWidth(null);
BufferedImage resultImage=new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
for (int y=0;y<h;y++)
for (int x=0;x<w;x++)
{
int color=tmpImage.getRGB(x,y);
// get A,R,G,B value
int A=color & 0xff000000;
int R=(color & 0x00ff0000) >>> 16;
int G=(color & 0x0000ff00) >>> 8;
int B=color & 0x000000ff;
// reduce the green and blue component by half
G/=2;
B/=2;
// packed back to a color value
color = A | (R<<16) | (G<<8) | B;
resultImage.setRGB(x,y,color);
}
return resultImage;
}
}
Next, we modify the method initSpriteList() in SpriteManager.java. Originally it just adds 50 bunnies to the list, now it adds one more "panic" bunny to the list.
// add 50 bunnies sprites to the sprite list
public void initSpriteList() throws Exception
{
BufferedImage image = javax.imageio.ImageIO.read(new java.io.File("bunny_sprite.png"));
java.util.Random random=new java.util.Random();
for (int i=0;i<50;i++)
{
Sprite sprite=new Sprite(image);
sprite.x=50+16*random.nextInt(20);
sprite.y=250+4*random.nextInt(20);
sprite.relativeSpeed=1+(i%3); // range from 1 to 4
sprite.gestureWait=8; // change it to 1 to see what happen
spriteList.add(sprite);
}
// add a panic bunny
ReddishSprite redSprite=new ReddishSprite(image);
redSprite.x=0;
redSprite.y=250;
redSprite.relativeSpeed=1; // full speed (look more panic)
redSprite.gestureWait=2; // fast rhythm (look more restless)
spriteList.add(redSprite); // add to the sprite list just like the normal sprite
}
Adding a Boss
To make thing more interesting, we extend the Sprite class again and make a "boss" bunny. It is double in size and it it moving slower. It also has the ability to fly in the sky.
/******************************************************************************
* File : BigSprite.java
* Author : http://java.macteki.com/
* Description :
* A "Boss" Sprite
* Tested with : JDK 1.6
******************************************************************************/
import java.awt.image.BufferedImage;
class BigSprite extends Sprite
{
// pre-defined source regions
private int[][][] frameRect = // [direction][gesture][x,y,w,h]
{
{{ 0, 0,64,64}, {64, 0,64,64}, {128, 0,64,64}, {192, 0,64,64} }, // left
{{ 0, 64,64,64}, {64, 64,64,64}, {128, 64,64,64}, {192, 64,64,64} }, // right
{{ 0,128,64,64}, {64,128,64,64}, {128,128,64,64}, {192,128,64,64} }, // down
{{ 0,192,64,64}, {64,192,64,64}, {128,192,64,64}, {192,192,64,64} } // up
};
public int[] getImageBound(int direction, int gesture)
{
return frameRect[direction][gesture];
}
public BigSprite(java.awt.image.BufferedImage img)
{
super(img);
this.image = makeBlue(this.image);
this.image = makeDoubleSizeImage(this.image);
}
// make it blue
private BufferedImage makeBlue(BufferedImage tmpImage)
{
int h=tmpImage.getHeight(null);
int w=tmpImage.getWidth(null);
BufferedImage resultImage=new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
for (int y=0;y<h;y++)
for (int x=0;x<w;x++)
{
int color=tmpImage.getRGB(x,y);
// get A,R,G,B value
int A=color & 0xff000000;
int R=(color & 0x00ff0000) >>> 16;
int G=(color & 0x0000ff00) >>> 8;
int B=color & 0x000000ff;
// reduce the red and green component by half
// double the blue component
R/=2; G/=2; B*=2;
// packed back to a color value
color = A | (R<<16) | (G<<8) | B;
resultImage.setRGB(x,y,color);
}
return resultImage;
}
// scale up the image by a factor of 2
private BufferedImage makeDoubleSizeImage(BufferedImage tmpImage)
{
int h=tmpImage.getHeight(null);
int w=tmpImage.getWidth(null);
BufferedImage resultImage=new BufferedImage(w*2,h*2,BufferedImage.TYPE_INT_ARGB);
java.awt.Graphics2D gr=(java.awt.Graphics2D) resultImage.getGraphics();
java.awt.geom.AffineTransform transform=gr.getTransform();
transform.scale(2,2);
gr.setTransform(transform);
gr.drawImage(tmpImage,0,0,null);
return resultImage;
}
// Boss Sprite is flying in the sky
public int[] getActiveRegion()
{
// upperLeft corner(x,y), lowerRight corner(x,y)
return new int[]{ 0,0,750,150}; // upper area of the screen.
}
}
Of course we need to modify initSpriteList() again, add the boss sprite code just below the panic sprite code.
// add a panic bunny
ReddishSprite redSprite=new ReddishSprite(image);
redSprite.x=0;
redSprite.y=250;
redSprite.relativeSpeed=1; // full speed (look more panic)
redSprite.gestureWait=2; // fast rhythm (look more restless)
spriteList.add(redSprite); // add to sprite list just like a normal sprite
// add a Boss Bunny
BigSprite bossSprite=new BigSprite(image);
bossSprite.x=50;
bossSprite.y=100; // boss is flying in the sky
bossSprite.relativeSpeed=8; // boss move much slower due to its size
bossSprite.gestureWait=16; // boss is more reluctant to change gesture
spriteList.add(bossSprite); // add to sprite list just like a normal sprite
Result
If you are doing everything correctly, you should see a flying boss and a panic(red) bunny inside the crowd of the normal bunnies.Acknowledgement
- bunny_sprite.png is provided by Moosader :
http://moosader.deviantart.com/art/Public-domain-bunny-sprite-151156167
- background.jpg is provided by Jesccia Crabtree
http://www.jessicacrabtree.com/journal1/public-domain-nature-photos
Next
This is the end of the series. If you like it, post a comment. If you don't like it, also post a comment. Right now I am thinking of the next programming topic. So I cannot tell what is going next. Anyway, I would try hard to update this site frequently. If you'd like to propose a topic, you can leave a comments in this blog under any articles. I may share something on it if I have the necessary skills and knowledges.

No comments:
Post a Comment