本文实例为大家分享了java实现2048游戏功能的具体代码,供大家参考,具体内容如下

功能要求:2048的基本界面,能够实现2048的游戏功能。

总思路:两个类:Game和GameListener。

Game负责界面的实现和paint方法的重写

GameListener负责实现键盘和鼠标事件的处理。移动方法,相加方法,输赢判断和随机数的出现都要在键盘监听的方法中实现。

实现分析:要实现2048游戏,首先需要考虑2048都有些什么?

界面实现:

2048的游戏界面很简单,就是一些方格和数字。要实现这样的界面,我们可以考虑一下使用Java的绘图功能。具体来说就是使用JFrame类提供的Graphics对象进行绘图。2048界面由一个大的矩形背景和包含数字的许多小方块组成。Graphics对象的绘制矩形的方法就能实现背景和小方格的绘制。小方格内的数字则可以使用graphics的drawString方法来绘制。只需要在绘制的时候注意一下颜色就好。界面实现要拥到的类主要是JFrame类。

基本界面实现代码,不过是一些按钮之类的,没什么好说的。

private void initUI() {

setTitle("2048");

setDefaultCloseOperation(3);

setSize(600, 700);

setLocationRelativeTo(null);

this.setLayout(null);

//添加分数

jl2 = new JLabel("分数:0");

jl2.setFont(new Font("黑体", Font.BOLD, 30));

jl2.setBounds(20, 30, 200, 50);

this.add(jl2);

//添加开始按钮

ImageIcon start=new ImageIcon("res/start.png");//开始游戏图标,随意替换就好

startJB=new JButton(start);

startJB.setBounds(280, 40, 120, 30);

startJB.setFocusable(false);

startJB.setBorderPainted(false);//设置按钮的边框为空

startJB.setFocusPainted(false);

startJB.setContentAreaFilled(false);//设置按钮的边框内填充颜色

//添加退一步按钮

ImageIcon back=new ImageIcon("res/backicon.png");//游戏结束图标,随意替换就好

backJB=new JButton(back);

backJB.setBounds(430, 40, 120, 30);

backJB.setFocusable(false);

backJB.setBorderPainted(false);

backJB.setFocusPainted(false);

backJB.setContentAreaFilled(false);

this.add(startJB);

this.add(backJB);

setVisible(true);

GameListener gl = new GameListener(this, arry, jl2,startJB,backJB);

addKeyListener(gl);

startJB.addActionListener(gl);

backJB.addActionListener(gl);

}

方格和数字的绘制:

方格和数字的绘制同样是使用JFrame的画布对象的绘制矩形的方法实现。

public void buffPaint(Graphics g) {

Image image = createImage(600, 600);

Graphics g2 = image.getGraphics();

g2.setColor(Color.LIGHT_GRAY);

Graphics2D g2d = (Graphics2D) g2;

g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

g2.fillRoundRect(0, 0, Draw2048.RD, Draw2048.RD, 20, 20);

g2.setColor(Color.GRAY);

for (int r = 0; r < arry.length; r++) {

for (int c = 0; c < arry[r].length; c++) {

g2.fillRect(20 + c * (Draw2048.D + Draw2048.space), 20 + r

* (Draw2048.D + Draw2048.space), Draw2048.D, Draw2048.D);

}

}

for (int r = 0; r < arry.length; r++) {

for (int c = 0; c < arry[r].length; c++) {

if (arry[r][c] != 0) {

g2.setColor(255, 250, 240);

g2.fillRect(20 + c * (Draw2048.D + Draw2048.space), 20 + r

* (Draw2048.D + Draw2048.space), Draw2048.D,

Draw2048.D);

g2.setColor(new Color(0, 191, 255));

g2.setFont(new Font("楷体", Font.BOLD, Draw2048.FSIZE));

g2.drawString(arry[r][c] + "", 50 + c

* (Draw2048.D + Draw2048.space), 90 + r

* (Draw2048.D + Draw2048.space));

}

}

}

g.drawImage(image, 50, 150, this);

}

Draw2048是一个接口,里面定义了关于方格绘制的相关常量,D方格边长,space方格间间隔。RD背景大矩形的边长。使用接口的好处就是使得界面的更改(如改成5*5的格子)可以更加方便的实现,提高程序的扩展性。另外界面需要不断的更新,所以要调用paint方法不断的重绘。如果直接把这里的绘制写在paint方法中,不断的重绘会使得界面一直在闪烁。这里的解决方案就是使用图片缓冲,先在图片中绘制好,在把图片一次性绘制出来,这样就不会出现界面的闪烁问题了。

移动实现:

要想让方格移动起来,可以考虑的方法就是使用画板的重绘。方格内的数字则使用一个二维数组来保存。每次移动就让数组的值发生变化就行,然后根据数组的值把数据绘制到界面上。当然玩游戏时总不能靠意念操控,我们需要有输入设备,也就是键盘。所以需要给界面加上键盘监听。当用户按下不同的键则实现不同的移动算法。值得注意的是,在监听类中编写相应的移动算法的时候要理清循环的使用和结束(尤其是break语句的使用),否则会出现各种各样的bug。移动实现是需要用到keyListener类。

下面是向上移动的实现,其他方向的移动都差不多,自己琢磨一下就好:

//向上移动的算法

for (int r = 0; r < arry.length; r++)

for (int c = 0; c < arry[r].length; c++) {

if (arry[r][c] > max)//找出数组最大值,用于判断玩家的方块是否达到2048

max = arry[r][c];

if (arry[r][c] == 0) {

for (int r1 = r + 1; r1 < arry[c].length; r1++)

if (arry[r1][c] != 0) {

arry[r][c] = arry[r1][c];

arry[r1][c] = 0;

count++;//判断是否发生移动,并且作为输赢判断的标准之一

break;

}

}

}

通过双层循环,循环每一个值,如果它为0,则可以往上移动。遍历该值所在列,找到第一个不为0的值,移动这个值(即交换两个数的值)。移动后退出内层循环,继续遍历下一个值。

数字的相加:

使用独立的算法遍历数组,在移动方向上的相邻数两个相加,然后一个置为0。这里的算法实现和移动的算法十分相像,需要注意的地方同样也是break和循环的使用。还有一个要注意的就是:数字的相加要放在数字移动之前来完成,否则会出现移动后的数字空格。

//向左的相加算法

for (int r = 0; r < arry.length; r++)

for (int c = 0; c < arry[r].length; c++)

if (arry[r][c] != 0)

for (int c1 = c + 1; c1 < arry[r].length; c1++)

if (arry[r][c] == arry[r][c1]) {

arry[r][c] *= 2;

score += arry[r][c];

arry[r][c1] = 0;

count++;//判断是否发生相加,并作为输赢判断条件之一。

break;

} else if (arry[r][c1] != 0) {

break;

}

同样是遍历数组的每一个值,如果这个值不为0,则找所在行的相邻的相同的值相加,结束最内层循环。如果相邻的两个值不同,也结束最内层循环。两个break语句的使用,避免了数字之间的跳跃相加。

输赢的判断:

2048的赢的规则是,相加数字出现2048,所以只需要判断数组中是否有一个数字等于2048就行,如果有,就输出相应的获胜信息。

2048的输的规则是,界面已经满(数组已满,且无可移动,相加的数字)。个人的判断方法是全局变量count加上判断数组是否已满。count如果等于0,则表示无法移动和相加,配合数组已满的条件就能判断玩家已经输了。

随机数字的出现:

随机数字出现的条件是发生移动或者相加,所以判断然让使用count。条件成立则调用相应算法实现。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

java做2048_java版实现2048游戏功能相关推荐

  1. php和java做众筹系统哪个好,Java版众筹系统和PHP众筹系统对比分析

    众筹系统是为从事众筹行业设计开发的,用于满足众筹运营者和投资之间操作管理的一个平台.目前市场主流的众筹系统主要有java版和php版.今天小编就来介绍下这2个版本的众筹系统有何区别. Java版众筹系 ...

  2. 利用java开发简易版扫雷游戏

    1.简介 学了几周的Java,闲来无事,写个乞丐版的扫雷,加强一下Java基础知识. 2.编写过程 编写这个游戏,一共经历了三个阶段,编写了三个版本的游戏代码. 第一版:完成了扫雷游戏的基本雏形,实现 ...

  3. 【PAT甲级 LinkedHashMap】1041 Be Unique (20 分) Java、C++版

    题目 题目的意思是,找到第一个不重复的元素.输出它. 一开始用Java做,试了好多种方法都超时.后来换用C++通过了. AC题解:C++版 用Java尝试了各种方式,都是后两个测试点过不去,只好换C+ ...

  4. Think in Java第四版 读书笔记10 第16章 数组

    Think in Java第四版 读书笔记10 第16章 数组 数组和容器很像 但他们有一些差别 16.1 数组为什么特殊 数组与容器的区别主要在效率和存储类型 效率:数组是简单的线性序列 使得数组的 ...

  5. Think in Java第四版 读书笔记9第15章 泛型

    Think in Java第四版 读书笔记9第15章 泛型 泛型:适用于很多很多的类型 与其他语言相比 Java的泛型可能有许多局限 但是它还是有很多优点的. 本章介绍java泛型的局限和优势以及ja ...

  6. 关于用java做微信机器人的艰辛过程

    一定要看到最后,否则后果很严重哦~ 1.技术栈 1.可爱猫框架,官网可爱猫论坛 2.Simpler-robot框架,官网微信 - 可爱猫-httpapi 3.springboot 2.可爱猫环境搭建 ...

  7. Java虚拟机规范 Java SE 8版 - class文件格式(二)

    Java虚拟机规范 Java SE 8版 - class文件格式(二) 4.5 字段 4.6 方法 4.7 属性 4.7.1 自定义和命名新的属性 4.7.2 ConstantValue 属性 4.7 ...

  8. Q新闻丨Java 9正式版恐再延期;顺丰菜鸟口水战涉及阿里云;编程语言排行榜Python第四;盲人程序员背百万字符,用耳朵编程...

    编辑|小智 本周要闻:Java 9 正式版有可能被推迟到 9 月 21 号发布:顺丰.菜鸟口水战始末,或涉及阿里云:Node.js 发布 v8.0.0:Visual Studio for Mac 版本 ...

  9. 刚刚从GitHub 上扒下来,标星 75k,超牛的《Java面试突击版》,这么高标星果真有原因的

    前言 不论是校招还是社招都避免不了各种面试.笔试,如何去准备这些东西就显得格外重要.不论是笔试还是面试都是有章可循的,我这个有章可循'说的意思只是说应对技术面试是可以提前准备. 运筹帷幄之后,决胜千里 ...

  10. GitHub上标星95k+超牛的《Java面试突击版》PDF

    前言 不论是校招还是社招都避免不了各种面试.笔试,如何去准备这些东西就显得格外重要.不论是笔试还是面试都是有章可循的,我这个有章可循'说的意思只是说应对技术面试是可以提前准备. 运筹帷幄之后,决胜千里 ...

最新文章

  1. ML之NB:基于NB朴素贝叶斯算法训练20类新闻文本数据集进行多分类预测
  2. java中静态变量,静态代码块,静态方法,实例变量,匿名代码块的加载顺序
  3. 汉三水属国(北地属国、安定属国)
  4. 从零开始开发 VS Code 插件之 Translator Helper
  5. Qt下简单的文件读取
  6. python eval简介
  7. dz安装教程php,discuz论坛安装教程 2017最新discuz论坛安装教程
  8. m2e (maven eclipse) 在运行一些命令时出现了无法compile(Unable to locate the Javac Compiler in:)...
  9. 360全景拼接 opencv_广州海珠区专业改全景,丰田塞纳改3D全景,360全景行车记录仪的功能...
  10. 数据挖掘概念与技术复习
  11. Axure制作音乐App原型图
  12. Python:1004 成绩排名
  13. 利用快速傅里叶计算多项式相乘
  14. 飞猪订房显示服务器出错,消费者在飞猪平台全款预订酒店后无法办理入住
  15. 股票什么时候买入什么时候卖出适合?
  16. top 100 percent
  17. java Thread的start和run方法的区别
  18. Raptor 经典例题 2 (冒泡法排序 100名同学拉成一圈)
  19. java isinterrupted_JAVA多线程之中断机制(stop()、interrupted()、isInterrupted())
  20. SPFA算法(最短路径)

热门文章

  1. Simon的新中文“百万格子”重磅推出
  2. 百度文库上传总是被私有,如何正确上传百度文库
  3. Javascript网页打印大全
  4. 高清格式——720p/1080i/1080p,谁更清晰
  5. Java实现经纬度格式转化
  6. 水温控制系统设计(AVRmega16单片机)代码编写(包含显示器、单片机、温度传感器)
  7. 【有源汇上下界可行流】ACM-ICPC 2018 沈阳赛区网络预赛 - F - Fantastic Graph
  8. 在使用html5的video标签播放视频时为何只有声音却没有图像
  9. 百度C++工程师的那些极限优化(内存篇)
  10. CoffeeScript 简介