我正在尝试模拟游戏应用中角色的动作。
角色将接受四个方向(左,右,上,下)的移动。
当前,我使用2D Spritesheet(以我的情况为4行和列;每个Sprite的宽度= 58,高度= 79,因此整个Spritesheet的大小为232x316)来完成工作。 / p>
但是,当我尝试为角色设置动画时,动画只会迭代Spritesheet的第一行。如何让它在全部16个精灵中循环显示?
还是我应该在这种情况下使用4个单独的Spritesheet?
非常感谢任何输入!
public class MainActivity extends AppCompatActivity {
private GameView gameView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
gameView = new GameView(this);
setContentView(gameView);
}
@Override
protected void onResume() {
super.onResume();
gameView.resume();
}
@Override
protected void onPause() {
super.onPause();
gameView.pause();
}
class GameView extends SurfaceView implements Runnable {
private Thread gameThread;
private SurfaceHolder ourHolder;
private volatile boolean playing;
private Canvas canvas;
private Bitmap bitmapRunningMan;
private boolean isMoving;
private float runSpeedPerSecond = 500;
private float manXPos = 10, manYPos = 10;
private int frameWidth = 58, frameHeight = 79;
private int frameCount = 16;
private int currentFrame = 0;
private long fps;
private long timeThisFrame;
private long lastFrameChangeTime = 0;
private int frameLengthInMillisecond = 100;
private Rect frameToDraw = new Rect(0, 0, frameWidth, frameHeight);
private RectF whereToDraw = new RectF(manXPos, manYPos, frameWidth, frameHeight);
public GameView(Context context) {
super(context);
ourHolder = getHolder();
bitmapRunningMan = BitmapFactory.decodeResource(getResources(), R.drawable.ninja);
bitmapRunningMan = Bitmap.createScaledBitmap(bitmapRunningMan, frameWidth * frameCount, frameHeight * frameCount, false);
}
@Override
public void run() {
while (playing) {
long startFrameTime = System.currentTimeMillis();
update();
draw();
timeThisFrame = System.currentTimeMillis() - startFrameTime;
if (timeThisFrame >= 1) {
fps = 1000 / timeThisFrame;
}
}
}
public void update() {
if (isMoving) {
manXPos = manXPos + runSpeedPerSecond / fps;
if (manXPos > getWidth()) {
manYPos += (int) frameHeight;
manXPos = 10;
}
if (manYPos + frameHeight > getHeight()) {
manYPos = 10;
}
}
}
public void manageCurrentFrame() {
long time = System.currentTimeMillis();
if (isMoving) {
if (time > lastFrameChangeTime + frameLengthInMillisecond) {
lastFrameChangeTime = time;
currentFrame++;
if (currentFrame >= frameCount) {
currentFrame = 0;
}
}
}
frameToDraw.left = currentFrame * frameWidth;
frameToDraw.right = frameToDraw.left + frameWidth;
}
public void draw() {
if (ourHolder.getSurface().isValid()) {
canvas = ourHolder.lockCanvas();
canvas.drawColor(Color.WHITE);
whereToDraw.set((int) manXPos, (int) manYPos, (int) manXPos + frameWidth, (int) manYPos + frameHeight);
manageCurrentFrame();
canvas.drawBitmap(bitmapRunningMan, frameToDraw, whereToDraw, null);
ourHolder.unlockCanvasAndPost(canvas);
}
}
public void pause() {
playing = false;
try {
gameThread.join();
} catch(InterruptedException e) {
Log.e("ERR", "Joining Thread");
}
}
public void resume() {
playing = true;
gameThread = new Thread(this);
gameThread.start();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN :
isMoving = !isMoving;
break;
}
return true;
}
}
}