zoukankan      html  css  js  c++  java
  • 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下载:








  • 相关阅读:
    抽取幸运观众
    随机产生139开头的电话号码
    脚本同步服务器系统时间
    判断网页是否存活
    nginx 添加到环境变量中
    spring boot helloworld
    IDEA 2019.3.3 Maven配置
    Window IDEA ULTIMATE 2019.3.3 安装&配置
    centos 7 Jenkins版本升级
    window 10 vscode+vue配置
  • 原文地址:https://www.cnblogs.com/yfceshi/p/6979667.html
Copyright © 2011-2022 走看看