本文实例为大家分享了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。条件成立则调用相应算法实现。

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

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

  1. C++的学习心得和知识总结(十八)|基于EasyX实现 2048游戏 项目(C/C++版)

    目录结构 注:提前言明 本文借鉴了以下博主.书籍或网站的内容,其列表如下: 1.网络热门游戏 2048,点击前往 2.EasyX官方链接,点击前往 3.中国色谱 颜色代码对照表(RGB多用于easyX ...

  2. java课设 简单九宫格_[Java教程]简易版九宫格相加数值相等

    [Java教程]简易版九宫格相加数值相等 0 2016-02-24 00:00:10 九宫格的样子以及游戏想大家接触过,想当年也是玩了好多九宫格游戏,其中最经典的就是1-9这九个数字填进格子,横竖向. ...

  3. 黑马程序员全套Java教程_Java基础教程_异常(含扩展)(二十三)

    黑马程序员全套Java教程_Java基础教程_异常(含扩展)(二十三) 1.1 异常概述与异常体系结构 1.2 JVM遇到异常时的默认处理方案 1.3 异常处理 1.4 异常处理之try--catch ...

  4. 2048 java代码_java实现的2048游戏完整实例

    本文实例讲述了java实现的2048游戏.分享给大家供大家参考,具体如下: 先来看看运行效果: 具体代码如下: package awtDemo; import javax.swing.*; impor ...

  5. 2048游戏java版

    最近上java看,写了个2048游戏 分3个文件,一个是Game类写算法的,一个是Win类写图形界面的,一个是游戏的主类my2048 主要算法思路:每次上下左右,分割成单独一行或者一列处理,就变成了对 ...

  6. 基于android的2048游戏设计,基于Android平台的2048游戏设计与开发.docx

    基于Android平台的2048游戏设计与开发 高级操作系统论文(设计) 题 目 基于Android个人2048 小游戏的设计与开发姓 名 学 号 院. 系 信息学院 专 业 指导教师 职称(学历)目 ...

  7. 2048游戏制作html,一个自制的2048小游戏(一)

    导语 本次将会从头到尾讲一个2048游戏的制作过程,中间也会穿插自己的理解 一.项目结构 除了html和css文件外,分了main.js,support.js,showanimation.js,以及引 ...

  8. 用c语言编写一个2048 游戏,求c语言编写的2048游戏代码,尽量功能完善一些

    正在编写中,请稍后! 追答 : 代码来了!有点急,没做界面. 追答 : 2048_launcher.c : #include #include #include void main() { print ...

  9. 消灭泡泡糖游戏java编程_JAVA面向对象编程课程设计——泡泡堂

    ###一.成员介绍 姓名|任务分配|个人博客链接 --|:--:|--: 张一弛(组长)|GUI设计.游戏界面相关类实现.阿里巴巴扫描纠错.团队博客编写|在做了,在做了,下次一定 王江鸿|Box类.B ...

  10. java 数据结构_Java版-数据结构-队列(数组队列)

    前言 看过笔者前两篇介绍的 Java版数据结构 数组和 栈的盆友,都给予了笔者一致的好评,在这里笔者感谢大家的认可!!! 由于本章介绍的数据结构是 队列,在队列的实现上会基于前面写的 动态数组来实现, ...

最新文章

  1. disconf mysql_disconf-web 安装
  2. C# 哈希表(Hashtable)用法笔记
  3. 797. 所有可能的路径
  4. 11月4日,上海开源基础设施峰会,不见不散!
  5. TCP/IP入门(3) --传输层
  6. Git是目前世界上最先进的分布式版本控制系统(没有之一)。
  7. Java中文件路径的写法
  8. PHP集锦点,php 函数集锦
  9. php输出因子,如何在PHP因子程序中返回值
  10. 如何在C#窗体中定义全局变量
  11. 阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第4节 等待唤醒机制_2_等待唤醒案例分析...
  12. Objective-C学习—UIScrollView控件使用
  13. mysql hyperloglog_Redis HyperLogLog
  14. 链接脚本(Linker Script)用法解析(一) 关键字SECTIONS与MEMORY
  15. 在尘世间做最好的自己
  16. LiveData更新数据报错java.lang.IllegalStateException: Cannot invoke setValue on a background thread
  17. 小白跑WRF第七天,运行WRF案例
  18. 计算机网络通信的媒体介质,计算机网络基础:常见的网络传输介质
  19. Linux_clustalW安装及使用(部分)
  20. java图形化界面编程之Swing

热门文章

  1. STC开天斧虚拟示波器使用
  2. linux 输入密码后无法进入系统,【Linux学习笔记十六】用户密码修复和GRUB引导错误无法进入系统解决办法...
  3. Orcad Schematic常用功能
  4. Unity3D坦克大战项目总结
  5. JSON在线序列化网站
  6. 2019全国大学生电子设计大赛-F题纸张计数
  7. 双创项目_宫颈癌智能风险检测(4)
  8. 结构为王——确定分析思路(数据分析方法论)
  9. 曲苑杂坛--修改数据库服务器名称
  10. 易游网络验证好不好?如何正确的使用易游验证