Mar 7, 2012

SurfaceView Game step-by-step: react device movement/orientation using accelerometer

With the help of accelerometer on Android device(Get detail info of Accelerometer), we can react device movement/orientation for our SurfaceView Game(Implement onTouchEvent() to handle user touch on SurfaceView). After finished, the the Sprite will move once user move the device.

SurfaceView Game step-by-step: react device movement/orientation using accelerometer
Implement new class - MyAccelerometer.java.
package com.MyGame;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;

public class MyAccelerometer implements SensorEventListener{

private SensorManager sensorManager;
private Sensor sensorAccelerometer;
private MyGameActivity parent;

private float maximumRange;

public MyAccelerometer(Context c) {
parent = (MyGameActivity)c;
}

void registerListener(){
sensorManager = (SensorManager)parent.getSystemService(Context.SENSOR_SERVICE);
sensorAccelerometer = sensorManager.getDefaultSensor(
Sensor.TYPE_ACCELEROMETER);

maximumRange = sensorAccelerometer.getMaximumRange();

sensorManager.registerListener(this,
sensorAccelerometer,
SensorManager.SENSOR_DELAY_NORMAL);
}

void unregisterListener(){
sensorManager.unregisterListener(this);
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub

}

@Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
/*
* event.values[0]: azimuth, rotation around the Z axis.
* event.values[1]: pitch, rotation around the X axis.
* event.values[2]: roll, rotation around the Y axis.
*/

float valueAzimuth = event.values[0];
float valuePitch = event.values[1];

parent.updateAccelerometer(
valueAzimuth/maximumRange, -valuePitch/maximumRange);

}

}


Modify MyGameActivity.java to instance MyAccelerometer object in onCreate(), init it in onResume(), unregisterListener it in onPause(), and also implement updateAccelerometer().
package com.MyGame;

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

public class MyGameActivity extends Activity {

MyGameSurfaceView myGameSurfaceView1;
MyForeground myForeground;

MyAccelerometer myAccelerometer;

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

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

myAccelerometer = new MyAccelerometer(this);

}

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

myAccelerometer.registerListener();

}

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

myAccelerometer.unregisterListener();
}

void updateAccelerometer(float tx, float ty){
int w = myForeground.getWidth();
int h = myForeground.getHeight();

float x = ((w/2) * tx) + (w/2);
float y = ((h/2) * ty) + (h/2);
myForeground.updateAccelerometer(x, y);
}

}


Update MyForeground.java.
package com.MyGame;

import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff.Mode;
import android.util.AttributeSet;

public class MyForeground extends MyGameSurfaceView {

Sprite mySprite;

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

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

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

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

@Override
protected void onDraw(Canvas canvas) {
//Clear Canvas with transparent background
canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);

mySprite.draw(canvas);
}

@Override
public void updateStates() {
// TODO Auto-generated method stub
mySprite.update();
}

void updateAccelerometer(float tx, float ty){
mySprite.setX((int)tx);
mySprite.setY((int)ty);
}

}


Update Sprite.java to remove un-used code.
package com.MyGame;

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

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

public Sprite(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);
}

public void update(){

}

}


The code can be download here: https://sites.google.com/site/helloandroidingcoding/download/MyGame_20120307.zip?attredirects=0&d=1

No comments:

Post a Comment

Infolinks In Text Ads