基于Java实现的2048小游戏

teardrop

发布日期: 2021-02-19 10:21:36 浏览量: 102
评分:
star star star star star star star star star star_border
*转载请注明来自write-bug.com

一、实验目的

通过编写Java的应用系统综合实例——2048小游戏,总结、回顾和实践面向对象的编程思想以及编程方法,并通过编写程序来掌握Java语言编程技巧,将学习到的知识融会贯通,同时提高调试程序的能力,养成良好的编程习惯,并增强对程序设计整体思路的把握。

程序使用Eclipse集成开发环境完成,熟悉并掌握在Eclipse开发环境下编写Java程序。

二、设备与环境

  • 硬件:计算机

  • 软件:Windows系列操作系统、JDK开发包、Eclipse开发环境

三、实验内容及要求

3.1 实验要求

使用Java swing编程实现2048游戏。游戏功能是将4*4的方框里的数字之和加到2048即获成功。

游戏规则:在一个4*4的方格里,玩家可以用键盘控制(上、下、左、右以及W、S、A、D均可),可将同一方向的数字进行累加。通过有限次的移动,将随机出现的数字2在任意一个方向一直累加到2048即获成功。若四个方向不能再移动并且没有达到2048,游戏即结束。

3.2 实验内容

3.2.1 各类及主要成员函数的功能

序号 类名及方法名 主要功能
1 Copy2048 该类为程序入口,含有main方法
2 Copy2048(构造方法) 实现控制运行等总体要求,实现游戏主板、字体设置、游戏控制、分数计算等具体要求
3 do_label_keyPressed 该方法实现游戏对键盘的响应,如上、下、左、右以及W、S、A、D。即对游戏累加方向的控制
4 Create2 该方法实现在游戏面板内的随机位置出现数字2
5 setColor 该方法实现对每个数字显示不同颜色的控制

3.2.2 具体代码及实现

程序入口主方法

  1. public static void main(String[] args){
  2. EventQueue.invokeLater(new Runnable(){
  3. //调用完毕后,它会被销毁,因为匿名内部类是作为临时变量存在的,给它分配的内存在此时会被释放
  4. public void run(){
  5. try{
  6. Copy2048 frame = new Copy2048();
  7. frame.setVisible(true); //透明度
  8. }
  9. catch(Exception e1){
  10. e1.printStackTrace();
  11. }
  12. }
  13. });
  14. }

实现控制运行等总体要求,实现游戏主板、字体设置、游戏控制、分数计算等具体要求

  1. public Copy2048(){
  2. super();
  3. setResizable(false); //禁止调整窗体大小
  4. getContentPane().setLayout(null); //设置空布局
  5. setBounds(500,50,500,615); //setBounds(x,y,width,height);
  6. setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  7. //标题窗口退出的设置,窗口上的叉号
  8. setTitle("2048PC版 计科B122班 张灏");
  9. //设置窗体标题
  10. scoresPane = new JPanel(); //创建分数显示面板
  11. scoresPane.setBackground(Color.green); //设置分数显示面板的背景色
  12. scoresPane.setBounds(20, 20, 460, 40);
  13. scoresPane.setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.YELLOW)); //设置得分面板的边框
  14. getContentPane().add(scoresPane); //将得分面板添加到窗体
  15. scoresPane.setLayout(null); //设置面板空布局
  16. labelMaxScores = new JLabel("最高分:"); //最高分标签
  17. labelMaxScores.setFont(font); //设置字体类型和大小
  18. labelMaxScores.setBounds(10, 5, 50, 30); //设置最高分标签的位置尺寸
  19. scoresPane.add(labelMaxScores); //将最高分标签添加到得分容器中
  20. textMaxScores = new JTextField("暂不可用"); //得分标签
  21. textMaxScores.setBounds(60, 5, 150, 30);
  22. textMaxScores.setFont(font);
  23. textMaxScores.setEditable(false);
  24. scoresPane.add(textMaxScores); //将得分标签添加到分数面板中
  25. labelScores = new JLabel("得 分:");
  26. labelScores.setFont(font); //设置字体类型和大小
  27. labelScores.setBounds(240, 5, 50, 30);
  28. scoresPane.add(labelScores);
  29. textScores = new JLabel(String.valueOf(scores));
  30. textScores.setFont(font);
  31. textScores.setBounds(290, 5, 150, 30);
  32. scoresPane.add(textScores);
  33. mainPane = new JPanel(); //创建游戏主面板
  34. mainPane.setBounds(20, 70, 460, 500); //设置主面板位置尺寸
  35. this.getContentPane().add(mainPane);
  36. mainPane.setLayout(null); //设置空布局
  37. texts = new JLabel[4][4]; //创建文本框二维数组
  38. for(int i = 0; i < 4; i++){ //遍历数组
  39. for(int j = 0; j < 4; j++){
  40. texts[i][j] = new JLabel(); //创建标签
  41. texts[i][j].setFont(font2);
  42. texts[i][j].setHorizontalAlignment(SwingConstants.CENTER);
  43. //设置文本的水平对齐方式
  44. texts[i][j].setText("");
  45. texts[i][j].setBounds(120 * j, 120 * i, 100, 100);
  46. //设置方块的大小位置
  47. setColor(i, j, "");
  48. texts[i][j].setOpaque(true);
  49. //设置控件不透明
  50. texts[i][j].setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.green));//设置方块边框颜色
  51. mainPane.add(texts[i][j]); //将创建的文本框放在
  52. }
  53. }
  54. tips = new JLabel("Tips:使用上、下、左、右键或者W、S、A、D键控制");
  55. tips.setFont(font);
  56. tips.setBounds(60,480,400,20);
  57. mainPane.add(tips);
  58. textMaxScores.addKeyListener(new KeyAdapter(){
  59. //为最高分标签添加按键监听器
  60. public void keyPressed( KeyEvent e){ //键盘敲击
  61. do_label_keyPressed(e); //调用时间处理方法
  62. }
  63. });
  64. Create2();
  65. Create2();
  66. }

该方法实现游戏对键盘的响应,如上、下、左、右以及W、S、A、D。即对游戏累加方向的控制

  1. protected void do_label_keyPressed(final KeyEvent e){
  2. int code = e.getKeyCode(); //获取按键代码
  3. int a ; //a 的引入是为了防止连加的情况出现
  4. String str ;
  5. String str1;
  6. int num;
  7. switch(code){
  8. case KeyEvent.VK_LEFT:
  9. case KeyEvent.VK_A: //如果按键代码是左方向键或者A键
  10. for(int i = 0; i < 4; i++){
  11. a = 5;
  12. for(int k = 0; k < 3; k++){
  13. for(int j = 1; j < 4; j++){ //遍历16个方块
  14. str = texts[i][j].getText(); //获取当前方块标签文本字符
  15. str1 = texts[i][j-1].getText(); //获取当前左1方块标签文本字符
  16. if(str1.compareTo("") == 0){ //如果左1方块文本为空字符
  17. texts[i][j-1].setText(str); //字符左移
  18. setColor(i, j-1,str);
  19. texts[i][j].setText(""); //当前方块字符置空
  20. setColor(i, j, "");
  21. }
  22. else if((str.compareTo(str1) == 0) && (j !=a) && (j != a-1)){ //如果当前方块和左1方块文本字符相等
  23. num = Integer.parseInt(str);
  24. scores += num;
  25. times ++;
  26. str = String.valueOf(2 * num);
  27. texts[i][j-1].setText(str); //左1方块文本字符变为两方块之和
  28. setColor(i, j-1, str);
  29. texts[i][j].setText(""); //当前方块字符置空
  30. setColor(i, j, "");
  31. a = j;
  32. }
  33. }
  34. }
  35. }
  36. l1 = 1; //用于判断游戏是否失败
  37. Create2();
  38. break;
  39. case KeyEvent.VK_RIGHT:
  40. case KeyEvent.VK_D:
  41. for(int i = 0; i < 4; i ++){
  42. a = 5;
  43. for(int k = 0; k < 3; k++){
  44. for(int j = 2; j >= 0; j--){
  45. str = texts[i][j].getText();
  46. str1 = texts[i][j + 1].getText();
  47. if(str1.compareTo("") == 0){
  48. texts[i][j + 1].setText(str);
  49. setColor(i, j+1, str);
  50. texts[i][j].setText("");
  51. setColor(i, j, "");
  52. }
  53. else if(str.compareTo(str1) == 0 && j !=a && j != a+ 1){
  54. num = Integer.parseInt(str);
  55. scores += num ;
  56. times ++;
  57. str = String.valueOf(2 * num);
  58. texts[i][j + 1].setText(str);
  59. setColor(i, j+1, str);
  60. texts[i][j].setText("");
  61. setColor(i, j, "");
  62. a = j;
  63. }
  64. }
  65. }
  66. }
  67. l2 = 1;
  68. Create2();
  69. break;
  70. case KeyEvent.VK_UP:
  71. case KeyEvent.VK_W:
  72. for(int j = 0; j < 4; j++){
  73. a = 5;
  74. for(int k = 0; k < 3; k++){
  75. for(int i = 1; i < 4; i++){
  76. str = texts[i][j].getText();
  77. str1 = texts[i - 1][j].getText();
  78. if(str1.compareTo("") == 0){
  79. texts[i - 1][j].setText(str);
  80. setColor(i-1, j, str);
  81. texts[i][j].setText("");
  82. setColor(i, j, "");
  83. }
  84. else if(str.compareTo(str1) == 0 && i != a && i != a -1){
  85. num = Integer.parseInt(str);
  86. scores += num ;
  87. times ++;
  88. str = String.valueOf(2 * num);
  89. texts[i - 1][j].setText(str);
  90. setColor(i-1, j, str);
  91. texts[i][j].setText("");
  92. setColor(i, j, "");
  93. a = i;
  94. }
  95. }
  96. }
  97. }
  98. l3 =1;
  99. Create2();
  100. break;
  101. case KeyEvent.VK_DOWN:
  102. case KeyEvent.VK_S:
  103. for(int j = 0; j < 4; j ++){
  104. a = 5;
  105. for(int k = 0; k < 5; k++){
  106. for(int i = 2; i >= 0; i--){
  107. str = texts[i][j].getText();
  108. str1 = texts[i + 1][j].getText();
  109. if(str1.compareTo("") == 0){
  110. texts[i + 1][j].setText(str);
  111. setColor(i+1, j, str);
  112. texts[i][j].setText("");
  113. setColor(i, j, "");
  114. }
  115. else if(str.compareTo(str1) == 0 && i != a && i != a + 1){
  116. num = Integer.parseInt(str);
  117. scores += num ;
  118. times ++;
  119. str = String.valueOf(2 * num);
  120. texts[i + 1][j].setText(str );
  121. setColor(i+1, j, str);
  122. texts[i][j].setText("");
  123. setColor(i, j, "");
  124. a = i;
  125. }
  126. }
  127. }
  128. }
  129. l4 = 1;
  130. Create2();
  131. break;
  132. default:
  133. break;
  134. }
  135. textScores.setText(String.valueOf(scores));
  136. }

该方法实现在游戏面板内的随机位置出现数字2

  1. public void Create2(){
  2. int i ,j;
  3. boolean r = false;
  4. String str;
  5. if(times > 0){
  6. while(!r){
  7. i = random.nextInt(4);
  8. j = random.nextInt(4);
  9. str = texts[i][j].getText();
  10. if((str.compareTo("") == 0)){
  11. texts[i][j].setIcon(icon2);
  12. texts[i][j].setText("2");
  13. setColor(i, j, "2");
  14. times --;
  15. r = true;
  16. l1 = l2 = l3 = l4 = 0;
  17. }
  18. }
  19. }
  20. else if(l1 >0 && l2 >0 && l3 > 0 && l4 > 0){ //l1到l4同时被键盘赋值为1说明任何方向键都不能产生新的数字2,说明游戏失败
  21. tips.setText(" GAME OVER !");
  22. }
  23. }

该方法实现对每个数字显示不同颜色的控制

  1. public void setColor(int i, int j, String str){
  2. switch(str){
  3. case "2":
  4. texts[i][j].setBackground(Color.yellow);
  5. break;
  6. case "4":
  7. texts[i][j].setBackground(Color.red);
  8. break;
  9. case "8":
  10. texts[i][j].setBackground(Color.pink);
  11. break;
  12. case "16":
  13. texts[i][j].setBackground(Color.orange);
  14. break;
  15. case "32":
  16. texts[i][j].setBackground(Color.magenta);
  17. break;
  18. case "64":
  19. texts[i][j].setBackground(Color.LIGHT_GRAY);
  20. break;
  21. case "128":
  22. texts[i][j].setBackground(Color.green);
  23. break;
  24. case "256":
  25. texts[i][j].setBackground(Color.gray);
  26. break;
  27. case "512":
  28. texts[i][j].setBackground(Color.DARK_GRAY);
  29. break;
  30. case "1024":
  31. texts[i][j].setBackground(Color.cyan);
  32. break;
  33. case "2048":
  34. texts[i][j].setBackground(Color.blue);
  35. break;
  36. case "":
  37. case "4096":
  38. texts[i][j].setBackground(Color.white);
  39. break;
  40. default:
  41. break;
  42. }
  43. }

3.2.3 游戏运行结果

初始游戏界面,上面有最高分及得分情况,最下面为帮助菜单

每个方向都能累加,并在空白处随机显示新的数字2,并且计算得分

游戏失败的情况

四个方向不能再移动并且没有达到2048,游戏即结束。

四、实验结果及分析

在学习Java程序从设计这门课之前,自己接触过一些有关Java的东西,当初觉得要比C和C++简单,因为没有C的指针,而且又和C++一样有封装的概念。后来上网查了查,发现Java语言在现在使用的非常广泛,也是一门比较容易入门的语言。

这个2048小游戏是当初非常流行的手机游戏。不过代码确实很简单,只有350行左右。刚开始看代码的时候也是看不懂,因为有些函数只是认识但是不知道怎么用,后来自己通过查资料,掌握了它们的用法,觉得是一件非常自豪的事情。但是我觉得游戏还是做得不够完美,应该再加入时间计时以及查看得分排行榜的功能。现在我虽然达不到这个要求,但是我相信只有肯钻研,还是会做好的。以后要多练习敲代码的能力,不要怕辛苦,努力定会成功。

上传的附件 cloud_download 基于Java实现的2048小游戏.7z ( 177.20kb, 1次下载 )
error_outline 下载需要9点积分

发送私信

如果你想飞,放弃一切让你下降的重量

16
文章数
22
评论数
最近文章
eject