2048(Android)

整个页面分为三个部分:

1)GridLayout:存放两个TextView(【score】以及当前所得分数数值)

2)自定义控件GameView(GridLayout):4*4方格,每个方格中存放一个TextView(用于存放num)

3)Button重新开始



代码:

Main:

package com.example.project2048;

import com.example.project2048.R;  //加入自定义控件

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener{
	private int score = 0;
	private TextView tvScore;   //定义一个文本框,用于存储所得分数
	private static  MainActivity mainActivity = null;
	private GameView gameView;   //自定义控件(4*4卡片的操作,即游戏主体)
	private Button btRestart;  //按钮"重新开始"
	public MainActivity(){
		mainActivity = this;
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		tvScore = (TextView) findViewById(R.id.tvScore);  //实例化(卡片移动函数可调用)
		gameView = (GameView) findViewById(R.id.gameView);
		btRestart = (Button) findViewById(R.id.btRestart);
		btRestart.setOnClickListener(this);
	}
	public static MainActivity getMainActivity(){
		return mainActivity;
	}
	
	public void showScore(){
		tvScore.setText(score+"");
	}
	public void addScore(int s){  //分数计算
		score += s;
		showScore();
	}

	public void clearScore(){  //分数清0
		score = 0;
		showScore();
	}

	@Override
	public void onClick(View v) {
		gameView.restartGame();
	}
}


GameView:

package com.example.project2048;

import java.util.ArrayList;
import java.util.List;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.GridLayout;
import android.widget.Toast;

/*
 * 自定义控件:
 * 1.新建一个类,继承view/view的子类    *增加相应的构造方法
 * 2.在布局文件中加入该类   *使用全类名
 */
public class GameView extends GridLayout {
	
	private Card[][] cardsMap = new Card[4][4];   //存储4*4方格中的数字
	private List<Point> lists = new ArrayList<Point>();

	public GameView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		initGame(); 
	}
	
	private void initGame(){   //初始化
		setColumnCount(4);   //设置4行4列
		setBackgroundColor(0xffbbada0);   //设置背景颜色
		setOnTouchListener(new OnTouchListener() {   //(手指)移动监听
			private float startX,startY,offsetX,offsetY;
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				// TODO Auto-generated method stub
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:    //(手指)按下
					//获取当前位置坐标
					startX = event.getX();
					startY = event.getY();
					break;
				case MotionEvent.ACTION_UP:      //(手指)抬起
					//获取手指X,Y轴的位移(有方向)
					offsetX = event.getX() - startX;
					offsetY = event.getY() - startY;
					/*判断手指移动方向(上下左右)
					 *(-5,5)为误差范围内(误差:eg.手指不小心滑动) 
					 */
					if (Math.abs(offsetX) > Math.abs(offsetY)) {
						if (offsetX < -5) {
							swipeLeft();
							//Toast.makeText(getContext(), "向左滑动", Toast.LENGTH_LONG).show();
						} else if(offsetX > 5) {
							swipeRight();
							//Toast.makeText(getContext(), "向右滑动", Toast.LENGTH_LONG).show();
						}
					}else {
						if (offsetY < -5) {
							swipeUp();
							//Toast.makeText(getContext(), "向上滑动", Toast.LENGTH_LONG).show();
						}else if (offsetY > 5) {
							swipeDown();
							//Toast.makeText(getContext(), "向下滑动", Toast.LENGTH_LONG).show();
						}
						
					}
				
					break;
				}
				return true;
			}
		});
	}
	
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		// TODO Auto-generated method stub
		super.onSizeChanged(w, h, oldw, oldh);
		int cardWidth = (Math.min(w, h)-10)/4; //获取卡片大小
		addCard(cardWidth, cardWidth);
		startGame();
	}
	
	private void addCard(int cardWidth,int cardHeigh){
		Card c;
		//遍历方格,将文本框添加至方格中
		for (int y = 0; y < 4; y++) {
			for (int x = 0; x < 4; x++) {
				c = new Card(getContext());
			//	c.setNum(0);
				addView(c, cardWidth, cardHeigh);
				cardsMap[x][y] = c;
			}
		}
	}
	
	private void startGame(){   //游戏开始
		MainActivity.getMainActivity().clearScore();   //分数清0
		for (int y = 0; y < 4; y++) {
			for (int x = 0; x < 4; x++) {
				cardsMap[x][y].setNum(0);   //4*4方格上的数字全部置为0
			}
		}
		//添加两个随机数
		addRandomNum();
		addRandomNum();
	}
	private void addRandomNum(){   //添加随机数
		lists.clear();
		//遍历4*4方格,寻找空白方格(即数字为0的)
		for (int y = 0; y < 4; y++) {
			for (int x = 0; x < 4; x++) {
				if (cardsMap[x][y].getNum() <= 0) {
					lists.add(new Point(x, y));
				}
			}
		}
		Point p = lists.remove((int)(Math.random()*lists.size()));  //避免越界
		cardsMap[p.x][p.y].setNum(Math.random()>0.1 ? 2 : 4);//9:1
	}
	//上下左右移动
	private void swipeLeft(){   //左移
		boolean add = false;
		 for (int y = 0; y < 4; y++) {
			for (int x = 0; x < 4; x++) {
				for (int x1 = x+1; x1 < 4; x1++) {
					if (cardsMap[x1][y].getNum() > 0) {  //右边存在不为空(不为0)的卡片
						//左边卡片为空(为0),右边卡片左移
						if (cardsMap[x][y].getNum()<=0) {
							cardsMap[x][y].setNum(cardsMap[x1][y].getNum());
							cardsMap[x1][y].setNum(0);
							x--;
							add = true;
						} 
						//左边卡片与右边卡片值相等,右边移至左边叠加
						else if(cardsMap[x][y].equals(cardsMap[x1][y])) {
							cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2);
							cardsMap[x1][y].setNum(0);
							MainActivity.getMainActivity().addScore(cardsMap[x][y].getNum()); //分数相应增加
							add = true;
						}
						break;
					}
				}
			}
		}
		 if (add) {
			addRandomNum();  //移动后添加随机数
			endGame();   //判断游戏是否结束
		}
	}
	
	private void swipeRight(){   //右移
		boolean add = false;
		for (int y = 0; y < 4; y++) {
			for (int x = 3; x >=0 ; x--) {
				for (int x1 = x-1; x1 >=0; x1--) {
					if (cardsMap[x1][y].getNum() > 0) {
						if (cardsMap[x][y].getNum() <=0) {
							cardsMap[x][y].setNum(cardsMap[x1][y].getNum());
							cardsMap[x1][y].setNum(0);
							x++;
							add = true;
						}else if (cardsMap[x][y].equals(cardsMap[x1][y])) {
							cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2);
							cardsMap[x1][y].setNum(0);
							MainActivity.getMainActivity().addScore(cardsMap[x][y].getNum());
							add = true;
						}
						break;
					}
				}
			}
		}
		if (add) {
			addRandomNum();
			endGame();
		}
	}
	
	private void swipeUp(){   //上移
		boolean add = false;
		for (int x = 0; x < 4; x++) {
			for (int y = 0; y < 4; y++) {
				for (int y1 = y+1; y1 < 4; y1++) {
					if (cardsMap[x][y1].getNum() > 0) {
						if (cardsMap[x][y].getNum() <= 0) {
							cardsMap[x][y].setNum(cardsMap[x][y1].getNum());
							cardsMap[x][y1].setNum(0);
							y--;
							add = true;
						}else if (cardsMap[x][y].equals(cardsMap[x][y1])) {
							cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2);
							cardsMap[x][y1].setNum(0);
							MainActivity.getMainActivity().addScore(cardsMap[x][y].getNum());
							add = true;
						}
						break;
					}
				}
			}
		}
		if (add) {
			addRandomNum();
			endGame();
		}
	}
	
	private void swipeDown(){   //下移
		boolean add = false;
		for (int x = 0; x < 4; x++) {
			for (int y = 3; y >=0; y--) {
				for (int y1 = y-1; y1 >=0; y1--) {
					if (cardsMap[x][y1].getNum() > 0) {
						if (cardsMap[x][y].getNum()<=0) {
							cardsMap[x][y].setNum(cardsMap[x][y1].getNum());
							cardsMap[x][y1].setNum(0);
							y++;
							add = true;
						}else if (cardsMap[x][y].equals(cardsMap[x][y1])) {
							cardsMap[x][y].setNum(cardsMap[x][y].getNum()*2);
							cardsMap[x][y1].setNum(0);
							MainActivity.getMainActivity().addScore(cardsMap[x][y].getNum());
							add = true;
						}
						break;
					}
				}
			}
		}
		if (add) {
			addRandomNum();
			endGame();
		}
	}
	
	private void endGame(){   //判断游戏是否结束
		boolean complete = true;
		
		ALL:for (int y = 0; y < 4; y++) {
			for (int x = 0; x < 4; x++) {
				//卡片仍有为空(为0),或连续两张有值相等的,则游戏继续
				if (cardsMap[x][y].getNum() == 0
						||(x > 0 && cardsMap[x][y].equals(cardsMap[x-1][y]))
						||(x < 3 && cardsMap[x][y].equals(cardsMap[x+1][y]))
						||(y > 0 && cardsMap[x][y].equals(cardsMap[x][y-1]))
						||(y < 3 && cardsMap[x][y].equals(cardsMap[x][y+1]))) {
					complete = false;
					break ALL;
				}
			}
		}//ALL:有一个条件满足循环即中断,提高效率
		if (complete) {  //若游戏结束
			new AlertDialog.Builder(getContext())   //弹出提示对话框
			.setTitle("你好!")
			.setMessage("游戏结束")
			//为“重新开始”按钮设置监听事件
			.setPositiveButton("重新开始", new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					// TODO Auto-generated method stub
					startGame();
				}
			}).show();
		}
	}
	
	public void restartGame(){   //重新开始游戏
		MainActivity.getMainActivity().clearScore();  //分数清0
		//遍历4*4方格,将值不为0的所有卡片置为0
		for (int y = 0; y < 4; y++) {
			for (int x = 0; x < 4; x++) {
				if (cardsMap[x][y] ==null) {
					continue;
				}
				cardsMap[x][y].setNum(0);
			}
		}
		//添加两个随机数
		addRandomNum();
		addRandomNum();
	}

}


Card:

package com.example.project2048;

import android.content.Context;
import android.graphics.Color;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.widget.TextView;

public class Card extends FrameLayout {
	private TextView tv;  //文本框(卡片中存放数值)
	private int num = 0;
	
	public Card(Context context) {
		super(context);
		tv = new TextView(getContext());
		tv.setTextSize(32);
		tv.setGravity(Gravity.CENTER);  //在方格中居中放置
		tv.setBackgroundColor(0x33ffffff);   
		LayoutParams params = new LayoutParams(-1, -1);
		params.setMargins(10, 10, 0, 0);
		addView(tv, params);  //将文本框添加至方格上
	}

	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
		//根据卡片上的值不同,设置相应卡片背景颜色
		if (num <= 0) {
			tv.setBackgroundColor(0x33ffffff);
			tv.setText("");   //若卡片值为0,则不显示数值
		} else {
			if(num == 2)
				tv.setBackgroundColor(Color.parseColor("#CDB79E"));//深灰
			if(num == 4)
				tv.setBackgroundColor(Color.parseColor("#CDB38B"));//加深灰
			if(num == 8)
				tv.setBackgroundColor(Color.parseColor("#FF8C00"));//橙色
			if(num == 16)
				tv.setBackgroundColor(Color.parseColor("#FF7F00"));//橙色
			if(num == 32)
				tv.setBackgroundColor(Color.parseColor("#FF4500"));//桔红
			if(num == 64)
				tv.setBackgroundColor(Color.parseColor("#FF0000"));//红
			if(num == 128)
				tv.setBackgroundColor(Color.parseColor("#FFF68F"));//浅桔
			
			/*tv.setText(num);
			 * tv.setText(num+"");
			 * 方法重载(int/char)
			 */
			tv.setText(num+"");  
		}
		
	}
	
	public boolean equals(Card c) {
		return this.getNum()==c.getNum();
	}
	

}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值