Android版【2048游戏】源码简单实现

最近2048这个小游戏比较火,自己也喜欢玩,就想着自己去利用安卓实现一个,先上图


大概实现流程有下面几步:

转载请注明出处:http://blog.csdn.net/u014695956/article/details/23620863

1.使用GridLayout作为装载方块的容器

    <GridLayout
        android:id="@+id/gridContainer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:alignmentMode="alignMargins"
        android:background="@anim/submit_item_selected"
        android:columnCount="4"
        android:rowCount="4" >

GridLayout是Android 4.0之后出现的布局,相关使用说明和优点可以去网上搜一下。指定4行4列,装方块的容器就准备好了。


2.定义方块的Bean

public class ItemInfo {
	/**
	 * 当前Item的数值
	 */
	private int number;
	/**
	 * 当前Item的位置
	 */
	private Point point;

	/**
	 * 当前Item上面的item
	 */
	private ItemInfo aboveItem;

	/**
	 * 当前Item下面的item
	 */
	private ItemInfo belowItem;
	/**
	 * 当前Item左边的item
	 */
	private ItemInfo leftItem;
	/**
	 * 当前Item右边的item
	 */
	private ItemInfo rightItem;
	/**
	 * 当前Item的View
	 */
	private ImageView view;

	//下面写相关get与set方法
}
方块本身保留有自己上下左右的方块对象。

3.定义两个List集合,一个集合用于存储所有方块,一个集合用于存储没有显示数字的方块,初始化如下:

	/**
	 * 定义存储显示空项的Item的集合
	 */
	private List<Integer> spaceItem;
	/**
	 * 定义存储所有Item的集合
	 */
	private List<ItemInfo> itemInfos;
...
	for (int i = 0; i < 16; i++) {
			spaceItem.add(i);
	}

...
		// 向gridConteainer里面添加spaceItem
		for (int i = 0; i < 16; i++) {
			// 定义一个ItemInfo的集合
			ItemInfo info = new ItemInfo();
			// 设定初始值
			info.setNumber(0);
			// 设定Point对象
			Point point = EngineUtils.getPoint(i);
			info.setPoint(point);
			// 得到填充item的View
			View view = View.inflate(this, R.layout.item_home, null);
			ImageView imageView = (ImageView) view.findViewById(R.id.iv);
			// 设置默认的背景
			imageView.setBackgroundResource(icons[0]);
			// 设置info对象里面的ImageView引用
			info.setView(imageView);
			gridContainer.addView(view);
			// 向Item集合中添加Item对象
			itemInfos.add(info);
		}


4.遍历设定每个方块自身上下左右的方块对象

		// 遍历gridContainer,设置各个Item的属性
		for (int i = 0; i < itemInfos.size(); i++) {
			ItemInfo info = itemInfos.get(i);

			// 判断是否在容器的左边缘
			if (i % 4 != 0) {// 不在容器的左边缘,说明左边有Item
				ItemInfo leftItem = itemInfos.get(i - 1);
				info.setLeftItem(leftItem);
			}
			// 判断是否在容器的右边缘
			if ((i + 1) % 4 != 0) {// 不在容器的右边缘,说明右边有Item
				ItemInfo rightItem = itemInfos.get(i + 1);
				info.setRightItem(rightItem);
			}
			// 判断是否在窗口的上边缘
			if (i / 4 != 0) {// 不在容器的上边缘,说明上边有Item
				ItemInfo aboveItem = itemInfos.get(i - 4);
				info.setAboveItem(aboveItem);
			}

			// 判断是否在容器的下边缘
			if (i < 12) {// 不在容器的下边缘,说明上边有Item
				ItemInfo belowItem = itemInfos.get(i + 4);
				info.setBelowItem(belowItem);
			}
		}

5.向左移动逻辑

	/**
	 * 向左移动
	 */
	private void moveToLeft() {
		List<Integer> temp = new ArrayList<Integer>();
		// 外层控制列数
		for (int i = 1; i < 4; i++) {
			// 内层控件行数据
			for (int j = 0; j < 4; j++) {
				// 计算索引
				int index = i + j * 4;
				// 通过索引得到集合中的item对象
				ItemInfo info = itemInfos.get(index);
				// 得到自身的Number
				int selfNumber = info.getNumber();
				// 如果当前的Number为0,则不做任何操作
				if (selfNumber == 0) {
					continue;
				}

				int d = 0;
				for (int k = 1; k < i + 1; k++) {
					int tempIngex = index - k;
					ItemInfo tempInfo = itemInfos.get(tempIngex);
					int tempNumber = tempInfo.getNumber();
					if (tempNumber != 0) {
						break;
					} else {
						d++;
					}
				}
				if (d != 0) {
					isLeftMove = true;
					repalceSpaceItem(index - d, index);
					replaceItem(index, index - d, selfNumber, false);
				}

				index = index - d;
				info = itemInfos.get(index);
				selfNumber = info.getNumber();

				// 通过item对象得到其左边的item,并判断左边的item的数值是否为0
				ItemInfo leftItem = info.getLeftItem();
				if (leftItem != null) {
					// 得到左边item的数值
					int leftNumber = leftItem.getNumber();
					if (leftNumber == selfNumber && !temp.contains(index - 1)) {// 合并

						isLeftMove = true;
						int tempNumber = leftNumber + selfNumber;
						replaceItem(index, index - 1, tempNumber, true);
						nowScore += tempNumber;
						// 更新分数
						Message msg = handler.obtainMessage();
						msg.obj = nowScore;
						handler.sendMessage(msg);
						spaceItem.add(index);
						temp.add(index - 1);
					}
				}

			}
		}
	}
实现思路:

a.两个for循环,分别控制循环行数与列数。遍历当前方块的时候如果当前方块的数值为0,则不做任何操作(第5步第17行代码)。

b.在遍历的过程中,遍历当前方块的时候判断当前方块最左边有几个空位,并将当前数值替换到到最左边的空位(第5步第35行代码)。

c.在b的基础上,继续向下执行,再判断当前方块左边的方块是否与自身方块数字相同,如果相同,则合并(第5步第47行代码)。

d.合并之后调用handler更新分数


收尾:设置手势监听,其他方向移动逻辑类似。

本代码实现基于Android 4.0以上,想在低版本上使用GridLayout需用 Android support-v7下的GridLayout,在此就不详述。

只实现了移动逻辑,方块移动动画等有空再续。

代码下载地址:http://download.csdn.net/detail/u014695956/7188665



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值