• android 2048游戏实现


    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("");
    				// 设置该button的字号大小
    				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();
    	}
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		init();
    	}
    
    	@Override
    	public 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下载:








  • 相关阅读:
    Windows SDK编程(Delphi版) 之 应用基础,楔子
    一个小问题引发的论证思考
    Delphi 组件开发教程指南(7)继续模拟动画显示控件
    用PyInstaller将python转成可执行文件exe笔记
    使用 .Net Memory Profiler 诊断 .NET 应用内存泄漏(方法与实践)
    Microsof Office SharePoint 2007 工作流开发环境搭建
    How to monitor Web server performance by using counter logs in System Monitor in IIS
    LINQ之Order By
    window 性能监视器
    内存泄露检测工具
  • 原文地址:https://www.cnblogs.com/yfceshi/p/6979667.html
Copyright © 2020-2023  润新知