从零开始开发Android版2048 (五) 撤销的实现

本篇的内容是,在前一篇的基础上加入了撤销的功能。撤销其实就是将当前的用户界面恢复到这次滑动值前的样子。我实现撤销的主要原理是,将每次滑动后界面上的格子和对应的数字记录下来,当然还有分数,把这些数据写入一个栈中,然后点击撤销操作的时候,将栈顶pop掉,读取下一个栈中的对象,并根据对象中存储的数据重新绘制界面。

下面是我用于存储每次界面情况的类,在这个类中保存了界面中主要的三个数据,空白格、数字格和当前的分数。

package com.example.t2048;

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

public class History {

	//对应主activity中的空格列表
	private List<Integer> spaceList;
	//对应主activity中的数字列表
	private NumberList numberList;
	//对应主activity中的当前分数
	private int score = 0;

	/**
	 * 构造方法
	 * @param sl  空格列表
	 * @param nl  数字列表
	 * @param s   当前分数
	 */
	History(List<Integer> sl, NumberList nl, int s) {
		spaceList = new ArrayList<Integer>(sl);
		numberList = new NumberList(new ArrayList<Integer>(nl.getStuffList()), new ArrayList<Integer>(nl.getNumberList()));
		this.score = s;
	}

	public List<Integer> getSpaceList(){
		return this.spaceList;
	}

	public NumberList getNumberList() {
		return this.numberList;
	}

	public int getScore() {
		return this.score;
	}

	/**
	 * 打印日志
	 */
	public void printLog(){
		System.out.println(this.spaceList.toString());
		this.numberList.printLog();
		System.out.println("score: "+this.score);
	}
}

然后,我在主Activity中声明了一个stack用于保存每次的History

	//保存历史记录,用于撤销操作
	Stack<History> historyStack = new Stack<History>();

在每次完成初始化以及每次有效的滑动之后,将当前界面的History压入stack中

	History history = new History(spaceList, numberList, score);
	historyStack.push(history);

执行撤销的操作,我写了如下方法,代码还是很简单的:

	/**
	 * 撤销操作,获取操作记录栈中最后的记录,并重绘界面
	 */
	public void goBack(){
		//至少应有一次有效滑动后才能撤销
		if(historyStack.size()>=2){
		    //将当前的界面记录在栈中弹出
			historyStack.pop();
			//取栈中第二个对象即为本次操作之前的界面的记录
			History history = historyStack.peek();

			numberList = history.getNumberList();
			spaceList = history.getSpaceList();
			score = history.getScore();	

			//调取方法,重绘界面
			drawViews(spaceList, numberList, score);
		}
	}

	/**
	 * 根据参数重绘界面
	 * @param spaceList      空白格列表
	 * @param numberList     数字格列表
	 * @param score          当前分数
	 */
	public void drawViews(List<Integer> spaceList, NumberList numberList, int score){
		scoreText.setText(score+"");
		gridLayout.removeAllViews();
		for(int i=0; i<16; i++){
			View view = View.inflate(this, R.layout.item, null);
			ImageView image = (ImageView) view.findViewById(R.id.image);			

			if(numberList.contains(i))
				image.setBackgroundResource(icons[numberList.getNumberByIndex(i)]);
			else
				image.setBackgroundResource(icons[0]);
			gridLayout.addView(view);
		}
	}

完成以上代码后,将goback方法绑定到撤销按钮的onclicklistener中,就完成的撤销功能的实现。

本篇的原理基本就是这样的,这样实现在代码上感觉比较好理解,但是在效率上有很大的问题,比如在用户的操作记录了很多之后,内存的占用率会比较高(没有实际检测过有多少),耗电肯定也会增加不少,我想这也是为什么有的版本的2048只提供几步撤销功能的原因之一吧。如果大家有什么更好的实现方法,欢迎留言或者私信,多交流促进共同进步哈。

最后,附上截至目前,所有的源码,如有问题希望大家批评指正

下载地址:http://download.csdn.net/detail/johnsonwce/7290697

从零开始开发Android版2048 (五) 撤销的实现,布布扣,bubuko.com

时间: 2024-10-12 16:52:54

从零开始开发Android版2048 (五) 撤销的实现的相关文章

从零开始开发Android版2048 (三)逻辑判断

最近工作比较忙,所以更新的慢了一点,今天的主要内容是关于Android版2048的逻辑判断,经过本篇的讲解,基本上完成了这个游戏的主体部分. 首先还是看一下,我在实现2048时用到的一些存储的数据结构.我在实现时,为了省事存储游戏过程中的变量主要用到的是List. 比如说:List<Integer> spaceList = new ArrayList<Integer>();这个spaceList主要用于保存,所有空白格的位置,也就是空白格在GridLayout中的位置(从0到15)

从零开始开发Android版2048 (四) 分数、重置、结束

这一篇的内容主要是在上一篇的基础上,加入分数计算(包括当前分数和最高分数).游戏结束的判断以及游戏界面的重置这三个部分的功能. 一.分数的计算和保存 首先,2048这个游戏的分数包括,两个部分当前游戏分数和最高分,当前的游戏分数我们可以保存在程序的变量中,因为它只对当前这盘游戏有用,游戏结束就可以清空:而最高分则需要以一种方式保存在手机中,这样当我们下次再打开游戏时,还能读取到之前操作的最高分. 1.当前分数 当前分数的计算还是很简单.我们只需要在每次发生合并的时候,将产生的分数加到我们声明的分

从零開始开发Android版2048 (一)初始化界面

自学Android一个月多了,一直在工作之余零零散散地看一些东西.感觉经常使用的东西都有些了解了,可是一開始写代码总会出各种奇葩的问题.感觉还是代码写得太少.这样继续杂乱地学习下去进度也太慢了,并且学一点忘一点,效率太低.所以从今天開始.我打算实际做点小程序.在开发中不断地学习吧. 恰好近期Android上有个游戏2048比較火,所以就那这个练手吧. 由于对Android还没有太深入的了解,所以我写的东西都会比較基础,所以须要看一些高阶开发的朋友能够绕过了,也希望能够有高手们给我一些指导和建议,

从零開始开发Android版2048 (二)获取手势信息

今天是尝试開始Android版2048小游戏的第二天.在今天,我主要学习了怎样获取用户在屏幕滑动的手势,以及对布局进行了一些小小的完好. 获取用户操作的手势(比方向左滑.向右滑等)主要用到了GestureDetector.这个类能够帮助我们获取一些常见的用户对屏幕的操作.比如单击.双击.按压.拖动等.详细的使用说明.大家能够查API也能够去百度,或者看我之前有一篇使用GestureDetector实现的小样例(http://blog.csdn.net/xiapinnong/article/det

从零開始开发Android版2048 (四) 分数、重置、结束

这一篇的内容主要是在上一篇的基础上,增加分数计算(包含当前分数和最高分数).游戏结束的推断以及游戏界面的重置这三个部分的功能. 一.分数的计算和保存 首先,2048这个游戏的分数包含,两个部分当前游戏分数和最高分,当前的游戏分数我们能够保存在程序的变量中,由于它仅仅对当前这盘游戏实用,游戏结束就能够清空:而最高分则须要以一种方式保存在手机中,这样当我们下次再打开游戏时,还能读取到之前操作的最高分. 1.当前分数 当前分数的计算还是非常easy.我们仅仅须要在每次发生合并的时候,将产生的分数加到我

屌丝也能开发安卓版2048(App Inventor)

想编写安卓游戏,java太难,来试试App Inventor,虽然有人认为他是中学生的玩具,但是也能编写2048这样的火爆游戏,不需要太复杂的算法. 整个游戏有几个模块: 一.游戏初始化 数列转化为图形,使用了canvas和精灵,相对应list,这里注意精灵位置是固定的,只是更改图片,多少分,就对于n.jpg,0分是底色图片.左右移动,使用了flung判断,绝对值判断,水平速度和垂直速度哪个大,用来判断是左右移动还是上下移动. 二.计分模块 一般计分在合并处增加,最高分用了tiny db,游戏结

Android版2048

虽然说2048是好久前比较火的小游戏,但直到最近才有机会去研究下2048实现的源码,这里就简单写一下我(bie)的(ren)思路: 首先2048需要有十六个卡片,这个卡片可以用FrameLayout的子类来实现(继承),里面可以用TextView来实现设置背景颜色,显示的数字等.这样我们就可以简单实现这个卡片啦: public class Card extends FrameLayout { private int num = 0;    private TextView label; publ

百度地图开发 Android版应用Key申请

一 申请API key 在使用百度地图之前,我们必须去申请一个百度地图的API key,申请地址http://lbsyun.baidu.com/apiconsole/key,自己自行注册一个百度账号,很快就能申请到的,如下图 创建应用 Key type 选择“for mobile”,安全码是Android签名证书的证书指纹 (SHA1)值 + “;” + 你的应用程序包名,所以当你配置好了API key 你不能随意更换应用程序的包名, 如果更换了包名我们需要重新配置API key,接下来我们来介

开发腾讯移动游戏平台SDK Android版Ane扩展 总结

来源:http://blog.csdn.net/linguifa/article/details/25832011 本文记录了在开发 腾讯移动游戏平台SDK(MSDK) Android版Ane扩展 过程中所遇到的问题和相关解决方案 问题一:编译报错:Unable to resolve target 'android-7': 将低版本的代码导入eclipse时,常遇到这样的问题:Unable to resolve target 'android-XX' 这是原代码中project.properti