You are here

Chapter 15: Throw in an asteroid

In the previous chapters we have spent large amounts of time with very small amounts of visible results on the device's screen.

So let's switch mode and start implementing visible stuff!

As we will have three different types of moving graphical objects, it is wise to start with a generic class with all that is common.

Thus, create GfxObject.java and put in the following:

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;
 
  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;
  }
 
  public void draw(Canvas canvas, float x, float y, Paint paint) {
   canvas.drawBitmap(bitmap, x - bitmap.getWidth() / 2,
     y - bitmap.getHeight() / 2, paint);
  }

}

Actually, almost everything required to move around an asteroid (or ship or missile) is here.

As you notice I choose to use polar coordinates (distance, angle - or velocity, direction) to express the object's movement, while I use Cartesian coordinates (x, y) for it's position. I found it more intuitive that way, as the asteroid's two halves will inherit their "parent's" speed later on but get a changed direction, while x,y is more suitable when it comes to "looping" objects around the screen's edges.

Anyway, it's time to create Asteroid.java:

package com.ajomannen.justroids;

import android.content.res.Resources;
import android.graphics.BitmapFactory;

public class Asteroid extends GfxObject {
 
  public Asteroid(Resources resources, float xPos, float yPos) {
   bitmap = BitmapFactory.decodeResource(resources,
     R.drawable.asteroid_100);
   x = xPos;
   y = yPos;
  }

}

See how short it became? We will have to put a bit more code later on, though, such as the handling of splitting an asteroid into two halves and so on. but for now it will do.

All we have to do now, is to create an instance of Asteroid and call it's move() and draw() methods from our GameEngine:

package com.ajomannen.justroids;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;

public class GameEngine {

  Context context;
  Resources resources;
 
  public float screenWidth;
  public float screenHeight;
  private Paint blackPaint;
  private Paint textPaint;
 
  Asteroid asteroid;
 
  public void Init(Context context) {
   this.context = context;
   resources = context.getResources();
 
   blackPaint = new Paint();
   blackPaint.setColor(Color.BLACK);
   blackPaint.setStyle(Style.FILL);
 
   textPaint = new Paint();
   textPaint.setColor(Color.LTGRAY);
   textPaint.setTextSize(40);
 
   asteroid = new Asteroid(resources, 20, 20);
   asteroid.setVelocity(2);
   asteroid.setDirection(135);
 
   setSurfaceDimensions(240, 160);
 
  }
 
  public void onDestroy() {
   try {
   } catch (Exception e) {
   }
  }
 
  public void setSurfaceDimensions(int width, int height) {
   screenWidth = width;
   screenHeight = height;
  }
 
  public void Update() {
   asteroid.move(screenWidth, screenHeight);
  }
 
  public void Draw(Canvas canvas) {
   canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), blackPaint);
   asteroid.draw(canvas, asteroid.x, asteroid.y, textPaint);
  }

}

And now to the visibility. Press ctrl-F11, click "Play" and see the asteroid fly by:

Comments

Why does my virtual device say," Unfortunately, JustRoids has just stopped" every time I click on the play button?
I checked the log and it said that it did not recognize the method "onClickGame". 
Please help!!

ajo's picture

Hi there,
If you could send me (ajo@benareby.com) a copy of your ecplise project, I'll try my best to help you out.
 
BR - Anders

Sir,
I wrote all codes but  I didn't understood How to add draw() and move() methods in Game Engine Activity 
I mean do i have to paste it after existing codes or I have to edit existing codes with from above codes Plese Help me 
 

ajo's picture

Hi Yash,
 
You should edit the existing methods, so they look like code pieces above.
 
When we added the Update and Draw methods in Chapter 11, we included the setting and prinout of a timestring, just to have something to show on the screen.
 
Now in Chapter 15, the setting of the timestring shall be replaced with asteroid.move and the printout of the timestring with asteroid.draw.
 
BR - Anders

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer