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.
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./****************************************************************************** * 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; } }
// 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