Wednesday, May 3, 2017

How to load sprite sheet with 5 rows and 5 columns top view in android?

Leave a Comment

I have a sprite sheet of 612x864 dimension with 5 rows and 5 columns .My problem is how can I load it and animate it? I want to move the cat sprite in y-axis only .I've already try but my code is not working properly. Here is my code.

In GameView.java

import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.view.SurfaceHolder; import android.view.SurfaceView;  public class GameView extends SurfaceView { private Bitmap bmp; private SurfaceHolder holder; private GameLoopThread gameLoopThread; private Sprite sprite;  public GameView(Context context) {     super(context);     gameLoopThread = new GameLoopThread(this);     holder = getHolder();     holder.addCallback(new SurfaceHolder.Callback() {          @Override         public void surfaceDestroyed(SurfaceHolder holder) {             boolean retry = true;             gameLoopThread.setRunning(false);             while (retry) {                 try {                     gameLoopThread.join();                     retry = false;                 } catch (InterruptedException e) {                 }             }         }          @Override         public void surfaceCreated(SurfaceHolder holder) {             gameLoopThread.setRunning(true);             gameLoopThread.start();         }          @Override         public void surfaceChanged(SurfaceHolder holder, int format,                                    int width, int height) {         }     });     bmp = BitmapFactory.decodeResource(getResources(), R.drawable.catsprite);     sprite = new Sprite(this,bmp); }  @Override protected void onDraw(Canvas canvas) {     canvas.drawColor(Color.BLACK);     sprite.onDraw(canvas); } } 

GameLoopThread.java

import android.graphics.Canvas;  public class GameLoopThread extends Thread { static final long FPS = 10; private GameView view; private boolean running = false;  public GameLoopThread(GameView view) {     this.view = view; }  public void setRunning(boolean run) {     running = run; }  @Override public void run() {     long ticksPS = 1000 / FPS;     long startTime;     long sleepTime;     while (running) {         Canvas c = null;         startTime = System.currentTimeMillis();         try {             c = view.getHolder().lockCanvas();             synchronized (view.getHolder()) {                 view.onDraw(c);             }         } finally {             if (c != null) {                 view.getHolder().unlockCanvasAndPost(c);             }         }         sleepTime = ticksPS-(System.currentTimeMillis() - startTime);         try {             if (sleepTime > 0)                 sleep(sleepTime);             else                 sleep(10);         } catch (Exception e) {}     } } } 

Sprite.java

import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Rect;  public class Sprite { private static final int BMP_ROWS = 5; private static final int BMP_COLUMNS = 5; private int x = 0; private int y = 0; private int ySpeed = 3; private GameView gameView; private Bitmap bmp; private int currentFrame = 1; private int width; private int height;  public Sprite(GameView gameView, Bitmap bmp) {     this.gameView = gameView;     this.bmp = bmp;     this.width = bmp.getWidth() / BMP_COLUMNS;     this.height = bmp.getHeight() / BMP_ROWS; }  private void update() {     if (y > gameView.getWidth() - width - y) {         ySpeed = -5;     }     if (y + y < 0) {         ySpeed = 5;     }     y = y + ySpeed;     currentFrame = ++currentFrame % BMP_COLUMNS; }  public void onDraw(Canvas canvas) {     update();     int srcX = currentFrame * width;     int srcY = 1 * height;     Rect src = new Rect(srcX, srcY, srcX + width, srcY + height);     Rect dst = new Rect(x, y, x + width, y + height);     canvas.drawBitmap(bmp, src, dst, null); } } 

2 Answers

Answers 1

I'll recommend you to use this library. It's great for Sprite Animation. It has some limitations though, but it works fine.

Here is the code how I done it.

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.runningcat); int width = bitmap.getWidth(); int height = bitmap.getHeight();  int frameWidth = width / 5;    //you have 5 columns int frameHeight = height / 5;  //and 5 rows int frameNum = 25;             //there would be 25 images   SpriteSheetDrawer spriteSheetDrawer = new SpriteSheetDrawer(         bitmap,         frameWidth,         frameHeight,         frameNum)         .spriteLoop(true)         .frequency(2);   //change it as per your need   DisplayObject displayObject = new DisplayObject(); displayObject         .with(spriteSheetDrawer)         .tween()         .tweenLoop(true)         .transform(0, 0) //I have changed it according to my need, you can also do this by changing these values         .toX(4000, 0)    //this one too.         .end(); //In actual example, it's set as animation starts from one end of the screen and goes till the other one.   FPSTextureView textureView = (FPSTextureView) findViewById(R.id.fpsAnimation); textureView.addChild(displayObject).tickStart(); 

Answers 2

Problem is in src value that you're using in method. canvas.drawBitmap(bmp, src, dst, null); srcY should be zero. I've tested here.

private Bitmap character; private counter,charFrame; private RectF annonymousRectF; private Rect annonymousRect;  public Sprite() {      character=BitmapFactory.decodeResource(context.getResources(), R.drawable.flipchar2);      annonymousRect=new Rect();      annonymousRectF=new RectF(); }   public void update() {     counter++;     if(counter%5==0)         if(charFrame<NO_CHAR_FRAME-1)             charFrame++;         else             charFrame=0; }  public void draw(){     annonymousRect.set(charFrame*character.getWidth()/NO_CHAR_FRAME,0,(charFrame+1)*character.getWidth()/NO_CHAR_FRAME,character.getHeight());     annonymousRectF.set(-width*.015f,height*.35f,width*.5f,height*.58f);  //set value according to where you want to draw     canvas.drawBitmap(character, annonymousRect,annonymousRectF, null); } 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment