0

0

Java版实现2048的游戏功能实例

零下一度

零下一度

发布时间:2017-07-21 22:01:09

|

2037人浏览过

|

来源于php中文网

原创

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

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

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

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

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

立即学习Java免费学习笔记(深入)”;

界面实现:

  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类。

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

全诚商城生成HTML多用户版
全诚商城生成HTML多用户版

1、什么是店中店?店中店是全诚商多用户版的一大特色,它既是独立的个体,又具有群集功能。我们做个例子说明:假设尊贵的您现实生活中租赁了一个店面,店面空间很大,您可以把您的店面分割成很多独立空间再向别人转租,这样您可以额外获得一部分租赁费用收入,借以减少你的个人租赁费用投入,还能起到活跃销售场所的气氛,俗话说:货卖一堆吗。你租赁的店面可以完全分割成很多空间向外转租,也可以自己保留一块空间为自己销售商品

下载
//向上移动的算法
for
(int r = 0; r < arry.length; r++) for (int c = 0; c < arry[r].length; c++) {if (arry[r][c] > max)//找出数组最大值,用于判断玩家的方块是否达到2048max = 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。条件成立则调用相应算法实现。

 

相关文章

在线游戏
在线游戏

海量精品小游戏合集,无需安装即点即玩,休闲益智、动作闯关应有尽有,秒开即玩,轻松解压,快乐停不下来

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

14

2026.01.30

c++ 字符串格式化
c++ 字符串格式化

本专题整合了c++字符串格式化用法、输出技巧、实践等等内容,阅读专题下面的文章了解更多详细内容。

9

2026.01.30

java 字符串格式化
java 字符串格式化

本专题整合了java如何进行字符串格式化相关教程、使用解析、方法详解等等内容。阅读专题下面的文章了解更多详细教程。

12

2026.01.30

python 字符串格式化
python 字符串格式化

本专题整合了python字符串格式化教程、实践、方法、进阶等等相关内容,阅读专题下面的文章了解更多详细操作。

4

2026.01.30

java入门学习合集
java入门学习合集

本专题整合了java入门学习指南、初学者项目实战、入门到精通等等内容,阅读专题下面的文章了解更多详细学习方法。

20

2026.01.29

java配置环境变量教程合集
java配置环境变量教程合集

本专题整合了java配置环境变量设置、步骤、安装jdk、避免冲突等等相关内容,阅读专题下面的文章了解更多详细操作。

18

2026.01.29

java成品学习网站推荐大全
java成品学习网站推荐大全

本专题整合了java成品网站、在线成品网站源码、源码入口等等相关内容,阅读专题下面的文章了解更多详细推荐内容。

19

2026.01.29

Java字符串处理使用教程合集
Java字符串处理使用教程合集

本专题整合了Java字符串截取、处理、使用、实战等等教程内容,阅读专题下面的文章了解详细操作教程。

3

2026.01.29

Java空对象相关教程合集
Java空对象相关教程合集

本专题整合了Java空对象相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3万人学习

C# 教程
C# 教程

共94课时 | 8万人学习

Java 教程
Java 教程

共578课时 | 53.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号