實作記憶遊戲

1. activity_main.xml

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

    <TableRow android:gravity="center" >
        <ImageView
            android:id="@+id/card0"
            android:layout_width="90dp"
            android:layout_height="90dp"
            android:layout_marginRight="10dp"
            android:src="@drawable/ic_launcher" />

        <ImageView
            android:id="@+id/card1"
            android:layout_width="90dp"
            android:layout_height="90dp"
            android:layout_marginRight="10dp"
            android:src="@drawable/ic_launcher" />

        <ImageView
            android:id="@+id/card2"
            android:layout_width="90dp"
            android:layout_height="90dp"
            android:layout_marginRight="10dp"
            android:src="@drawable/ic_launcher" />
    </TableRow>

    <TableRow android:gravity="center" >
        <ImageView
            android:id="@+id/card3"
            android:layout_width="90dip"
            android:layout_height="90dip"
            android:layout_marginRight="10dp"
            android:src="@drawable/ic_launcher" />

        <ImageView
            android:id="@+id/card4"
            android:layout_width="90dip"
            android:layout_height="90dip"
            android:layout_marginRight="10dp"
            android:src="@drawable/ic_launcher" />

        <ImageView
            android:id="@+id/card5"
            android:layout_width="90dip"
            android:layout_height="90dip"
            android:layout_marginRight="10dp"
            android:src="@drawable/ic_launcher" />
    </TableRow>

    <TableRow android:gravity="center" >
        <ImageView
            android:id="@+id/card6"
            android:layout_width="90dip"
            android:layout_height="90dip"
            android:layout_marginRight="10dp"
            android:src="@drawable/ic_launcher" />

        <ImageView
            android:id="@+id/card7"
            android:layout_width="90dip"
            android:layout_height="90dip"
            android:layout_marginRight="10dp"
            android:src="@drawable/ic_launcher" />

        <ImageView
            android:id="@+id/card8"
            android:layout_width="90dip"
            android:layout_height="90dip"
            android:layout_marginRight="10dp"
            android:src="@drawable/ic_launcher" />
    </TableRow>

    <TableRow android:gravity="center" >
        <ImageView
            android:id="@+id/card9"
            android:layout_width="90dip"
            android:layout_height="90dip"
            android:layout_marginRight="10dp"
            android:src="@drawable/ic_launcher" />

        <ImageView
            android:id="@+id/card10"
            android:layout_width="90dip"
            android:layout_height="90dip"
            android:layout_marginRight="10dp"
            android:src="@drawable/ic_launcher" />

        <ImageView
            android:id="@+id/card11"
            android:layout_width="90dip"
            android:layout_height="90dip"
            android:layout_marginRight="10dp"
            android:src="@drawable/ic_launcher" />
    </TableRow>

    <TableRow android:gravity="center" >
        <Button
            android:id="@+id/res"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="ReStart" />
    </TableRow>

</TableLayout>

2. Rotate3dAnimation.java

import android.graphics.Camera;
import android.graphics.Matrix;
import android.view.animation.Animation;
import android.view.animation.Transformation;



public class Rotate3dAnimation extends Animation {
 private final float mFromDegrees;
 private final float mToDegrees;
 private final float mCenterX;
 private final float mCenterY;
 private final float mDepthZ;
 private final boolean mReverse;
 private Camera mCamera;

 /**
  * Creates a new 3D rotation on the Y axis. The rotation is defined by its
  * start angle and its end angle. Both angles are in degrees. The rotation
  * is performed around a center point on the 2D space, definied by a pair of
  * X and Y coordinates, called centerX and centerY. When the animation
  * starts, a translation on the Z axis (depth) is performed. The length of
  * the translation can be specified, as well as whether the translation
  * should be reversed in time.
  *
  * @param fromDegrees
  *            the start angle of the 3D rotation
  * @param toDegrees
  *            the end angle of the 3D rotation
  * @param centerX
  *            the X center of the 3D rotation
  * @param centerY
  *            the Y center of the 3D rotation
  * @param reverse
  *            true if the translation should be reversed, false otherwise
  */
 public Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX,
   float centerY, float depthZ, boolean reverse) {
  mFromDegrees = fromDegrees;
  mToDegrees = toDegrees;
  mCenterX = centerX;
  mCenterY = centerY;
  mDepthZ = depthZ;
  mReverse = reverse;
 }

 @Override
 public void initialize(int width, int height, int parentWidth,
   int parentHeight) {
  super.initialize(width, height, parentWidth, parentHeight);
  mCamera = new Camera();
 }

 @Override
 protected void applyTransformation(float interpolatedTime, Transformation t) {
  final float fromDegrees = mFromDegrees;
  float degrees = fromDegrees
    + ((mToDegrees - fromDegrees) * interpolatedTime);

  final float centerX = mCenterX;
  final float centerY = mCenterY;
  final Camera camera = mCamera;

  final Matrix matrix = t.getMatrix();
  camera.save();
  if (mReverse) {
   camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
  } else {
   camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
  }
  camera.rotateY(degrees);
  camera.getMatrix(matrix);
  camera.restore();

  matrix.preTranslate(-centerX, -centerY);
  matrix.postTranslate(centerX, centerY);
 }
}



3. MainActivity.java

import java.util.ArrayList;
import java.util.Collections;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;



public class MainActivity extends Activity implements OnClickListener {

 HandleDelay hc;
 ArrayList<Integer> al = new ArrayList<Integer>();
 Button res;
 int cmp = 0;
 ImageView[] card = new ImageView[12];
 ImageView cardA = null, cardB = null;
 private static int picid[] = { R.drawable.chrysanthemum,
   R.drawable.chrysanthemum, R.drawable.desert, R.drawable.desert,
   R.drawable.hydrangeas, R.drawable.hydrangeas, R.drawable.jellyfish,
   R.drawable.jellyfish, R.drawable.koala, R.drawable.koala,
   R.drawable.lighthouse, R.drawable.lighthouse };

 private static int setimageid[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
 private static int setimageviewui[] = { R.id.card0, R.id.card1, R.id.card2,
   R.id.card3, R.id.card4, R.id.card5, R.id.card6, R.id.card7,
   R.id.card8, R.id.card9, R.id.card10, R.id.card11 };

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  hc = new HandleDelay();
  res = (Button) findViewById(R.id.res);
  res.setOnClickListener(this);
  setImageView();
  addInitListerer();
  setInitImageViewId();
  Random();
 }

 public void onClick(View v) {
  if (v == res) {
   for (int i = 0; i < 12; i++) {
    card[i].setImageDrawable(getResources().getDrawable(
      R.drawable.ic_launcher));

   }
   cmp = 0;
   al.clear();
   Random();
   addInitListerer();
   setInitImageViewId();
   return;
  }

  for (int i = 0; i < 12; i++) {
   if (v == card[i]) {
    setRotationBeforeAnimation(card[i], al.get(i));
   }
  }
  if (cardA == null) {
   cardA = (ImageView) v;
   removeListerer(cardA, 0);
   res.setEnabled(false);
  } else if (cardB == null) {
   cardB = (ImageView) v;
   removeListerer(cardB, 2);
  }
  if (cardA != null && cardB != null) {
   count();
  }
 }

 public void setRotationBeforeAnimation(ImageView select, int id) {
  float centerX = select.getWidth() / 2f;
  float centerY = select.getHeight() / 2f;
  // 構建3D旋轉動畫對象,旋轉角度为0到90度,這使得ListView將會從可見變为不可見
  final Rotate3dAnimation rotation = new Rotate3dAnimation(0, 92,
    centerX, centerY, 360.0f, true);
  // 動畫持續時間500毫秒
  rotation.setDuration(400);
  // 動畫完成後保持完成的狀態
  rotation.setFillAfter(true);
  rotation.setInterpolator(new AccelerateInterpolator());
  // 設置動畫的監聽器
  rotation.setAnimationListener(new TurnToImageViewBefore(select, id));
  select.startAnimation(rotation);
 }

 public void setRotationAfterAnimation(ImageView select) {
  float centerX = select.getWidth() / 2f;
  float centerY = select.getHeight() / 2f;
  // 構建3D旋轉動畫對象,旋轉角度为0到90度,這使得ListView將會從可見變为不可見
  final Rotate3dAnimation rotation = new Rotate3dAnimation(360, 270,
    centerX, centerY, 360.0f, true);
  // 動畫持續時間500毫秒
  rotation.setDuration(500);
  // 動畫完成後保持完成的狀態
  rotation.setFillAfter(true);
  rotation.setInterpolator(new AccelerateInterpolator());
  // 設置動畫的監聽器
  rotation.setAnimationListener(new TurnToImageViewAfter(select));
  select.startAnimation(rotation);
 }

 class TurnToImageViewBefore implements AnimationListener {
  ImageView imageview;
  int imageid;

  public TurnToImageViewBefore(ImageView imageview, int imageid) {
   this.imageview = imageview;
   this.imageid = imageid;
  }

  public void onAnimationStart(Animation animation) {
  }
  /**
   * 當ListView的動畫完成後,還需要再启動ImageView的動畫,讓ImageView從不可見變为可見
   */
  @Override
  public void onAnimationEnd(Animation animation) {

   float centerX = imageview.getWidth() / 2f;
   float centerY = imageview.getHeight() / 2f;

   // 構建3D旋轉動畫對象,旋轉角度为270到360度,這使得ImageView將會從不可見變为可見
   final Rotate3dAnimation rotation = new Rotate3dAnimation(270, 360,
     centerX, centerY, 360.0f, false);
   // 動畫持續時間500毫秒
   rotation.setDuration(400);
   // 動畫完成後保持完成的狀態
   rotation.setFillAfter(true);
   rotation.setInterpolator(new AccelerateInterpolator());
   imageview.setImageDrawable(getResources().getDrawable(
     picid[imageid]));
   imageview.startAnimation(rotation);
  }

  @Override
  public void onAnimationRepeat(Animation animation) {
  }

 }
 class TurnToImageViewAfter implements AnimationListener {
  ImageView imageview;
  public TurnToImageViewAfter(ImageView imageview) {
   this.imageview = imageview;
  }

  public void onAnimationStart(Animation animation) {
  }
  /**
   * 當ListView的動畫完成後,還需要再启動ImageView的動畫,讓ImageView從不可見變为可見
   */
  @Override
  public void onAnimationEnd(Animation animation) {

   // 獲取布局的中心點位置,作为旋轉的中心點
   float centerX = imageview.getWidth() / 2f;
   float centerY = imageview.getHeight() / 2f;
   // 構建3D旋轉動畫對象,旋轉角度为270到360度,這使得ImageView將會從不可見變为可見
   final Rotate3dAnimation rotation = new Rotate3dAnimation(270, 180,
     centerX, centerY, 360.0f, false);
   // 動畫持續時間500毫秒
   rotation.setDuration(500);
   // 動畫完成後保持完成的狀態
   rotation.setFillAfter(true);
   rotation.setInterpolator(new AccelerateInterpolator());
   imageview.setImageDrawable(getResources().getDrawable(
     R.drawable.ic_launcher));
   imageview.startAnimation(rotation);

  }
  @Override
  public void onAnimationRepeat(Animation animation) {

  }
 }
 public void setInitImageViewId() {
  for (int i = 0; i < 12; i++) {
   card[i].setId(setimageid[i]);
  }
 }

 public void setImageView() {
  for (int i = 0; i < 12; i++) {
   card[i] = (ImageView) findViewById(setimageviewui[i]);

  }
 }

 public void removeListerer(ImageView imageview, int selected) {
  if (selected == 0) {
   for (int i = 0; i < 12; i++) {
    if (imageview.getId() == i) {
     card[i].setOnClickListener(null);
    }
   }
  } else if (selected == 1) {
   for (int i = 0; i < 12; i++) {
    if (!(card[i].getId() == 999)) {
     card[i].setOnClickListener(null);
    }
   }
  } else if (selected == 2) {
   for (int i = 0; i < 12; i++) {
    card[i].setOnClickListener(null);
   }
  }
 }

 public void addInitListerer() {
  for (int i = 0; i < 12; i++) {
   card[i].setOnClickListener(this);
  }
 }

 public void addListerer() {
  for (int i = 0; i < 12; i++) {
   if (!(card[i].getId() == 999)) {
    card[i].setOnClickListener(this);
   }
  }
 }

 private void Compare(ImageView ivA, ImageView ivB) {
  Log.e("ivA", ivA.getDrawable().getConstantState().toString());
  Log.e("ivB", ivB.getDrawable().getConstantState().toString());
  if (ivA.getDrawable().getConstantState() == ivB.getDrawable()
    .getConstantState()) {
   cmp++;
   for (int i = 0; i < 12; i++) {
    if (ivA.getId() == i || ivB.getId() == i) {
     card[i].setId(999);
     removeListerer(card[i], 1);
    }
   }
  } else {
   setRotationAfterAnimation(ivA);
   setRotationAfterAnimation(ivB);
  }
  if (cmp == 6) {
   Toast.makeText(this, "Game Finished", Toast.LENGTH_SHORT).show();
  }
  cardA = null;
  cardB = null;
 }

 private void Random() {
  for (int i = 0; i < 12; i++) {
   al.add(i);
  }
  Collections.shuffle(al);
 }

 public void count() {
  new Thread(new Runnable() {
   @Override
   public void run() {
    Message msg = new Message();
    for (int i = 1; i <= 3; i++) {
     msg.what = i;
     try {
      Thread.sleep(300);
      Log.e("Counter", "" + i);
     } catch (Exception ex) {
     }
    }
    hc.sendMessage(msg);
   }
  }).start();
 }

 class HandleDelay extends Handler {
  @Override
  public void handleMessage(Message msg) {
   int c = msg.what;
   if (c == 3) {
    Compare(cardA, cardB);
    c = 0;
    res.setEnabled(true);
    addListerer();
   }
  }
 }
}


4. 以上圖片請自備

沒有留言: