Tutorials‎ > ‎

How to make Pachinko using android

posted Dec 22, 2011, 11:17 PM by Eripin _   [ updated Aug 15, 2016, 11:29 PM by Surya Wang ]




Now, I want to give tutorial about make the image move according to the shake and change the image with another one if I move it.
I divided the step into 5 step. They are :
  1. Shake detection
  2. Crop image
  3. Manipulate image
  4. Onshake action
Shake detection 
	If we want to detect android shake motion, we can use SensorEventListener.  
In this tutorial, I use a class for managing shake event. I named it ShakeEventListener.

Code for ShakeEventListener :
import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager;
/** * Listener that detects shake gesture. */ public class ShakeEventListener implements SensorEventListener { /** Minimum movement force to consider. */ private static final int MIN_FORCE = 10; /** * Minimum times in a shake gesture that the direction of movement needs to * change. */ private static final int MIN_DIRECTION_CHANGE = 3; /** Maximum pause between movements. */ private static final int MAX_PAUSE_BETHWEEN_DIRECTION_CHANGE = 200; /** Maximum allowed time for shake gesture. */ private static final int MAX_TOTAL_DURATION_OF_SHAKE = 400; /** Time when the gesture started. */ private long mFirstDirectionChangeTime = 0; /** Time when the last movement started. */ private long mLastDirectionChangeTime; /** How many movements are considered so far. */ private int mDirectionChangeCount = 0; /** The last x position. */ private float lastX = 0; /** The last y position. */ private float lastY = 0; /** The last z position. */ private float lastZ = 0; /** OnShakeListener that is called when shake is detected. */ private OnShakeListener mShakeListener; /** * Interface for shake gesture. */ public interface OnShakeListener { /** * Called when shake gesture is detected. */ void onShake(); } public void setOnShakeListener(OnShakeListener listener) { mShakeListener = listener; } @Override public void onSensorChanged(SensorEvent se) { // get sensor data float x = se.values[SensorManager.DATA_X]; float y = se.values[SensorManager.DATA_Y]; float z = se.values[SensorManager.DATA_Z]; // calculate movement float totalMovement = Math.abs(x + y + z - lastX - lastY - lastZ); if (totalMovement > MIN_FORCE) { // get time long now = System.currentTimeMillis(); // store first movement time if (mFirstDirectionChangeTime == 0) { mFirstDirectionChangeTime = now; mLastDirectionChangeTime = now; } // check if the last movement was not long ago long lastChangeWasAgo = now - mLastDirectionChangeTime; if (lastChangeWasAgo = MIN_DIRECTION_CHANGE) { // check total duration long totalDuration = now - mFirstDirectionChangeTime; if (totalDuration < MAX_TOTAL_DURATION_OF_SHAKE) { mShakeListener.onShake(); resetShakeParameters(); } } } else { resetShakeParameters(); } } } /** * Resets the shake parameters to their default values. */ private void resetShakeParameters() { mFirstDirectionChangeTime = 0; mDirectionChangeCount = 0; mLastDirectionChangeTime = 0; lastX = 0; lastY = 0; lastZ = 0; } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }
After create that class, create main class that will implement the shake detection. I named it ShakeActivity. Code For ShakeActivity :
private SensorManager mSensorManager; private ShakeEventListener mSensorListener; import com.phonegap.DroidGap; import android.os.Bundle; public class ShakeActivity extends DroidGap { @Override protected void onResume() { super.onResume(); mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI); } @Override protected void onStop() { mSensorManager.unregisterListener(mSensorListener); super.onStop(); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mSensorListener = new ShakeEventListener(); mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI); mSensorListener.setOnShakeListener(new ShakeEventListener.OnShakeListener() { public void onShake() { Toast.makeText(KPBActivityImpl.this, "Shake!", Toast.LENGTH_SHORT).show(); } }); }
Crop Image Next step is the ability to crop the image. We can use canvas to place our new image. We use matrix and Bitmap to resize our image. Also we need path to set position of our image. It is very important to set position of our image because we will change image according to the shake and we need to make simple animation for that image. I make my own function to handle this problem. Code :
public void addGbr(ImageView gbr,float posY,Bitmap bitGbr1,Bitmap bitGbr2){ try{ Paint paint = new Paint(); paint.setFilterBitmap(true); RectF rectf = new RectF(0,0,100,66); RectF rectf2 = new RectF(0,0,100,100); Canvas canvas = new Canvas(targetBitmap); Path path = new Path(); Path path2 = new Path(); path.addRect(rectf, Path.Direction.CW); path2.addRect(rectf2, Path.Direction.CW); canvas.clipPath(path); canvas.drawBitmap( bitGbr1, 0f,67-posY, paint); canvas.clipPath(path2); canvas.drawBitmap( bitGbr2, 0f, -posY, paint); Matrix matrix = new Matrix(); matrix.postScale(1f, 1f); Bitmap resizedBitmap = Bitmap.createBitmap(targetBitmap, 0, 0, 100, 100, matrix, true); /*convert Bitmap to resource */ BitmapDrawable bd = new BitmapDrawable(resizedBitmap); gbr.setBackgroundDrawable(bd); } catch(Exception e){ System.out.println("Error1 : " + e.getMessage() + e.toString()); } }
The code that I use is using value that suitable to my application like 66f value. So, that is not exact value for another application. Manipulate image Manipulate image that I mean here is the ability to change one image to another image and the ability to change the image that is being shake. Code :
private Runnable myRunnable = new Runnable() { @Override public void run() { if(flag<=3){ if(flag==2){ gbrUbah=gbr2;pnh1.setBackgroundColor(color.black); pnh2.setBackgroundResource(R.drawable.arrowdown); } else if(flag==3){ gbrUbah=gbr3;pnh2.setBackgroundColor(color.black); pnh3.setBackgroundResource(R.drawable.arrowdown); } if(bykGetar<0)bykGetar=0; if(_letakY<=0){ mSensorListener.penanda=flag; bykGetar--; _letakY=66f; if(q==3)q=0; else q++; } if(q==3){ addGbr(gbrUbah,_letakY,bitAllGbr[3],bitAllGbr[0]); } else{ addGbr(gbrUbah,_letakY,bitAllGbr[q],bitAllGbr[q+1]); } //set max, ga bs berenti int speed=6000/((bykGetar)+8); if(speed0){_letakY-=10;mSensorListener.penanda=0;} } } };
OnShake action To control the image movement according to shaking, I use thread to read the shake value first, and with that shake value, move the image and change to another if the image already shaken. Code :
myHandler = new Handler(); mSensorListener.setOnShakeListener(new ShakeEventListener.OnShakeListener() { public void onShake() { bykGetar=mSensorListener.nilai*3; flag=mSensorListener.f; myHandler.postDelayed(myRunnable, 1000); //flag++; } });