非常感谢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 模拟Cookie 登陆简单操作示例 在本文中,我们将介绍 Java 模拟 Cookie 登陆的简单操作,结合实例...本示例可以帮助开发者快速了解 Java 模拟 Cookie 登陆的实现原理和实现方法,为实际开发中提供了有价值的参考。
总之,Java模拟线程并发是一个广泛且深入的话题,涵盖了线程的创建、同步、管理和高级并发工具的使用。理解和熟练应用这些知识,能够帮助开发者编写出高效、安全的多线程程序。在实际开发中,应根据具体需求选择合适...
用java模拟访问浏览网站的代码,可以输出各种网页属性,以及html源代码
这个“java模拟微信浏览器访问.rar”压缩包中的主要文件是“MonitorWeixinBrowser.java”,我们可以推测这是一个Java程序,用于模拟微信内置浏览器的行为。下面将详细介绍这个主题的相关知识点。 1. **Java HTTP ...
Java模拟技术,也被称为Java模拟器或Java虚拟机,是一种在非Java环境下运行Java应用程序的软件工具。这种技术使得开发者和用户能够在个人电脑上模拟Android或其他基于Java的移动设备环境,以便于测试、开发或者使用...
Java模拟登录的关键步骤包括: 1. **构建HTTP请求**:使用像`HttpURLConnection`或者第三方库如`Apache HttpClient`或`OkHttp`,创建一个指向登录页面的POST请求。你需要设置请求头,比如`Content-Type`通常设为`...
Java 模拟Ajax POST GET 提交代码,实测很好用。
本项目名为"Java模拟登录百度Demo",旨在通过Java编程语言实现对百度网站的自动登录功能。在这个教程中,我们将深入探讨如何使用Java来完成这一目标。 首先,模拟登录的核心是发送HTTP请求。在Java中,我们可以使用...
在"java httpclient 模拟登录"这个场景下,我们通常会用到HttpClient来模拟用户登录网站的过程,获取登录后的session信息,以便后续能够访问登录后才能看到的页面内容。以下将详细介绍如何使用Java HttpClient进行...
Java模拟淘宝登录源码是一种常见的网络编程技术,主要用于自动化测试、数据抓取或者模拟用户行为。在这个场景中,我们使用的工具是HTTPClient库,这是一个强大的Java HTTP客户端应用编程接口,可以方便地处理HTTP...
这里提供的“Java模拟题 Java题库”包含了10套完整的Java练习题目,每套都配有详细的答案,为学习者提供了宝贵的实践机会。 1. **基础语法**:Java的基础语法包括变量、数据类型、运算符、控制结构(如if语句、for...
《Java游戏2048开发详解》 2048是一款简单却极具挑战性的数字合成游戏,由Gabriele Cirulli在2014年创造。本篇将深入探讨如何使用Java编程语言来实现这款经典游戏。 首先,我们要了解Java的基础知识。Java是一种...
在Java模拟的系统中,文件管理涉及到了文件的创建、复制、剪切和粘贴等基本操作。这些功能的实现通常需要用到数据结构如链表或树来维护文件系统。用户接口则提供给用户与系统交互的途径,可能是命令行界面或图形用户...
以上就是关于"java模拟键盘鼠标"这个项目的主要知识点。在实际开发中,需要注意模拟操作的准确性和效率,以及避免过于频繁的操作导致账号被系统识别为异常。同时,尊重他人的隐私和使用条款,确保这种技术的合法和...
在Java编程领域,模拟电梯上下楼程序是一种常见的练习,它能帮助开发者理解多线程、同步机制以及事件驱动编程的概念。`ElevatorSimulator`项目就是这样一个实例,它使用Java语言构建,具备良好的用户界面和规范化的...
java模拟钢琴java模拟钢琴java模拟钢琴java模拟钢琴java模拟钢琴java模拟钢琴java模拟钢琴java模拟钢琴java模拟钢琴
在本主题中,我们将深入探讨如何使用 Java 语言来模拟操作系统的进程调度算法。Java 作为一种多平台、面向对象的语言,提供了丰富的工具和库,使得实现这样的模拟成为可能。 首先,我们需要了解基本的进程调度概念...
Java模拟机,是一种软件模拟器,它允许开发者在没有特定硬件环境的情况下运行Java应用程序或Java虚拟机(JVM)。在Java开发过程中,模拟机扮演着至关重要的角色,它提供了跨平台兼容性,使得Java程序“一次编写,...
【标题】:Java模拟ARP协议 在计算机网络中,ARP(Address Resolution Protocol)协议是用于将IP地址解析为物理(MAC)地址的关键协议。当主机需要向其他IP地址发送数据时,它首先需要知道目标IP对应的MAC地址。...