2017-02-17 1 views
8

У меня есть лист спрайтов размером 612x864 с 5 строками и 5 столбцами. Моя проблема в том, как я могу загрузить его и анимировать? Я хочу переместить кошачий спрайт только по оси Y. Я уже пытаюсь, но мой код работает неправильно. Вот мой код.Как загрузить лист спрайтов с 5 строками и 5-ти столбцами в виде андроида?

В 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

Вам следует подумать об использовании игрового движка, такого как LibGDX. У этого есть классы и методы, которые делают такую ​​вещь очень безболезненной. –

+0

p.s. Из того, что я могу сказать, единственная причина, по которой вы передаете 'GameView' в конструктор' Sprite', - это обнаружение столкновения со стороны экрана. Я предлагаю отправить параметр 'int maxY' в конструктор' Sprite', а не 'GameView'. Это отменит классы 'Sprite' и' GameView'. –

+0

Спасибо, сэр @ Code-Apprentice за ваш комментарий. Я попробую его использовать движок игры. –

ответ

3

Я рекомендую вам использовать this библиотеку. Это здорово для Sprite Анимация. Однако он имеет некоторые ограничения, но работает отлично.

Вот код, как я это сделал.

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(); 
3

Проблема в значении src, которое вы используете в методе. canvas.drawBitmap(bmp, src, dst, null); srcY должен быть равен нулю. Я протестировал здесь.

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); 
} 
Смежные вопросы