You are here

Chapter 18: A better implementation of object rotation

I tried a completely different approach, and instead of creating bitmaps over and over again, I rotate the whole canvas around the center of our asteroid before drawing it. This is the new GfxObject.java:

package com.ajomannen.justroids;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;

public class GfxObject {

  protected Bitmap bitmap;
  protected float x;
  protected float y;
  private double velocity = 0;
  private double direction = 0;
  private double dX = 0;
  private double dY = 0;
  private int rotation = -1;
  private int angle = 0;

  public void setVelocity(float velocity) {
   this.velocity = velocity;
   calculateDXDY();
  }

  public void setDirection(float direction) {
   this.direction = direction;
   calculateDXDY();
  }

  private void calculateDXDY() {
   double radians = Math.toRadians(direction);
   dX = Math.cos(radians) * velocity;
   dY = Math.sin(radians) * velocity;
  }

  public void move(float screenWidth, float screenHeight) {
   float minX = 0 - bitmap.getWidth() / 2;
   float maxX = screenWidth + bitmap.getWidth() / 2;
   float minY = 0 - bitmap.getHeight() / 2;
   float maxY = screenHeight + bitmap.getHeight() / 2;

   x += dX;
   y += dY;
   if (x > maxX)
    x = minX;
   if (x < minX)
    x = maxX;
   if (y > maxY)
    y = minY;
   if (y < minY)
    y = maxY;

   angle += rotation;
   if (Math.abs(angle) >= 360)
    angle = 0;
  }

  public void draw(Canvas canvas, float x, float y, Paint paint) {
   canvas.save(Canvas.MATRIX_SAVE_FLAG);
   canvas.rotate(-angle, x, y);
   canvas.drawBitmap(bitmap, x - bitmap.getWidth() / 2,
     y - bitmap.getHeight() / 2, paint);
   canvas.restore();
  }

}

A quick profiling shows that all periodic GCs are gone:

Success! (All the hiccups are also gone, and the asteroid moves smoothly around on the screen.)

 

When looking at the CPU consumption, we can also see a significant improvement:

Now it is the Canvas.drawBitmap method that takes the most CPU, with a total of 60.7% of 64.9% of 44% = 17%, while rotating the canvas 25 times per second only costs 5% of the available cycles (on my emulator running on my €200 netbook). 

I did not expect that Canvas.rotate would be that​ cheap.

 

Anyway, I think we're done here for now. Rotating the canvas is the way forward for the moment.

 

Requirements implemented in this chapter

✔ 16. The asteroids shall rotate (just for the effect).

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer