Android编写2048小游戏规则

释放双眼,带上耳机,听听看~!

 

先来说说2048游戏规则:

开始时棋盘内随机出现两个数字,出现的数字仅可能为2或4

玩家可以选择上下左右四个方向,若棋盘内的数字出现位移或合并,视为有效移动

玩家选择的方向上若有相同的数字则合并,每次有效移动可以同时合并,但不可以连续合并

合并所得的所有新生成数字想加即为该步的有效得分

玩家选择的方向行或列前方有空格则出现位移

每有效移动一步,棋盘的空位(无数字处)随机出现一个数字(依然可能为2或4)

棋盘被数字填满,无法进行有效移动,判负,游戏结束

棋盘上出现2048,判胜,游戏结束

下面代码

MainActivity类

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new GameView(this));
}
}

定义一个卡片类显示数据

/卡片类型
public class Card extends FrameLayout {
//2
TextView tv;
private int number = 0;
int width;
public Card(Context context, int width) {
super(context);
this.width = width;
init();
}
private void init() {
tv = new TextView(getContext());
setPadding(5, 5, 5, 5);
FrameLayout.LayoutParams lp = new LayoutParams(width - 10, width - 10);
tv.setLayoutParams(lp);
tv.setGravity(Gravity.CENTER);
tv.setTextColor(Color.WHITE);
tv.setTextSize(48);
this.addView(tv);
setColor();
}
public void setNumber(int number) {
this.number = number;
if (number == 0)
tv.setText("");
else
tv.setText(number + "");
setColor();
}
@Override
public String toString() {
return "Card{" +
"tv=" + tv +
", number=" + number +
", width=" + width +
'}';
}
private void setColor() {
switch (number) {
case 0:
tv.setBackgroundColor(getResources().getColor(R.color.c0));
break;
case 2:
tv.setBackgroundColor(getResources().getColor(R.color.c2));
break;
case 4:
tv.setBackgroundColor(getResources().getColor(R.color.c4));
break;
case 8:
tv.setBackgroundColor(getResources().getColor(R.color.c8));
break;
case 16:
tv.setBackgroundColor(getResources().getColor(R.color.c16));
break;
case 32:
tv.setBackgroundColor(getResources().getColor(R.color.c32));
break;
case 64:
tv.setBackgroundColor(getResources().getColor(R.color.c64));
break;
case 128:
tv.setBackgroundColor(getResources().getColor(R.color.c128));
break;
case 256:
tv.setBackgroundColor(getResources().getColor(R.color.c256));
break;
case 512:
tv.setBackgroundColor(getResources().getColor(R.color.c512));
break;
case 1024:
tv.setBackgroundColor(getResources().getColor(R.color.c1024));
break;
case 2048:
tv.setBackgroundColor(getResources().getColor(R.color.c2048));
break;
}
}
public int getNumber() {
return number;
}
}

自己定义一下上面的几种颜色 在values下的colors中

<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
<color name="c0">#43382a</color>
<color name="c2">#2a8618</color>
<color name="c4">#3d6319</color>
<color name="c8">#F2B179</color>
<color name="c16">#F59563</color>
<color name="c32">#F57C5F</color>
<color name="c64">#5b69b7</color>
<color name="c128">#b37d3e</color>
<color name="c256">#3a9096</color>
<color name="c512">#d7882c</color>
<color name="c1024">#5c1b78</color>
<color name="c2048">#640548</color>
</resources>

布局类 和里面的运算方法

public class GameView extends GridLayout {
int[][] values = new int[4][4];
Card[][] cards = new Card[4][4];
// Integer -128-127 == 大于这个数 两个对象
public GameView(Context context) {
super(context);
init();
}
public GameView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setColumnCount(4);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
newGame();
}
private void newGame() {
//ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams((int) (getResources().getDisplayMetrics().widthPixels / 4), (int) (getResources().getDisplayMetrics().widthPixels / 4));
GridLayout.LayoutParams params = new GridLayout.LayoutParams();
// params.width = getResources().getDisplayMetrics().widthPixels / 4;
// params.height = getResources().getDisplayMetrics().widthPixels / 4;
//Log.e("TAG", params.width + " " + params.height);
this.removeAllViews();
// GridLayout.LayoutParams lpa = new GridLayout.LayoutParams(lp);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
values[i][j] = 0;
cards[i][j] = new Card(getContext(), getResources().getDisplayMetrics().widthPixels / 4);
// cards[i][j].setLayoutParams(params);
//cards[i][j].upLv();
this.addView(cards[i][j]);
}
}
//创建初始的两张卡
int i = (int) (Math.random() * 16);
int j = 0;
do {
j = (int) (Math.random() * 16);//0-15 15 3 3
} while (j == i);
Log.e("TAG", i + " " + j);
values[i / 4][i % 4] = Math.random() * 20 < 1 ? 4 : 2;
values[j / 4][j % 4] = Math.random() * 20 < 1 ? 4 : 2;
setValues();
}
float oldx, oldy;
int move = -1;
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
move = -1;
oldx = x;
oldy = y;
break;
case MotionEvent.ACTION_MOVE:
if (Math.abs(oldx - x) > Math.abs(oldy - y)) {
if (oldx - x > 15) { //左
Log.e("TAG", "---------->>>");
move = 1;
} else if (oldx - x < -15) {//右
Log.e("TAG", "---------->>>");
move = 2;
}
} else {
if (oldy - y > 15) {
move = 3;
} else if (oldy - y < -15) {
move = 4;
}
}
break;
case MotionEvent.ACTION_UP:
//记录之前的数组
int[][] temp = new int[4][4];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
temp[i][j] = values[i][j];
}
}
switch (move) {
case 1:
left();
break;
case 2:
right();
break;
case 3:
up();
break;
case 4:
down();
break;
}
setValues();
if (move != -1) {
//比对当前的数组
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (values[i][j] != temp[i][j]) {
addCard();
return true;
}
}
}
}
//判断游戏胜利还是结束4
if (isWin()) {
Toast.makeText(getContext(), "游戏胜利", Toast.LENGTH_SHORT).show();
}
if (isOver()) {
this.removeAllViews();
TextView tv = new TextView(getContext());
tv.setText("游戏结束,点击从新开始");
this.addView(tv);
tv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
newGame();
}
});
}
break;
}
return true;
}
private void addCard() {
while (true) {
int j = (int) (Math.random() * 16);
if (values[j / 4][j % 4] == 0) {
values[j / 4][j % 4] = 2;
cards[j / 4][j % 4].setNumber(2);
return;
}
}
}
public void left() {
//取出 4个 集合
for (int i = 0; i < 4; i++) {
List<Integer> list = new ArrayList<>();
for (int j = 0; j < 4; j++) {
int value = values[i][j];
if (value != 0)
list.add(value);
}
//比较
Log.e("TAG", list.toString());
if (list.size() == 0)
continue;
else if (list.size() == 1) {
values[i][0] = list.get(0);
for (int j = 0; j < 3; j++) {
values[i][j + 1] = 0;
}
} else if (list.size() == 2) {
if (list.get(0).equals(list.get(1))) {
values[i][0] = list.get(0) * 2;
//三个值补0
for (int j = 0; j < 3; j++) {
values[i][j + 1] = 0;
}
} else {
values[i][0] = list.get(0);
values[i][1] = list.get(1);
values[i][2] = 0;
values[i][3] = 0;
}
} else if (list.size() == 3) {
if (list.get(0).equals(list.get(1))) {
values[i][0] = list.get(0) * 2;
values[i][1] = list.get(2);
values[i][2] = 0;
values[i][3] = 0;
} else if (list.get(1).equals(list.get(2))) {
values[i][0] = list.get(0);
values[i][1] = list.get(2) * 2;
values[i][2] = 0;
values[i][3] = 0;
} else {
values[i][0] = list.get(0);
values[i][1] = list.get(1);
values[i][2] = list.get(2);
values[i][3] = 0;
}
} else {
if (list.get(0).equals(list.get(1))) {
if (list.get(3).equals(list.get(2))) {
values[i][0] = list.get(0) * 2;
values[i][1] = list.get(2) * 2;
values[i][2] = 0;
values[i][3] = 0;
} else {
values[i][0] = list.get(0) * 2;
values[i][1] = list.get(2);
values[i][2] = list.get(3);
values[i][3] = 0;
}
} else {
//1和2不相等
//先比对2 3 相等,不等
if (list.get(1).equals(list.get(2))) {
values[i][0] = list.get(0);
values[i][1] = list.get(1) * 2;
values[i][2] = list.get(3);
values[i][3] = 0;
} else {
if (list.get(2).equals(list.get(3))) {
values[i][0] = list.get(0);
values[i][1] = list.get(1);
values[i][2] = list.get(2) * 2;
values[i][3] = 0;
}
}
}
}
}
}
private void delete() {
// Log.e("TAG", "--------------------执行");
// //遍历
// for (int i = 0; i < 4; i++) {
//  for (int j = 0; j < 3; j++) {
//  Card card = cards[i][j];
//  Log.e("TAG", "i:" + i + " j:" + j + " num:" + card.getNumber());
//  if (card.getNumber() == 0) {
//   boolean isSub = false;
//   for (int k = j; k < 3; k++) {
//   cards[i][k].setNumber(cards[i][k + 1].getNumber());
//   if (cards[i][k + 1].getNumber() != 0) {
//    isSub = true;
//   }
//   }
//   if (isSub)
//   j--;
//   cards[i][3].setNumber(0);
//  } else if (card.getNumber() == cards[i][j + 1].getNumber()) {
//   card.upLv();
//   cards[i][j + 1].setNumber(0);
//   //后面的往前搬
//   for (int k = j + 1; k < 3; k++) {
//   cards[i][k].setNumber(cards[i][k + 1].getNumber());
//   }
//   cards[i][3].setNumber(0);
//   j--;
//  }
//  }
// }
// for (int j = 0; j < 4; j++) { //列
//  for (int i = 3; i >= 1; i--) {
//  Card card = cards[j][i];
//  if (card.getNumber() == 0) {
//   //全行左移
//   //要将
//   //如果是最后一个,不需要理会
//   continue;
//  } else {
//   //判断左边一个
//   if (cards[j][i - 1].getNumber() == 0) {
//   //从i --》i-1
//   for (int k = i - 1; k < 3; k++) {
//    cards[j][k].setNumber(cards[j][k + 1].getNumber());
//   }
//   cards[j][3].setNumber(0);
//
//   } else if (cards[j][i - 1].getNumber() == card.getNumber()) {
//   cards[j][i - 1].upLv();
//   card.setNumber(0);
//   for (int k = i; k < 3; k++) {
//    cards[j][k].setNumber(cards[j][k + 1].getNumber());
//   }
//   cards[j][3].setNumber(0);
//   }
//  }
//  }
// }
}
public void right() {
mirrorH();
left();
mirrorH();
}
private void mirrorH() {
for (int i = 0; i < 4; i++) {
int temp = values[i][0];
values[i][0] = values[i][3];
values[i][3] = temp;
temp = values[i][1];
values[i][1] = values[i][2];
values[i][2] = temp;
}
}
public void down() {
//左旋
int[][] temp = new int[4][4];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
temp[i][j] = values[3 - j][i];
}
}
values = temp;
left();
temp = new int[4][4];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
temp[i][j] = values[j][3 - i];
}
}
values = temp;
}
public void up() {
mirrorV();
down();
mirrorV();
}
private void mirrorV() {
for (int j = 0; j < 4; j++) {
int temp = values[0][j];
values[0][j] = values[3][j];
values[3][j] = temp;
temp = values[1][j];
values[1][j] = values[2][j];
values[2][j] = temp;
}
}
public void setValues() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
System.out.print(values[i][j] + " ");
cards[i][j].setNumber(values[i][j]);
}
System.out.println();
}
}
public boolean isWin() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (values[i][j] == 2048)
return true;
}
}
return false;
}
public boolean isOver() {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (values[i][j] == 0)
return false;
}
}
//满了
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
int value = values[i][j];
if (i > 1 && value == values[i - 1][j])
return false;
else if (i < 3 && value == values[i + 1][j])
return false;
else if (j > 1 && value == values[i][j - 1])
return false;
else if (j < 3 && value == values[i][j + 1])
return false;
}
}
return true;
}
}

 

人已赞赏
Android文章

Android开发书架效果实现原理与代码

2020-2-17 9:42:40

Android文章

android开发环境遇到adt无法启动的问题分析及解决方法

2020-2-17 10:42:30

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索