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); }
0 comments:
Post a Comment