Introducing Sprite In Android

In the last post foreground SurfaceView, the object on foreground was draw as a bitmap. Now we are going to implement a Sprite class. The Sprite class’s object keeps its own status such as location(x, y) and bitmap, and also draws itself on canvas.

Algorithm:

1.) Create a new project by File-> New -> Android Project name it SpriteIntroduction.

2.) Write following into main.xml:

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello" />
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.example.spriteintroduction.GameSurface
android:id="@+id/myview1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<com.example.spriteintroduction.ForegroundSurface
android:id="@+id/myforeground"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
</LinearLayout>

 

 

3.) Create and write following into GameThread.java:

 

package com.example.spriteintroduction;

public class GameThread extends Thread {

volatile boolean running = false;

GameSurface parent;
long sleepTime;

GameThread(GameSurface sv, long st){
super();
parent = sv;
sleepTime = st;
}

public void setRunning(boolean r){
running = r;
}

@Override
public void run() {
// TODO Auto-generated method stub
while(running){

try {
sleep(sleepTime);
parent.updateSurfaceView();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}
}

 

 

4.) Create and write following into GameSurface.java:

 

package com.example.spriteintroduction;

import java.util.Random;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class GameSurface extends SurfaceView implements SurfaceHolder.Callback{

SurfaceHolder surfaceHolder;

GameThread myGameThread = null;

int myCanvas_w, myCanvas_h;
Bitmap myCanvasBitmap = null;
Canvas myCanvas = null;
Matrix identityMatrix;

private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Random random;

public GameSurface(Context context) {
super(context);
// TODO Auto-generated constructor stub
}

public GameSurface(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}

public GameSurface(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub

}

@Override
public void surfaceCreated(SurfaceHolder holder) {

myCanvas_w = getWidth();
myCanvas_h = getHeight();
myCanvasBitmap = Bitmap.createBitmap(myCanvas_w, myCanvas_h, Bitmap.Config.ARGB_8888);
myCanvas = new Canvas();
myCanvas.setBitmap(myCanvasBitmap);

identityMatrix = new Matrix();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub

}

public void MyGameSurfaceView_OnResume(){

random = new Random();
surfaceHolder = getHolder();
getHolder().addCallback(this);

//Create and start background Thread
myGameThread = new GameThread(this, 200);
myGameThread.setRunning(true);
myGameThread.start();

}

public void MyGameSurfaceView_OnPause(){
//Kill the background Thread
boolean retry = true;
myGameThread.setRunning(false);

while(retry){
try {
myGameThread.join();
retry = false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

@Override
protected void onDraw(Canvas canvas) {

paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);

//int w = myCanvas.getWidth();
//int h = myCanvas.getHeight();
int x = random.nextInt(myCanvas_w-1);
int y = random.nextInt(myCanvas_h-1);
int r = random.nextInt(255);
int g = random.nextInt(255);
int b = random.nextInt(255);

paint.setColor(0xff000000 + (r << 16) + (g << 8) + b);
myCanvas.drawPoint(x, y, paint);

canvas.drawBitmap(myCanvasBitmap, identityMatrix, null);

}

public void updateStates(){
//Dummy method() to handle the States
}

public void updateSurfaceView(){
//The function run in background thread, not ui thread.

Canvas canvas = null;

try{
canvas = surfaceHolder.lockCanvas();

synchronized (surfaceHolder) {
updateStates();
onDraw(canvas);
}
}finally{
if(canvas != null){
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}

 

5.) Create and write following into ForegroundSurface.java:

 

package com.example.spriteintroduction;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;

public class ForegroundSurface extends GameSurface {

SpriteExample mySprite;

public ForegroundSurface(Context context) {
super(context);
init();
}

public ForegroundSurface(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public ForegroundSurface(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}

private void init(){
mySprite = new SpriteExample(
BitmapFactory.decodeResource(getResources(), R.drawable.myicon),
100, 100);
}

@Override
protected void onDraw(Canvas canvas) {
mySprite.draw(canvas);
}

}
6.) Create and write following into SpriteExample.java:

package com.example.spriteintroduction;

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

public class SpriteExample {
private Bitmap bitmap;
private int x;
private int y;
float bitmap_halfWidth, bitmap_halfHeight;

public SpriteExample(Bitmap bm, int tx, int ty){
bitmap = bm;
x = tx;
y = ty;
bitmap_halfWidth = bitmap.getWidth()/2;
bitmap_halfHeight = bitmap.getHeight()/2;
}

public void setX(int tx){
x = tx;
}

public void setY(int ty){
y = ty;
}

public int getX(){
return x;
}

public int getY(){
return y;
}

public void draw(Canvas canvas){
canvas.drawBitmap(bitmap, x-bitmap_halfWidth, y-bitmap_halfHeight, null);
}
}

 

7.) Write following permissions to your manifest

 

<activity android:name=".GameSurface" ></activity>
<activity android:name=".GameThread" ></activity>
<activity android:name=".ForegroundSurface" ></activity>
<activity android:name=".SpriteExample" ></activity>

 

 

8.) Run for output.

Steps:

1.) Create a project named SpriteIntroduction and set the information as stated in the image.

Build Target: Android 4.4
Application Name: SpriteIntroduction
Package Name: com.example.SpriteIntroduction
Activity Name: SpriteIntroductionActivity

sprite1

2.) Open SpriteIntroductionActivity.java file and write following code there:

 

package com.example.spriteintroduction;

import android.app.Activity;
import android.graphics.PixelFormat;
import android.os.Bundle;

public class SpriteIntroductionActivity extends Activity {

GameSurface myGameSurfaceView1;
ForegroundSurface myForeground;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myGameSurfaceView1 = (GameSurface)findViewById(R.id.myview1);
myForeground = (ForegroundSurface)findViewById(R.id.myforeground);

//Set myForeground using transparent background
myForeground.setZOrderOnTop(true);
myForeground.getHolder().setFormat(PixelFormat.TRANSPARENT);

}

@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
myGameSurfaceView1.MyGameSurfaceView_OnResume();
myForeground.MyGameSurfaceView_OnResume();

}

@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
myGameSurfaceView1.MyGameSurfaceView_OnPause();
myForeground.MyGameSurfaceView_OnPause();
}
}

 

 

3.) Compile and build the project.

Output

sprite2