完成了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;
}
}
最终效果: