6-Sprite animation with Android

Source: Internet
Author: User
Tags gety

If you followed the series so far we are pretty knowledgable in handling touches, displaying images and moving them around.

So far, we have known how to process touch time, draw pictures, and move them.

But a moving image it's a pretty dull sight as it looks really fake and amateurish. to give the characters some life we will need to do more than that. that is what animation is all about. A rock is an inanimate object and even if it is thrown, it doesn' t
Change its shape. A human on the other hand, is very animated. Try throwing one and you'll see twitching limbs and even screams in the air.

However, moving images seem silly. We need to do more to give the role new vitality. That is the function of animation. A rock is a non-moving object. Even if it is thrown out, it will not change the shape. Relatively speaking, a person will move, and a person will throw his arm and even shout.

Let's just resort to examining walking which is pretty complex in its own. imagine a human crossing your way (just in 2d ). you'll notice different displays of the body. left foot in front, right hand in front while the oposite limbs are behind. this slowly
Changes so the left foot remains behind while the right progresses along with the body. but at one point the cycle repeats. if you don't close your eyes you see the person progressing smoothly. if you close your eyes and keep them closed for a bit and open
Them again the person already went on and is in a different position. Try blinking quite rapidly and you will see something like the old black and white comedies. That is low frame rate. More on FPS
Here.

 

Actually we do want a low frame rate walking for this tutorial, just like this.



The role above looks a little tricky. It was found from Monkey Island, and she was played by Eline Marley.
This is called an genie. It is a simple 2D image or animation.

In order to do the above action, we need to walk every frame

This is a 150-pixel image with 30 pixels per frame.

Look, it explains better.

To display the above animation, We need to load each frame into an independent image and display them at regular intervals. Or we can load the entire image and use the cutting method provided by Android to display the corresponding frame.
This is a little troublesome. We know that we have five frames, each of which is 30 pixels. We define a rectangle. Its width is one frame, and its height is the height of the image.

Shows how I cut the first two frames. Finish the rest by yourself.

Let's start our project. We need the knowledge of the previous chapters, mainly game loop and graphic display content.

We need an object to do the action. We use elastic, so I created the class of Elastic. java.

01 public class ElaineAnimated {  02    03     private static final String TAG = ElaineAnimated.class.getSimpleName();  04    05     private Bitmap bitmap;      // the animation sequence  06     private Rect sourceRect;    // the rectangle to be drawn from the animation bitmap  07     private int frameNr;        // number of frames in animation  08     private int currentFrame;   // the current frame  09     private long frameTicker;   // the time of the last frame update  10     private int framePeriod;    // milliseconds between each frame (1000/fps)  11    12     private int spriteWidth;    // the width of the sprite to calculate the cut out rectangle  13     private int spriteHeight;   // the height of the sprite  14    15     private int x;              // the X coordinate of the object (top left of the image)  16     private int y;              // the Y coordinate of the object (top left of the image)  17    18 } 

Private attributes should be promoted on time

  • Bitmap is a graph that contains all frames. The second image in this article
  • Sourcerect is the selected rectangle, which is a small blue window in the image below. The rectangle moves one frame at a time.
  • Frameticker is the Java timestamp of the latest frame transformation in the walking sequence. Note that this is not the FPs of the game, but the FPs of the walking. If we want to finish the process in one second, five frames are required, because our image has five frames, we need 30 frames to get a smooth animation, but this is not the focus.
  • Frameperiod indicates the time needed to display a frame. If the loop is completed in one second, the value is 0.2 seconds, and each frame shows 0.2 seconds.

The constructor is as follows:

01 public ElaineAnimated(Bitmap bitmap, int x, int y, int width, int height, int fps, int frameCount) {  02         this.bitmap = bitmap;  03         this.x = x;  04         this.y = y;  05         currentFrame = 0;  06         frameNr = frameCount;  07         spriteWidth = bitmap.getWidth() / frameCount;  08         spriteHeight = bitmap.getHeight();  09         sourceRect = new Rect(0, 0, spriteWidth, spriteHeight);  10         framePeriod = 1000 / fps;  11         frameTicker = 0l;  12     } 

 

I'm assuming that the frames are the same width so I calculate the width of the rectangle by dividing the width of the image with the number of frames. I also pass in
fpsWhich is again, the frames per second of the walk cycle not the game FPS.

 

Elaine will haveupdateMethod of her own as she is an animated object and she needs to look good and she is in charge of dragging her feet. because the period of the game update cycle and Elaine's one might be (in this case is) Different
We pass the actual game time as a variable so we know when we need to display the next frame.
For example the game runs very fast and the update is called every 20 milliseconds and we need to update the frame every 200 ms, then the progression of the frame will happen at every 10th game update.

Here's the code:

01 public void update(long gameTime) {  02     if (gameTime > frameTicker + framePeriod) {  03         frameTicker = gameTime;  04         // increment the frame  05         currentFrame++;  06         if (currentFrame >= frameNr) {  07             currentFrame = 0;  08         }  09     }  10     // define the rectangle to cut out sprite  11     this.sourceRect.left = currentFrame * spriteWidth;  12     this.sourceRect.right = this.sourceRect.left + spriteWidth;  13 } 

The update is called from the main game Panel (check previous entries how that works). This is the update method of
MainGamePanelClass.

1 public void update() {  2     elaine.update(System.currentTimeMillis());  3 } 

 

TheupdateMethod is simple (Elaine's). It increments the frame if the passed in time (which is the system time when the update method was called) is greater than the last time (frameTicker) The frame was updated plus the period
Of the next update.
If the next frame is beyond the last, we reset the cycle.

After all that area from which the image will be cut out is defined as
sourceRect
.
That's it. Now let's go on to display it.

1 public void draw(Canvas canvas) {  2         // where to draw the sprite  3         Rect destRect = new Rect(getX(), getY(), getX() + spriteWidth, getY() + spriteHeight);  4         canvas.drawBitmap(bitmap, sourceRect, destRect, null);  5     } 

At is all. We set the destination rectangle as to where to draw the cut out image. It is at elasticity's position (X and Y set in the constructor ).

 
1 canvas.drawBitmap(bitmap, sourceRect, destRect, null); 

Tells android to cut out the image definedsourceRectFrom the image contained in
bitmapAnd draw it into the rectangle on the canvas defined
destRect
.

ThedrawIs called from the game panel's render method triggered by the game loop (check previous entries ).

TheMainGamePanel.javaDiffers slightly from the one from previous chapters. I got rid of all the droidz and added just Eline.

01 private ElaineAnimated elaine;  02    03     public MainGamePanel(Context context) {  04         //* ... removed ... */  05    06         // create Elaine and load bitmap  07         elaine = new ElaineAnimated(  08                 BitmapFactory.decodeResource(getResources(), R.drawable.walk_elaine)  09                 , 10, 50    // initial position  10                 , 30, 47    // width and height of sprite  11                 , 5, 5);    // FPS and number of frames in the animation  12    13         // create the game loop thread  14         thread = new MainThread(getHolder(), this);  15    16         //* ... removed ... */  17     } 

 

Elasticity is instantiated in the Panel's constructor and is given an initial positon of (x = 10, y = 50 ). I pass in the width and the height of the sprite too but that is ignored anyway, but you can modify the code.
The FPS is very important and the number of frames too. FPS says how many frames are to be shown in one second. The last parameter is the number of frames in the cycle.

The thread and activity classes haven' t changed at all. You can find them in the download as they are quite long to be pasted. The image is named
walk_elaine.pngAnd it was copied/res/drawable-mdpi/So android can pick it up automatically.

If you run the application you shocould be seeing elastine swimming walking cycles in one place. We shocould have used jumping as that can be med in one place but you get the idea.

 

Elaine walking

 

Enhancement

To make some neat additions modify eloine'sdrawMethod so it displays the original image containing the sprites from which the frames are extracted.

1 public void draw(Canvas canvas) {  2     // where to draw the sprite  3     Rect destRect = new Rect(getX(), getY(), getX() + spriteWidth, getY() + spriteHeight);  4     canvas.drawBitmap(bitmap, sourceRect, destRect, null);  5     canvas.drawBitmap(bitmap, 20, 150, null);  6     Paint paint = new Paint();  7     paint.setARGB(50, 0, 255, 0);  8     canvas.drawRect(20 + (currentFrame * destRect.width()), 150, 20 + (currentFrame * destRect.width()) + destRect.width(), 150 + destRect.height(),  paint);  9 } 

 

This just displays the image at (20,150) and creates a new paint object so we can paint over the current frame on the original image.
The methodsetARGBCreates a semi-transparent green paint. The first value is
50Which means it's 75% transparent.0Is completely transparentwhile
255Is fully opaque.
After everything was drawn we paint a rectangle of the size of a frame onto the original image so you see which frame is being displayed in the motion.

 

Walking with current frame painted

 

That's it. Run it and you have your first sprite animation.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.