假期时无意间在微信上看到有人转发了2048的游戏链接,就想试着自己写一个,于是用了五天的时间完成了这个小游戏,下载地址是:http://zhushou.360.cn/detail/index/soft_id/3121426
我为它取名为——简2048,有兴趣的朋友可以去下载来试玩下。
游戏截图如下:
整个游戏的基础功能的实现十分简单,仅需要用到三个类,分别是卡片类:Card.java,游戏界面组件:GameView.java,主Activity类:MainActivity。
Card类用来生成游戏中的每个方格,继承了FrameLayout,所以Card也是一个布局类,当中包含了一个TextView组件,用来显示每个方格的数值Num,并提供了getNum()和setNum()来设置和获取其数值。代码如下:
public class Card extends FrameLayout {
private TextView label;
private int num;
public Card(Context context) {
super(context);
label = new TextView(getContext());
label.setBackgroundColor(0x33ffffff);
label.setTextSize(32);
label.setGravity(Gravity.CENTER);
LayoutParams lp = new LayoutParams(-1, -1);
lp.setMargins(10, 10, 0, 0);
addView(label, lp);
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
if (num == 0) {
label.setText("");
return;
}
label.setText(num + "");
}
public boolean equals(Card c) {
return this.getNum() == c.getNum();
}
}
GameView类用来生成游戏的主界面,继承了GridLayout类,所以GameView也是一个布局类。因为2048的游戏区域是一个n行n列的正方形区域,则GameView当中即包含了n*n个Card对象。通过设定每个方格的数值变化即可实现相应的“左移”,“右移”,“合并”等多种操作。
该注意的是,当手指向左滑动时,要实现全部方块向左移动,相邻且数值相同的方块要合并在一起,实现方法是LeftCard()。Left()函数用来实现所有方块向左移动的功能,但不包括数值检测与合并。LeftCard()方法首先执行一次Left(),然后从左往右检测是否有相邻方法数值相同,有则合并,且再执行一次Left()。代码如下:
public class GameView extends GridLayout {
private Card[][] cards;
public GameView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public GameView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public GameView(Context context) {
super(context);
init();
}
//初始化
public void init() {
setBackgroundColor(0xffbbada0);
cards = new Card[4][4];
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
cards[x][y] = new Card(getContext());
}
}
RandomCard();
RandomCard();
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
int cardWidth = (Math.min(w, h) - 10) / 4;
addCard(cardWidth);
}
public void addCard(int cardWidth) {
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) {
addView(cards[x][y], cardWidth, cardWidth);
}
}
}
//生成随机数字
public void RandomCard() {
int i = 0;
for (int x = 0; x < 4; x++) {
for (int y = 0; y < 4; y++) {
if (cards[x][y].getNum() == 0) {
i++;
}
}
}
if (i == 0) {
return;
}
int random = new Random().nextInt(16);
int x = random / 4;
int y = random % 4;
while (cards[x][y].getNum() != 0) {
random = new Random().nextInt(16);
x = random / 4;
y = random % 4;
}
cards[x][y].setNum(2);
}
//左移
public void LeftCard() {
Left();
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 3; x++) {
if (cards[x][y].getNum() != 0) {
if (cards[x][y].equals(cards[x + 1][y])) {
int num = 2 * cards[x][y].getNum();
cards[x][y].setNum(num);
cards[x + 1][y].setNum(0);
Left();
}
}
}
}
RandomCard();
}
//右移
public void RightCard() {
Right();
for (int y = 0; y < 4; y++) {
for (int x = 3; x > 0; x--) {
if (cards[x][y].getNum() != 0) {
if (cards[x][y].equals(cards[x - 1][y])) {
int num = 2 * cards[x][y].getNum();
cards[x][y].setNum(num);
cards[x - 1][y].setNum(0);
Right();
}
}
}
}
RandomCard();
}
//上移
public void TopCard() {
Top();
for (int x = 0; x < 4; x++) {
for (int y = 0; y < 3; y++) {
if (cards[x][y].getNum() != 0) {
if (cards[x][y].equals(cards[x][y + 1])) {
int num = 2 * cards[x][y].getNum();
cards[x][y].setNum(num);
cards[x][y + 1].setNum(0);
Top();
}
}
}
}
RandomCard();
}
//下移
public void BottomCard() {
Bottom();
for (int x = 0; x < 4; x++) {
for (int y = 3; y > 0; y--) {
if (cards[x][y].getNum() != 0) {
if (cards[x][y].equals(cards[x][y - 1])) {
int num = 2 * cards[x][y].getNum();
cards[x][y].setNum(num);
cards[x][y - 1].setNum(0);
Bottom();
}
}
}
}
RandomCard();
}
//全部向左
public void Left() {
for (int y = 0; y < 4; y++) {
int i = 0;
for (int x = 0; x < 4; x++) {
if (cards[x][y].getNum() != 0) {
int num = cards[x][y].getNum();
cards[x][y].setNum(0);
cards[i++][y].setNum(num);
}
}
}
}
//全部向右
public void Right() {
for (int y = 0; y < 4; y++) {
int i = 3;
for (int x = 3; x > -1; x--) {
if (cards[x][y].getNum() != 0) {
int num = cards[x][y].getNum();
cards[x][y].setNum(0);
cards[i--][y].setNum(num);
}
}
}
}
//全部向上
public void Top() {
for (int x = 0; x < 4; x++) {
int i = 0;
for (int y = 0; y < 4; y++) {
if (cards[x][y].getNum() != 0) {
int num = cards[x][y].getNum();
cards[x][y].setNum(0);
cards[x][i++].setNum(num);
}
}
}
}
//全部向下
public void Bottom() {
for (int x = 0; x < 4; x++) {
int i = 3;
for (int y = 3; y > -1; y--) {
if (cards[x][y].getNum() != 0) {
int num = cards[x][y].getNum();
cards[x][y].setNum(0);
cards[x][i--].setNum(num);
}
}
}
}
//屏幕触摸事件
float X;
float Y;
float OffsetX;
float OffsetY;
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
X = event.getX();
Y = event.getY();
break;
case MotionEvent.ACTION_UP:
OffsetX = event.getX() - X;
OffsetY = event.getY() - Y;
if (Math.abs(OffsetX) > (Math.abs(OffsetY))) {
if (OffsetX < -5) {
LeftCard();
} else if (OffsetX > 5) {
RightCard();
}
} else {
if (OffsetY < -5) {
TopCard();
} else if (OffsetY > 5) {
BottomCard();
}
}
break;
}
return true;
}
}
这样,向主Activity设置的布局文件activity_main.xml中增添GameView组件,就可以实现游戏的基本功能了。代码如下:
<?xml version="1.0"?>
<LinearLayout xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" >
<chen.zy.game2048.GameView android:id="@+id/gameView" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1" android:columnCount="4" android:rowCount="4" >
</chen.zy.game2048.GameView>
</LinearLayout>
仅依靠这三个类,就可以实现2048的基础功能,代码虽然简洁,但实现的效果肯定也没有我上述的截图好,其他功能需要自己再来后续添加,如保存游戏记录、音效、主题等。
这里提供实现了基础功能的代码下载地址:Android游戏——2048源码
需要完整源代码、有疑问或想交流的童鞋可以在下边留言,我会一一回复的~