Android自学笔记(三)实现2048小游戏

完成了LabVIEW上的2048之后。。最近学了几周的Android,所以就想用Android实现一下。。

百度了不少方案 ,有View,GridView,我就突发奇想……想用TextView实现一下,然后就有了大概的思路:用一个二维数组然后在运算的过程中实时更新TextView的属性,并加入了计分和最高分记录与回显。 上代码!

1.首先是布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:orientation="horizontal" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="40dp"
            android:text="Score:"
            android:textColor="#CCC0B3" />

        <TextView
            android:id="@+id/score"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:text="0"
            android:textColor="#CCC0B3" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="40dp"
            android:text="BestScore:"
            android:textColor="#CCC0B3" />

        <TextView
            android:id="@+id/bestscore"
            android:layout_width="60dp"
            android:layout_height="wrap_content"
            android:text="0"
            android:textColor="#CCC0B3" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/textview00"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:background="#CCC0B3"
            android:gravity="center"
            android:textColor="#FFFFFF"
            android:textSize="20dp" />

        <TextView
            android:id="@+id/textview01"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_marginLeft="10dp"
            android:background="#CCC0B3"
            android:gravity="center"
            android:textColor="#FFFFFF"
            android:textSize="20dp" />

        <TextView
            android:id="@+id/textview02"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_marginLeft="10dp"
            android:background="#CCC0B3"
            android:gravity="center"
            android:textColor="#FFFFFF"
            android:textSize="20dp" />

        <TextView
            android:id="@+id/textview03"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_marginLeft="10dp"
            android:background="#CCC0B3"
            android:gravity="center"
            android:textColor="#FFFFFF"
            android:textSize="20dp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/textview10"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:background="#CCC0B3"
            android:gravity="center"
            android:textColor="#FFFFFF"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/textview11"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_marginLeft="10dp"
            android:background="#CCC0B3"
            android:gravity="center"
            android:textColor="#FFFFFF"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/textview12"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_marginLeft="10dp"
            android:background="#CCC0B3"
            android:gravity="center"
            android:textColor="#FFFFFF"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/textview13"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_marginLeft="10dp"
            android:background="#CCC0B3"
            android:gravity="center"
            android:textColor="#FFFFFF"
            android:textSize="20sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/textview20"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:background="#CCC0B3"
            android:gravity="center"
            android:textColor="#FFFFFF"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/textview21"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_marginLeft="10dp"
            android:background="#CCC0B3"
            android:gravity="center"
            android:textColor="#FFFFFF"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/textview22"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_marginLeft="10dp"
            android:background="#CCC0B3"
            android:gravity="center"
            android:textColor="#FFFFFF"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/textview23"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_marginLeft="10dp"
            android:background="#CCC0B3"
            android:gravity="center"
            android:textColor="#FFFFFF"
            android:textSize="20sp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/textview30"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:background="#CCC0B3"
            android:gravity="center"
            android:textColor="#FFFFFF"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/textview31"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_marginLeft="10dp"
            android:background="#CCC0B3"
            android:gravity="center"
            android:textColor="#FFFFFF"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/textview32"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_marginLeft="10dp"
            android:background="#CCC0B3"
            android:gravity="center"
            android:textColor="#FFFFFF"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/textview33"
            android:layout_width="70dp"
            android:layout_height="70dp"
            android:layout_marginLeft="10dp"
            android:background="#CCC0B3"
            android:gravity="center"
            android:textColor="#FFFFFF"
            android:textSize="20sp" />
    </LinearLayout>

</LinearLayout>

2.MainActivity

package com.ldgforever.twozerofourdight;

import java.util.Map;

import com.ldgforever.action.Action;
import com.ldgforever.savedata.savedata;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MotionEvent;
import android.widget.TextView;

public class MainActivity extends Activity {

	private static TextView mtextview00;
	private static TextView mtextview01;
	private static TextView mtextview02;
	private static TextView mtextview03;

	private static TextView mtextview10;
	private static TextView mtextview11;
	private static TextView mtextview12;
	private static TextView mtextview13;

	private static TextView mtextview20;
	private static TextView mtextview21;
	private static TextView mtextview22;
	private static TextView mtextview23;

	private static TextView mtextview30;
	private static TextView mtextview31;
	private static TextView mtextview32;
	private static TextView mtextview33;

	private static TextView mScore;
	private static TextView mBestScore;

	public static int score = 0;
	public static int bestscore = 0;

	float startX = 0, startY = 0, endX, endY;
	private int[][] a = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } };

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		score = 0;
		mtextview00 = (TextView) findViewById(R.id.textview00);
		mtextview01 = (TextView) findViewById(R.id.textview01);
		mtextview02 = (TextView) findViewById(R.id.textview02);
		mtextview03 = (TextView) findViewById(R.id.textview03);

		mtextview10 = (TextView) findViewById(R.id.textview10);
		mtextview11 = (TextView) findViewById(R.id.textview11);
		mtextview12 = (TextView) findViewById(R.id.textview12);
		mtextview13 = (TextView) findViewById(R.id.textview13);

		mtextview20 = (TextView) findViewById(R.id.textview20);
		mtextview21 = (TextView) findViewById(R.id.textview21);
		mtextview22 = (TextView) findViewById(R.id.textview22);
		mtextview23 = (TextView) findViewById(R.id.textview23);

		mtextview30 = (TextView) findViewById(R.id.textview30);
		mtextview31 = (TextView) findViewById(R.id.textview31);
		mtextview32 = (TextView) findViewById(R.id.textview32);
		mtextview33 = (TextView) findViewById(R.id.textview33);

		mScore = (TextView) findViewById(R.id.score);
		mBestScore = (TextView) findViewById(R.id.bestscore);
	}

	@Override
	public boolean dispatchTouchEvent(MotionEvent event) {

		int action = event.getAction();
		if (action == MotionEvent.ACTION_DOWN) {
			startX = event.getX();
			startY = event.getY();
		} else if (action == MotionEvent.ACTION_UP) {
			endX = event.getX();
			endY = event.getY();

			int direction = GetSlideDirection(startX, startY, endX, endY);
			int winORlose = Action.Slide(direction, a);
			switch (winORlose) {
			case 0:
				dialog("您赢了!");
				break;
			case 1:
				dialog("您输了");
			default:
				break;
			}
		}
		return super.dispatchTouchEvent(event);
	}

	// 返回角度
	private double GetSlideAngle(float dx, float dy) {
		return Math.atan2(dy, dx) * 180 / Math.PI;
	}

	private int GetSlideDirection(float startX, float startY, float endX, float endY) {
		float dy = startY - endY;
		float dx = endX - startX;
		int result = 0; // 没有滑动
		// 如果滑动距离太短
		if (Math.abs(dx) < 2 && Math.abs(dy) < 2) {
			return result;
		}
		double angle = GetSlideAngle(dx, dy);
		if (angle >= -45 && angle < 45) {
			return 1; // 向右滑动
		} else if (angle >= 45 && angle < 135) {
			return 2; // 向上滑动
		} else if (angle >= -135 && angle < -45) {
			return 4; // 向下滑动
		} else if ((angle >= 135 && angle <= 180) || (angle >= -180 && angle < -135)) {
			return 3; // 向左滑动
		}
		return result;
	}

	public void reset(int a[][]) {
		int i, j;
		for (i = 0; i < 4; i++) {
			for (j = 0; j < 4; j++) {
				a[i][j] = 0;
			}
		}
		score = 0;
		/**
		 * 回显数据
		 */
		Map<String, String> userInfoMap = savedata.getUserInfo();
		if (userInfoMap != null) {
			mBestScore.setText(userInfoMap.get("BestScore"));
		}
		updateState(a, score, bestscore);
	}

	/**
	 * 实时更新textview属性
	 * @param a
	 * @param Score
	 * @param BestScore
	 */
	public static void updateState(int[][] a, int Score, int BestScore) {
		updateTextViewState(a[0][0], mtextview00);
		updateTextViewState(a[0][1], mtextview01);
		updateTextViewState(a[0][2], mtextview02);
		updateTextViewState(a[0][3], mtextview03);

		updateTextViewState(a[1][0], mtextview10);
		updateTextViewState(a[1][1], mtextview11);
		updateTextViewState(a[1][2], mtextview12);
		updateTextViewState(a[1][3], mtextview13);

		updateTextViewState(a[2][1], mtextview21);
		updateTextViewState(a[2][2], mtextview22);
		updateTextViewState(a[2][3], mtextview23);
		updateTextViewState(a[2][0], mtextview20);

		updateTextViewState(a[3][0], mtextview30);
		updateTextViewState(a[3][1], mtextview31);
		updateTextViewState(a[3][2], mtextview32);
		updateTextViewState(a[3][3], mtextview33);

		mScore.setText(Score + "");
		mBestScore.setText(BestScore + "");
	}

	public static void updateTextViewState(int role, TextView textview) {
		switch (role) {
		case 2:
			textview.setText("2");
			textview.setBackgroundColor(Color.parseColor("#EEE4DA"));
			break;
		case 4:
			textview.setText("4");
			textview.setBackgroundColor(Color.parseColor("#EDE0C8"));
			break;
		case 8:
			textview.setText("8");
			textview.setBackgroundColor(Color.parseColor("#F2B179"));
			break;
		case 16:
			textview.setText("16");
			textview.setBackgroundColor(Color.parseColor("#F49563"));
			break;
		case 32:
			textview.setText("32");
			textview.setBackgroundColor(Color.parseColor("#F5794D"));
			break;
		case 64:
			textview.setText("64");
			textview.setBackgroundColor(Color.parseColor("#F55D37"));
			break;
		case 128:
			textview.setText("128");
			textview.setBackgroundColor(Color.parseColor("#EEE863"));
			break;
		case 256:
			textview.setText("256");
			textview.setBackgroundColor(Color.parseColor("#EDB04D"));
			break;
		case 512:
			textview.setText("512");
			textview.setBackgroundColor(Color.parseColor("#ECB04D"));
			break;
		case 1024:
			textview.setText("1024");
			textview.setBackgroundColor(Color.parseColor("#EB9437"));
			break;
		case 2048:
			textview.setText("2048");
			textview.setBackgroundColor(Color.parseColor("#EA7821"));
			break;
		default:
			textview.setText("");
			textview.setBackgroundColor(Color.parseColor("#CCC0B3"));
			break;
		}
	}

	/**
	 * 对话框
	 * @param winorlose
	 */
	protected void dialog(String winorlose) {
		AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
		builder.setMessage(winorlose);

		builder.setTitle("提示");

		builder.setPositiveButton("重新开始", new OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				reset(a);
				mScore.setText("0");
				dialog.dismiss();
			}
		});

		builder.setNegativeButton("关闭游戏", new OnClickListener() {

			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
				finish();
			}
		});
		builder.create().show();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
}

3.行为动作相关

package com.ldgforever.action;

import com.ldgforever.randomcreate.randomCreate;
import com.ldgforever.savedata.savedata;
import com.ldgforever.twozerofourdight.MainActivity;

import android.content.SharedPreferences;
import android.widget.TextView;

public class Action {

	static int t;

	static void up_remove_blank(int[][] a) {
		int i, j, k;
		for (j = 0; j < 4; j++) {
			for (i = 1; i < 4; i++) {
				k = i;
				while (k - 1 >= 0 && a[k - 1][j] == 0) {// 上面的那个为空
					t = a[k][j];
					a[k][j] = a[k - 1][j];
					a[k - 1][j] = t;
					k--;

				}
			}
		}

	}

	static void down_remove_blank(int a[][]) {
		int i, j, k;
		for (j = 0; j < 4; j++) {
			for (i = 2; i >= 0; i--) {
				k = i;
				while (k + 1 <= 3 && a[k + 1][j] == 0) {// 上面的那个为空
					t = a[k][j];
					a[k][j] = a[k + 1][j];
					a[k + 1][j] = t;
					k++;
				}
			}
		}
	}

	static void left_remove_blank(int a[][]) {
		int i, j, k;
		for (i = 0; i < 4; i++) {
			for (j = 1; j < 4; j++) {
				k = j;
				while (k - 1 >= 0 && a[i][k - 1] == 0) {// 上面的那个为空
					t = a[i][k];
					a[i][k] = a[i][k - 1];
					a[i][k - 1] = t;
					k--;
				}
			}
		}
	}

	static void right_remove_blank(int a[][]) {
		int i, j, k;
		for (i = 0; i < 4; i++) {
			for (j = 2; j >= 0; j--) {
				k = j;
				while (k + 1 <= 3 && a[i][k + 1] == 0) {// 上面的那个为空
					t = a[i][k];
					a[i][k] = a[i][k + 1];
					a[i][k + 1] = t;
					k++;
				}
			}
		}
	}

	static void left(int a[][]) {
		int i, j;
		for (i = 0; i < 4; i++) {
			for (j = 0; j < 3; j++) {
				if (a[i][j] == a[i][j + 1]) {
					a[i][j] += a[i][j + 1];
					if (a[i][j] != 0) {
						MainActivity.score += 2;
						updatecore(MainActivity.score, MainActivity.bestscore);
					}
					a[i][j + 1] = 0;
					left_remove_blank(a);
				}
			}
		}
	}

	static void up(int a[][]) {
		int i, j;
		for (j = 0; j < 4; j++) {
			for (i = 0; i < 3; i++) {
				if (a[i][j] == a[i + 1][j]) {
					a[i][j] += a[i + 1][j];
					if (a[i][j] != 0) {
						MainActivity.score += 2;
						updatecore(MainActivity.score, MainActivity.bestscore);
					}
					a[i + 1][j] = 0;
					up_remove_blank(a);
				}
			}
		}
	}

	static void right(int a[][]) {
		int i, j;
		for (i = 0; i < 4; i++) {
			for (j = 3; j >= 1; j--) {
				if (a[i][j] == a[i][j - 1]) {
					a[i][j] += a[i][j - 1];
					if (a[i][j] != 0) {
						MainActivity.score += 2;
						updatecore(MainActivity.score, MainActivity.bestscore);
					}
					a[i][j - 1] = 0;
					right_remove_blank(a);
				}
			}
		}
	}

	static void down(int a[][]) {
		int i, j;
		for (j = 0; j < 4; j++) {
			for (i = 3; i >= 1; i--) {
				if (a[i][j] == a[i - 1][j]) {
					a[i][j] += a[i - 1][j];
					if (a[i][j] != 0) {
						MainActivity.score += 2;
						updatecore(MainActivity.score, MainActivity.bestscore);
					}
					a[i - 1][j] = 0;
					down_remove_blank(a);
				}
			}
		}
	}

	static boolean isFailure(int a[][]) {
		int i, j;
		for (i = 0; i < 4; i++) {
			for (j = 0; j < 4; j++) {
				if (a[i][j] == 0) {
					return false;
				}
			}
		}
		return true;
	}

	static boolean isWin(int a[][]) {
		int i, j;
		for (i = 0; i < 4; i++) {
			for (j = 0; j < 4; j++) {
				if (a[i][j] == 2048) {
					return true;
				}
			}
		}
		return false;
	}

	public static void updatecore(int score, int bestscore) {
		if (MainActivity.score > MainActivity.bestscore) {
			MainActivity.bestscore = MainActivity.score;
			savedata.saveUserInfo(MainActivity.bestscore);
		}
	}

	public static int Slide(int direction, int a[][]) {
		if (direction == 3) {
			left_remove_blank(a);
			left(a);
			MainActivity.updateState(a, MainActivity.score, MainActivity.bestscore);
			if (isWin(a))
				return 0;
			else if (isFailure(a))
				return 1;
			else {
				String index = randomCreate.searchforZERO(a);
				randomCreate.randomCreate(a, index);
				MainActivity.updateState(a, MainActivity.score, MainActivity.bestscore);
			}
		} else if (direction == 1) {
			right_remove_blank(a);
			right(a);
			if (isWin(a))
				return 0;
			else if (isFailure(a))
				return 1;
			else {
				String index = randomCreate.searchforZERO(a);
				randomCreate.randomCreate(a, index);
				MainActivity.updateState(a, MainActivity.score, MainActivity.bestscore);
			}
		} else if (direction == 2) {
			up_remove_blank(a);
			up(a);
			if (isWin(a))
				return 0;
			else if (isFailure(a))
				return 1;
			else {
				String index = randomCreate.searchforZERO(a);
				randomCreate.randomCreate(a, index);
				MainActivity.updateState(a, MainActivity.score, MainActivity.bestscore);
			}
		} else if (direction == 4) {
			down_remove_blank(a);
			down(a);
			if (isWin(a))
				return 0;
			else if (isFailure(a))
				return 1;
			else {
				String index = randomCreate.searchforZERO(a);
				randomCreate.randomCreate(a, index);
				MainActivity.updateState(a, MainActivity.score, MainActivity.bestscore);
			}
		}
		return 2;
	}
}

4.生成2,4的随机数  2与4之比约为9:1

package com.ldgforever.randomcreate;

public class randomCreate {

	public static int[][] randomCreate(int a[][], String index) {
		String[] b = index.split("####");
		int random = (int) (Math.random() * (b.length - 1));
		String[] c = b[random].split("##");
		if (Math.random() > 0.1) {
			a[Integer.parseInt(c[0])][Integer.parseInt(c[1])] = 2;
		} else {
			a[Integer.parseInt(c[0])][Integer.parseInt(c[1])] = 4;
		}
		return a;
	}

	public static String searchforZERO(int a[][]) {
		int i, j;
		String index = "";
		for (i = 0; i < 4; i++) {
			for (j = 0; j < 4; j++) {
				if (a[i][j] == 0) {
					index = i + "##" + j + "####" + index;
				}
			}
		}
		return index;
	}

}

5.数据的存储与回显

package com.ldgforever.savedata;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

import android.os.Environment;
import android.text.TextUtils;

public class savedata {

	/**
	 * 保存Score
	 * 
	 * @return
	 */
	public static boolean saveUserInfo(int BestScore) {

		File BSFile = Environment.getDataDirectory();
		File file = new File(BSFile, "BestScore.txt");
		// String path =
		// "/data/data/com.ldgforever.twozerofourdight/BestScore.txt";
		try {
			FileOutputStream fos = new FileOutputStream(file);
			String data = "##" + BestScore;
			fos.write(data.getBytes());
			fos.flush();
			fos.close();
			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 读取用户输入文件
	 * 
	 * @return
	 */
	public static Map<String, String> getUserInfo() {

		File BSFile = Environment.getDataDirectory();
		File file = new File(BSFile, "BestScore.txt");
		// String path =
		// "/data/data/com.ldgforever.twozerofourdight/BestScore.txt";
		try {
			FileInputStream fis = new FileInputStream(file);
			BufferedReader reader = new BufferedReader(new InputStreamReader(fis)); // 构建字符流对象
			String text = reader.readLine();
			reader.close();
			if (!TextUtils.isEmpty(text)) {
				String[] split = text.split("##");
				Map<String, String> userInfoMap = new HashMap<String, String>();
				userInfoMap.put("Score", split[0]);
				userInfoMap.put("BestScore", split[1]);
				return userInfoMap;
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}

最终效果:




原文地址:https://www.cnblogs.com/ldgforever/p/5854099.html