android 2048游戏实现

来源:互联网 发布:什么叫java参数传递 编辑:程序博客网 时间:2024/05/02 05:05

android 的2048小游戏完整实现:GridLayout布局(android 4.0及以上)。

以前做过一个2048的算法题,学了几天android,觉得可以实现个安卓版的,也就动手写了个。

包含的东西:

GridLayout布局

在activity中动态添加view组件

判断用户在屏幕滑动的的方向

2048算法(参考之前用C++写的,写的还算通俗易懂吧,http://blog.csdn.net/liang5630/article/details/39895087)。

不多说,先上图:



package com.example.y2048;import android.annotation.SuppressLint;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.MotionEvent;import android.view.View;import android.widget.Button;import android.widget.GridLayout;import android.widget.TextView;import android.widget.Toast;import com.example.y2048.map.Direction;import com.example.y2048.map.Maps;public class MainActivity extends Activity {private String tag = "GridLayoutActivity";GridLayout gridLayout;float startX = 0, startY = 0, endX, endY;Maps maps = new Maps();private TextView score;private TextView best;@SuppressLint("NewApi")void init() {// 获取View对象gridLayout = (GridLayout) findViewById(R.id.root);for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {Button bn = new Button(this);bn.setClickable(false);bn.setText("");// 设置该按钮的字号大小bn.setTextSize(30);bn.setWidth(120);bn.setHeight(120);// 指定该组件所在的行GridLayout.Spec rowSpec = GridLayout.spec(i + 2);// 指定该组件所在的列GridLayout.Spec columnSpec = GridLayout.spec(j);String msg = "rowSpec:" + (i + 2) + " - columnSpec:" + (j);Log.d(tag, msg);GridLayout.LayoutParams params = new GridLayout.LayoutParams(rowSpec, columnSpec);// 指定该组件占满容器// params.setGravity(Gravity.FILL);gridLayout.addView(bn, params);maps.addButton(i, j, bn);}}score = (TextView) findViewById(R.id.score);score.setText("0");best = (TextView) findViewById(R.id.best);maps.setScore(score);maps.setBest(best);maps.init();}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();}@Overridepublic boolean dispatchTouchEvent(MotionEvent event) {// System.out.println("触摸");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);// System.out.println(startX+","+startY+"|"+endX+","+endY+"  "+direction);// Toast.makeText(this, direction+"", Toast.LENGTH_LONG).show();boolean gameOver = maps.Slide(direction);if (gameOver) {if(maps.getScore()>maps.getBestScore()){Toast.makeText(this, "恭喜超过最佳记录!!!", Toast.LENGTH_SHORT).show();maps.setBestScore(maps.getScore());best.setText(maps.getScore()+"");}else{Toast.makeText(this, "GameOver", Toast.LENGTH_SHORT).show();}}}return super.dispatchTouchEvent(event);}// 返回角度private double GetSlideAngle(float dx, float dy) {return Math.atan2(dy, dx) * 180 / Math.PI;}// 根据起点和终点返回方向 1:向上,2:向下,3:向左,4:向右,0:未滑动private int GetSlideDirection(float startX, float startY, float endX,float endY) {float dy = startY - endY;float dx = endX - startX;int result = Direction.NONE;// 如果滑动距离太短if (Math.abs(dx) < 2 && Math.abs(dy) < 2) {return result;}double angle = GetSlideAngle(dx, dy);if (angle >= -45 && angle < 45) {return Direction.RIGHT;} else if (angle >= 45 && angle < 135) {return Direction.UP;} else if (angle >= -135 && angle < -45) {return Direction.DOWN;} else if ((angle >= 135 && angle <= 180)|| (angle >= -180 && angle < -135)) {return Direction.LEFT;}return result;}public void reset(View view) {maps.init();}}


package com.example.y2048.map;public interface Direction {//1:向上,2:向下,3:向左,4:向右,0:未滑动static final int LEFT=3;static final int RIGHT=4;static final int UP=1;static final int DOWN=2;static final int NONE=0;}

package com.example.y2048.map;import java.util.Random;import android.content.Context;import android.content.SharedPreferences;import android.content.SharedPreferences.Editor;import android.view.View;import android.widget.Button;import android.widget.TextView;public class Maps {private TextView score;private TextView best;private Button[][] maps = new Button[4][4];public void addButton(int i, int j, Button btn) {maps[i][j] = btn;}private void swapText(Button btn1, Button btn2) {CharSequence text = btn1.getText();btn1.setText(btn2.getText());btn2.setText(text);}void up_remove_blank() {int i, j, k;for (j = 0; j < 4; j++) {for (i = 1; i < 4; i++) {k = i;while (k - 1 >= 0&& maps[k - 1][j].getText().toString().length() == 0) {// 上面的那个为空swapText(maps[k][j], maps[k - 1][j]);k--;}}}}void down_remove_blank() {int i, j, k;for (j = 0; j < 4; j++) {for (i = 2; i >= 0; i--) {k = i;while (k + 1 <= 3&& maps[k + 1][j].getText().toString().length() == 0) {// 上面的那个为空swapText(maps[k][j], maps[k + 1][j]);k++;}}}}void left_remove_blank() {int i, j, k;for (i = 0; i < 4; i++) {for (j = 1; j < 4; j++) {k = j;while (k - 1 >= 0&& maps[i][k - 1].getText().toString().length() == 0) {// 上面的那个为空swapText(maps[i][k], maps[i][k - 1]);k--;}}}}void right_remove_blank() {int i, j, k;for (i = 0; i < 4; i++) {for (j = 2; j >= 0; j--) {k = j;while (k + 1 <= 3&& maps[i][k + 1].getText().toString().length() == 0) {// 上面的那个为空swapText(maps[i][k], maps[i][k + 1]);k++;}}}}void left() {int i, j;for (i = 0; i < 4; i++) {for (j = 0; j < 3; j++) {String s1 = maps[i][j].getText().toString();String s2 = maps[i][j + 1].getText().toString();if (s1.equals(s2) && !s1.equals("")) {// maps[i][j]+=maps[i][j+1];Integer sum = Integer.valueOf(maps[i][j].getText().toString());sum += Integer.valueOf(maps[i][j + 1].getText().toString());int total = Integer.valueOf(score.getText().toString());score.setText(String.valueOf(sum + total));maps[i][j].setText(sum.toString());maps[i][j + 1].setText("");left_remove_blank();}}}}void right() {int i, j;for (i = 0; i < 4; i++) {for (j = 3; j >= 1; j--) {String s1 = maps[i][j].getText().toString();String s2 = maps[i][j - 1].getText().toString();if (s1.equals(s2) && !s1.equals("")) {// maps[i][j]+=maps[i][j-1];// maps[i][j-1]=0;Integer sum = Integer.valueOf(maps[i][j].getText().toString());sum += Integer.valueOf(maps[i][j - 1].getText().toString());int total = Integer.valueOf(score.getText().toString());score.setText(String.valueOf(sum + total));maps[i][j].setText(sum.toString());maps[i][j - 1].setText("");right_remove_blank();}}}}void up() {int i, j;for (j = 0; j < 4; j++) {// 每一列for (i = 0; i < 3; i++) {String s1 = maps[i][j].getText().toString();String s2 = maps[i + 1][j].getText().toString();if (s1.equals(s2) && !s1.equals("")) {// maps[i][j]=maps[i][j]+maps[i+1][j];// maps[i+1][j]=0;Integer sum = Integer.valueOf(maps[i][j].getText().toString());sum += Integer.valueOf(maps[i + 1][j].getText().toString());int total = Integer.valueOf(score.getText().toString());score.setText(String.valueOf(sum + total));maps[i][j].setText(sum.toString());maps[i + 1][j].setText("");// 移除空格up_remove_blank();}}}}void down() {int i, j;for (j = 0; j < 4; j++) {// 每一列for (i = 3; i >= 1; i--) {String s1 = maps[i][j].getText().toString();String s2 = maps[i - 1][j].getText().toString();if (s1.equals(s2) && !s1.equals("")) {// maps[i][j]=maps[i][j]+maps[i-1][j];// maps[i-1][j]=0;Integer sum = Integer.valueOf(maps[i][j].getText().toString());sum += Integer.valueOf(maps[i - 1][j].getText().toString());int total = Integer.valueOf(score.getText().toString());score.setText(String.valueOf(sum + total));maps[i][j].setText(sum.toString());maps[i - 1][j].setText("");// 移除空格down_remove_blank();}}}}private void addNumber() {Random random = new Random();int x = random.nextInt(4);int y = random.nextInt(4);int number = random.nextInt(20);//出现2的概率为95% 4的概率5%if(number==0) number=4;else number=2;while (maps[x][y].getText().toString().length() != 0) {x = random.nextInt(4);y = random.nextInt(4);}maps[x][y].setText(number + "");}public void init() {for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {maps[i][j].setText("");}}score.setText("0");addNumber();addNumber();}private boolean isFull() {for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {if (maps[i][j].getText().toString().length() == 0) {return false;}}}return true;}public boolean Slide(int direction) {if (direction == Direction.LEFT) {left_remove_blank();left();if (isFull())return true;else {addNumber();}} else if (direction == Direction.RIGHT) {right_remove_blank();right();if (isFull())return true;else {addNumber();}} else if (direction == Direction.UP) {up_remove_blank();up();if (isFull())return true;else {addNumber();}} else if (direction == Direction.DOWN) {down_remove_blank();down();if (isFull())return true;else {addNumber();}}return false;}public void setScore(TextView score) {this.score = score;}public void setBest(TextView best) {this.best = best;best.setText(getBestScore()+"");}public int getScore(){return Integer.valueOf(score.getText().toString());}public int getBestScore(){SharedPreferences sp = best.getContext().getSharedPreferences("bestScore.txt", Context.MODE_PRIVATE);int bestScore=sp.getInt("bestScore", 0);return bestScore;}public void setBestScore(int score){SharedPreferences sp = best.getContext().getSharedPreferences("bestScore.txt", Context.MODE_PRIVATE);Editor edit = sp.edit();edit.putInt("bestScore", score);edit.commit();}}

<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/root"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:columnCount="4"    android:rowCount="6"    tools:ignore="NewApi" >    <TextView        android:layout_width="wrap_content"        android:layout_height="50dp"        android:layout_marginLeft="4dp"        android:layout_marginRight="4dp"        android:gravity="center"        android:text="Score:" />    <TextView        android:id="@+id/score"        android:layout_width="wrap_content"        android:layout_height="50dp"        android:layout_marginLeft="4dp"        android:layout_marginRight="4dp"        android:gravity="center"        android:text="Score:" />    <TextView        android:layout_width="wrap_content"        android:layout_height="50dp"        android:gravity="center"        android:text="Best:" />    <TextView        android:id="@+id/best"        android:layout_width="wrap_content"        android:layout_height="50dp"        android:gravity="center" />    <Button        android:layout_width="wrap_content"        android:layout_height="40dp"        android:layout_columnSpan="4"        android:onClick="reset"        android:text="reset" /></GridLayout>


转载请注明出处:http://blog.csdn.net/liang5630/article/details/41251549

源码及apk下载:








8 1