Handle Collision detection with Sprites

January 6th, 2012 by aabhaanjan

In this article we are going to learn how to add multiple sprits and handle their Collision. Lets start with following steps :

Step 1: Create a new MotoDev project.
MultipleSprite_Android

Step 2: Create sprite sheet animation for three character’s walk cycle.

boy1

Step 3: Put them in res/drawable folder.

Step 4: Open MainActivity.java class and add following code :
[xml]
package com.multiplesp;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;

public class MainActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new GameController(this));

}

}
[/xml]

Step 5: Create a new class GameController.java and put following code inside it
[xml]
package com.multiplesp;

import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.util.ArrayList;
import java.util.List;
import android.graphics.Bitmap;

public class GameController extends SurfaceView {

private SurfaceHolder _surfaceHolder;
private GameThread _gameThread;
private List Character = new ArrayList();
private long lastClick;
public GameController(Context context) {

super(context);
_gameThread = new GameThread(this);
_surfaceHolder = getHolder();
_surfaceHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder _surfaceHolder) {
boolean retry = true;
_gameThread.setRunning(false);
while (retry) {
try {
_gameThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
@Override
public void surfaceCreated(SurfaceHolder _surfaceHolder) {
createSprites();
_gameThread.setRunning(true);
_gameThread.start();
}
@Override
public void surfaceChanged(SurfaceHolder _surfaceHolder, int format,
int width, int height) {
}
});
}

private void createSprites() {
Character.add(createSprite(R.drawable.boy1));
Character.add(createSprite(R.drawable.girl1));
Character.add(createSprite(R.drawable.girl2));

}

private Character createSprite(int resouce) {
Bitmap bmp = BitmapFactory.decodeResource(getResources(), resouce);
return new Character(this,bmp);
}

@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
for (Character sprite : Character) {
sprite.onDraw(canvas);
}
}
@Override

public boolean onTouchEvent(MotionEvent event) {
if (System.currentTimeMillis() – lastClick > 500) {
lastClick = System.currentTimeMillis();
synchronized (getHolder()) {
for (int i = Character.size() – 1; i >= 0; i–) {
Character character = Character.get(i);
if (character.isCollition(event.getX(), event.getY())) {
Character.remove(character);
break;
}
}
}
}

return true;
}

}

[/xml]

Step 7: Create a GameThread Class and put following code inside :
[xml]
package com.multiplesp;

import android.graphics.Canvas;

public class GameThread extends Thread {
private GameController _gameController;
private boolean _isRunning = false;
static final long FPS = 10;

public GameThread(GameController _gameController) {
this._gameController = _gameController;
}

public void setRunning(boolean run) {
_isRunning = run;
}

@Override

public void run() {
long _trackFPS = 1000 / FPS;
long _startCounter;
long _sleepTime;
while (_isRunning) {
Canvas _canvas = null;
_startCounter = System.currentTimeMillis();
try {
_canvas = _gameController.getHolder().lockCanvas();
synchronized (_gameController.getHolder()) {
_gameController.onDraw(_canvas);
}

} finally {
if (_canvas != null) {
_gameController.getHolder().unlockCanvasAndPost(_canvas);
}
}
_sleepTime = _trackFPS – (System.currentTimeMillis() – _startCounter);
try {
if (_sleepTime > 0)
sleep(_sleepTime);
else
sleep(10);
} catch (Exception e) {}

}

}

}
[/xml]

Step 8:Create a Character.java class for your sprites. Put following code inside that:
[xml]
package com.multiplesp;

import java.util.Random;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;

public class Character {
int[] DIRECTION_TO_ANIMATION_MAP = { 3, 1, 0, 2 };
private static final int CHAR_ROWS = 4;
private static final int CHAR_COLUMNS = 3;
private static final int MAX_SPEED = 5;
private GameController GameController;
private Bitmap _characterbmp;
private int _xPos = 0;
private int _yPos = 0;
private int _xVelocity;
private int _yVelocity;
private int _currentFrame = 0;
private int _width;
private int _height;

public Character(GameController GameController, Bitmap _characterbmp) {
this._width = _characterbmp.getWidth() / CHAR_COLUMNS;
this._height = _characterbmp.getHeight() / CHAR_ROWS;
this.GameController = GameController;
this._characterbmp = _characterbmp;
Random _randomValue = new Random();
_xPos = _randomValue.nextInt(GameController.getWidth() – _width);
_yPos = _randomValue.nextInt(GameController.getHeight() – _height);
_xVelocity = _randomValue.nextInt(MAX_SPEED * 2) – MAX_SPEED;
_yVelocity = _randomValue.nextInt(MAX_SPEED * 2) – MAX_SPEED;
}

private void update() {
if (_xPos >= GameController.getWidth() – _width – _xVelocity || _xPos + _xVelocity <= 0) { _xVelocity = -_xVelocity; } _xPos = _xPos + _xVelocity; if (_yPos >= GameController.getHeight() – _height – _yVelocity || _yPos + _yVelocity <= 0) { _yVelocity = -_yVelocity; } _yPos = _yPos + _yVelocity; _currentFrame = ++_currentFrame % CHAR_COLUMNS; } public void onDraw(Canvas canvas) { update(); int orgX = _currentFrame * _width; int orgY = getAnimationRow() * _height; Rect src = new Rect(orgX, orgY, orgX + _width, orgY + _height); Rect dst = new Rect(_xPos, _yPos, _xPos + _width, _yPos + _height); canvas.drawBitmap(_characterbmp, src, dst, null); } private int getAnimationRow() { double dirDouble = (Math.atan2(_xVelocity, _yVelocity) / (Math.PI / 2) + 2); int direction = (int) Math.round(dirDouble) % CHAR_ROWS; return DIRECTION_TO_ANIMATION_MAP[direction]; } public boolean isCollition(float x2, float y2) { return x2 > _xPos && x2 < _xPos + _width && y2 > _yPos && y2 < _yPos + _height; } } [/xml] Step 9: Run your application . It should look like this : final