非常感谢c87094279的提醒 ,之前在键盘监听器中忘记将是否可以生成新的元素的标记置0了,所以在用键盘操作的时候,没有可移动的方块时会冒出新的方块。现在已经改进了,只需在keyReleased方法中加上count=0;
最近学习了文件的保存,所以做了个小游戏,来实现简单的数据保存.
2048最近很火,所以选择了它.
先放运行效果图(界面没做什么美化)
重点来了:
简介:
1.四个方向键可使那一排(列)数字靠在同一个方向,遇到相同的自动相加.
2.计算步数以及分数,每一步获得的分数为两个方块合并时候生成的数字
3.随着数字改变颜色
4.当所有元素都在同一个方向时,按该方向按钮不会冒出新的元素
5.拼出2048后弹出提示
6.加入撤销功能
7.结束游戏又立即开始新游戏
8.可以保存进度,可以继续游戏
9.增加键盘功能
10.每次退出游戏自动保存数据,修复每次游戏自动读取上次保存的数据
实现方法:
1.用4*4的JButton数组(方便重置数字与背景颜色),用4*4int数组保存数组并btn.setText();
2.首先生成6个随机数,4个作为两个方块的xy轴,2个作为初始数字.
3.每点击一下方向则将相邻的相同数字相加,并将非0方块靠至该方向(写了很多判断)
4.每次点击按钮都判断是否能继续下一步,不能下一步则弹出结束游戏对话.
5.遍历数字时顺便设置颜色
6.当发生数字合并或者方块移动时,令count=1;否则count=0;只有count=1时才能生成新的数字
7.用S保存当前最大的数字,一旦达到2048,弹出提示.
8.用一个中间数组保存(将这些数据,包括数组,分数,最大数字变成对象,用一个动态数组保存对象.撤销一步则移除一个.)
9.用fileinputstream和fileoutputstream保存最后一次记录 ,ObjectOutputStream保存操作步骤
10.键盘监听器需要窗体上没有焦点,所有的JButton 都必须设置为不可成为焦点.setFocusable(false);
11.复合键设置了几个中间变量存储当前该键的状态,程序中实现了ctrl+z撤销 ctrl+s 保存.主要是要解决ctrl+s 与s 不能冲突.
12.每次自动保存进度到planAuto.dat,手动保存的保存到plan.dat.这样就避免了程序设计的缺陷(之前每次进入游戏都会自动回到上次保存的进度)
13.为减少数据保存的空间占用,只保存最近5个每一步的操作记录,所以恢复记录后只能撤消之前的步骤最多5次.
遇到的问题:
程序用到的知识都很基础,在这里只谈一下心得:
1.创建了4*4的JButton,用来显示数字和背景颜色.(JLabel也有setBackGround的方法,不过试了一下看不到效果,所以就改用JButton了.)然后创建了四个方向键来控制游戏.用JLabel显示得分score,步数status,最大数字S等信息,生成6个随机数,4个作为两个方块的xy轴,2个作为初始数字.
2.在ActionListener监听器类里面,我需要确定按下了哪一个方向键,进行判断之后进行相应操作,先调用setX方法(X表示任意方向),把相邻的相同加起来并且遇到0就自动填充过去.并刷新4*4Jbutton的显示.然后生成下一个随机位置和随机数.
3.在监听器增加判断,如果已经不能游戏了,就不能再生成随机数了,并弹出提示,如果最大数字S达到2048也要弹出提示
4.为了更好的心情舒畅的玩这个游戏,撤销功能是必须的,万一不小心按错了可能就输掉了,所以我考虑加入撤销功能.原打算用int[n][4][4]来保存,后来决定先把每一次int[4][4]变成对象再加入到ArrayList里面.点击撤销之后,先删除最新加进去的对象,再取出上一次加进去的对象.并将对象undo.data数组赋值给Game.data.(S,score也是一样)
在这里就遇到了一个问题,我加进arraylist里面的时候直接用undo.data=Game.data.再add(undo);
结果取出来之后每次都是最后一次加进去的data数组.这里卡住了很久,后来才想通.a=b;等于是把b的 地址赋值给了a;所以b指向的是a,而不是a的值.所以用两个for循环来进行赋值.
Undo undo = new Undo(); for(int i=0;i<4;i++){ for(int j=0;j<4;j++){ undo.data[i][j]=Game.data[i][j]; } } MyListener.undoAl.add(undo);
if(source.equals("撤销")){ if(undoAl.size()>1){ undoAl.remove(undoAl.size()-1); status--; if(score1.size()>1){ score1.remove(score1.size()-1); score=score1.get(score1.size()-1); System.out.println(score1.size()); if(S1.size()>0){ S=S1.remove(S1.size()-1); System.out.println(S1.size()); //这里又有疑问了,S1的size方法返回的数字是不重复的数据的个数,如果我加了很多个16进去,他不断的remove16,但是S1.size()确只有一次改变 } } temp=(Undo)undoAl.get(undoAl.size()-1); for(int i=0;i<4;i++){ for(int j=0;j<4;j++){ Game.data[i][j]=temp.data [i][j]; } } show(); } }
5这个是这次的重点
是为了巩固知识才写了这个小游戏,巩固文件保存的知识,因为游戏本身的逻辑是很简单的.
一开始用FileoutputStream保存S,score,status,和data[4][4]中的每一个元素,读取的时候也按顺序读进来.但是这样子读进来的数据会影响到撤销功能,读了数据之后是没办法撤销的(读进来的时候必须先清空ArrayList,又要把读进来的数据加到ArrayList.之前的记录没了).又考虑到S,score都用了单独的ArrayList,后来就直接把data,S,score都写成undo的属性,以对象形式保存在文件里面,最多保存6个,这样就可以实现最多5次撤销.要是用FileOutputStream太麻烦.直接用ObjectOutputStream将ArrayList的最后6项写出去.
6.最后,加入了键盘功能.ctrl+s 可以保存,ctrl+z可以撤销 wasd 小键盘2468以及 方向键均可控制方向.,加了WindowListener 在关闭窗口时自动保存数据,下次进入游戏就可以自动继续了.
统计了一下保存的数据占用的空间,最多占用844字节
/*
* 步数 字节数
* 0 76+128=204
* 1 332
* 2 460
* 3 588
* 4 716
* >=5 844
*/
Config类是便于打包成jar后图片资源能正常显示
Game为主类,程序的入口,初始化窗口和游戏数据
MyListener为监听器类,实现了动作,键盘,窗口监听器
planSave为保存文件的类
Undo为保存需要撤销的数据的类
相关推荐
java 键盘模拟java 键盘模拟java 键盘模拟java 键盘模拟java 键盘模拟java 键盘模拟java 键盘模拟java 键盘模拟java 键盘模拟java 键盘模拟java 键盘模拟java 键盘模拟java 键盘模拟java 键盘模拟java 键盘模拟java ...
Java 模拟线程并发 Java, 模拟线程并发,线程,并发 Java, 模拟线程并发,线程,并发 Java, 模拟线程并发,线程,并发 Java, 模拟线程并发,线程,并发
主要介绍了Java 模拟cookie登陆简单操作,结合实例形式分析了Java 模拟cookie登陆的相关原理与基本实现技巧,需要的朋友可以参考下
用java模拟访问浏览网站的代码,可以输出各种网页属性,以及html源代码
java 模拟 微信 浏览器访问web页面.
Java 模拟Ajax POST GET 提交代码,实测很好用。
java 模拟操作系统的进程调度 java 模拟操作系统的进程调度
JAVA模拟题JAVA模拟题JAVA模拟题JAVA模拟题JAVA模拟题JAVA模拟题JAVA模拟题JAVA模拟题
Java模拟银行系统
有10套Java模拟练习题 并附有答案
java模拟钢琴java模拟钢琴java模拟钢琴java模拟钢琴java模拟钢琴java模拟钢琴java模拟钢琴java模拟钢琴java模拟钢琴
模拟面试 Java 模拟面试 Java 模拟面试 Java 模拟面试 Java
java模拟题、考试复习必备java模拟题、考试复习必备java模拟题、考试复习必备java模拟题、考试复习必备java模拟题、考试复习必备java模拟题、考试复习必备java模拟题、考试复习必备java模拟题、考试复习必备java模拟...
JAVA模拟键盘输入
java毕业设计——基于Java的模拟写字板的设计与实现(论文+开题报告+答辩PPT+源代码+讲解视频).zip java毕业设计——基于Java的模拟写字板的设计与实现(论文+开题报告+答辩PPT+源代码+讲解视频).zip java毕业设计...
ElevatorSimulator是用java语言写的一款模拟电梯上下楼,有很好的界面,规范化的代码,功能很全!
java模拟qq源码
java模拟客户端向服务器发送post请求
压力测试java模拟工程