文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

使用Java编写一个2048小游戏

2023-06-06 15:09

关注

本文章向大家介绍使用Java编写一个2048小游戏的基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Java可以用来干什么

Java主要应用于:1. web开发;2. Android开发;3. 客户端开发;4. 网页开发;5. 企业级应用开发;6. Java大数据开发;7.游戏开发等。

1.项目结构

使用Java编写一个2048小游戏

2.代码

BaseData接口

package com.hsy.game;import java.awt.*;public interface BaseData { Font topicFont = new Font("微软雅黑", Font.BOLD, 50); Font scoreFont = new Font("微软雅黑", Font.BOLD, 28); Font normalFont = new Font("宋体", Font.PLAIN, 20); Font font1 = new Font("宋体", Font.BOLD, 46); Font font2 = new Font("宋体", Font.BOLD, 40); Font font3 = new Font("宋体", Font.BOLD, 34); Font font4 = new Font("宋体", Font.BOLD, 28); Font font5 = new Font("宋体", Font.BOLD, 22); int normalFontData = 20; int topicFontData = 30; void init(); void showView();}

GameView类

package com.hsy.game;import java.awt.Color;import java.awt.FlowLayout;import java.awt.FontMetrics;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.RenderingHints;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.util.ArrayList;import java.util.List;import java.util.Random;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;public class GameView implements BaseData{ private static final int jFrameWidth = 400; private static final int jFrameHeight = 530; private static int score = 0; private JFrame jFrameMain; private JLabel jLblTitle; private JLabel jLblScoreName; private JLabel jLblScore; private GameBoard gameBoard; private JLabel jlblTip; public GameView() {  init(); } @Override public void init() {  jFrameMain = new JFrame("2048小游戏");  jFrameMain.setSize(jFrameWidth, jFrameHeight);  jFrameMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  jFrameMain.setLocationRelativeTo(null);  jFrameMain.setResizable(false);  jFrameMain.setLayout(null);  jLblTitle = new JLabel("2048", JLabel.CENTER);  jLblTitle.setFont(topicFont);  jLblTitle.setForeground(Color.BLACK);  jLblTitle.setBounds(50, 0, 150, 60);  jFrameMain.add(jLblTitle);  // 分数区  jLblScoreName = new JLabel("得 分", JLabel.CENTER);  jLblScoreName.setFont(scoreFont);  jLblScoreName.setForeground(Color.WHITE);  jLblScoreName.setOpaque(true);  jLblScoreName.setBackground(Color.GRAY);  jLblScoreName.setBounds(250, 0, 120, 30);  jFrameMain.add(jLblScoreName);  jLblScore = new JLabel("0", JLabel.CENTER);  jLblScore.setFont(scoreFont);  jLblScore.setForeground(Color.WHITE);  jLblScore.setOpaque(true);  jLblScore.setBackground(Color.GRAY);  jLblScore.setBounds(250, 30, 120, 30);  jFrameMain.add(jLblScore);  // 说明:  jlblTip = new JLabel("操作: ↑ ↓ ← →, 按esc键重新开始 ",    JLabel.CENTER);  jlblTip.setFont(normalFont);  jlblTip.setForeground(Color.DARK_GRAY);  jlblTip.setBounds(0, 60, 400, 40);  jFrameMain.add(jlblTip);  gameBoard = new GameBoard();  gameBoard.setBounds(0, 100, 400, 400);  gameBoard.setBackground(Color.GRAY);  gameBoard.setFocusable(true);  gameBoard.setLayout(new FlowLayout());  jFrameMain.add(gameBoard); } // 游戏面板需要对键值实现侦听, // 这里采用内部类来继承 JPanel 类, // 并实现接口 KeyListener 中的 keyPressed 方法, // 方格是通过 @SuppressWarnings("serial") class GameBoard extends JPanel implements KeyListener {  private static final int CHECK_GAP = 10;  private static final int CHECK_ARC = 20;  private static final int CHECK_SIZE = 86;  private Check[][] checks = new Check[4][4];  private boolean isAdd = true;  public GameBoard() {   initGame();   addKeyListener(this);  }  @Override  public void keyPressed(KeyEvent e) {   switch (e.getKeyCode()) {    case KeyEvent.VK_ESCAPE:     initGame();     break;    case KeyEvent.VK_LEFT:     moveLeft();     createCheck();     judgeGameOver();     break;    case KeyEvent.VK_RIGHT:     moveRight();     createCheck();     judgeGameOver();     break;    case KeyEvent.VK_UP:     moveUp();     createCheck();     judgeGameOver();     break;    case KeyEvent.VK_DOWN:     moveDown();     createCheck();     judgeGameOver();     break;    default:     break;   }   repaint();  }  private void initGame() {   score = 0;   for (int indexRow = 0; indexRow < 4; indexRow++) {    for (int indexCol = 0; indexCol < 4; indexCol++) {     checks[indexRow][indexCol] = new Check();    }   }   // 生成两个数   isAdd = true;   createCheck();   isAdd = true;   createCheck();  }  private void createCheck() {   List<Check> list = getEmptyChecks();   if (!list.isEmpty() && isAdd) {    Random random = new Random();    int index = random.nextInt(list.size());    Check check = list.get(index);    // 2, 4出现概率3:1    check.value = (random.nextInt(4) % 3 == 0) ? 2 : 4;    isAdd = false;   }  }  // 获取空白方格  private List<Check> getEmptyChecks() {   List<Check> checkList = new ArrayList<>();   for (int i = 0; i < 4; i++) {    for (int j = 0; j < 4; j++) {     if (checks[i][j].value == 0) {      checkList.add(checks[i][j]);     }    }   }   return checkList;  }  private boolean judgeGameOver() {   jLblScore.setText(score + "");   if (!getEmptyChecks().isEmpty()) {    return false;   }   for (int i = 0; i < 3; i++) {    for (int j = 0; j < 3; j++) {     //判断是否存在可合并的方格     if (checks[i][j].value == checks[i][j + 1].value       || checks[i][j].value == checks[i + 1][j].value) {      return false;     }    }   }   return true;  }  private boolean moveLeft() {   for (int i = 0; i < 4; i++) {    for (int j = 1, index = 0; j < 4; j++) {     if (checks[i][j].value > 0) {      if (checks[i][j].value == checks[i][index].value) {       score += checks[i][index++].value <<= 1;       checks[i][j].value = 0;       isAdd = true;      } else if (checks[i][index].value == 0) {       checks[i][index].value = checks[i][j].value;       checks[i][j].value = 0;       isAdd = true;      } else if (checks[i][++index].value == 0) {       checks[i][index].value = checks[i][j].value;       checks[i][j].value = 0;       isAdd = true;      }     }    }   }   return isAdd;  }  private boolean moveRight() {   for (int i = 0; i < 4; i++) {    for (int j = 2, index = 3; j >= 0; j--) {     if (checks[i][j].value > 0) {      if (checks[i][j].value == checks[i][index].value) {       score += checks[i][index--].value <<= 1;       checks[i][j].value = 0;       isAdd = true;      } else if (checks[i][index].value == 0) {       checks[i][index].value = checks[i][j].value;       checks[i][j].value = 0;       isAdd = true;      } else if (checks[i][--index].value == 0) {       checks[i][index].value = checks[i][j].value;       checks[i][j].value = 0;       isAdd = true;      }     }    }   }   return isAdd;  }  private boolean moveUp() {   for (int i = 0; i < 4; i++) {    for (int j = 1, index = 0; j < 4; j++) {     if (checks[j][i].value > 0) {      if (checks[j][i].value == checks[index][i].value) {       score += checks[index++][i].value <<= 1;       checks[j][i].value = 0;       isAdd = true;      } else if (checks[index][i].value == 0) {       checks[index][i].value = checks[j][i].value;       checks[j][i].value = 0;       isAdd = true;      } else if (checks[++index][i].value == 0){       checks[index][i].value = checks[j][i].value;       checks[j][i].value = 0;       isAdd = true;      }     }    }   }   return isAdd;  }  private boolean moveDown() {   for (int i = 0; i < 4; i++) {    for (int j = 2, index = 3; j >= 0; j--) {     if (checks[j][i].value > 0) {      if (checks[j][i].value == checks[index][i].value) {       score += checks[index--][i].value <<= 1;       checks[j][i].value = 0;       isAdd = true;      } else if (checks[index][i].value == 0) {       checks[index][i].value = checks[j][i].value;       checks[j][i].value = 0;       isAdd = true;      } else if (checks[--index][i].value == 0) {       checks[index][i].value = checks[j][i].value;       checks[j][i].value = 0;       isAdd = true;      }     }    }   }   return isAdd;  }  @Override  public void paint(Graphics g) {   super.paint(g);   for (int i = 0; i < 4; i++) {    for (int j = 0; j < 4; j++) {     drawCheck(g, i, j);    }   }   // GameOver   if (judgeGameOver()) {    g.setColor(new Color(64, 64, 64, 150));    g.fillRect(0, 0, getWidth(), getHeight());    g.setColor(Color.WHITE);    g.setFont(topicFont);    FontMetrics fms = getFontMetrics(topicFont);    String value = "Game Over!";    g.drawString(value,      (getWidth()-fms.stringWidth(value)) / 2,      getHeight() / 2);   }  }  // 绘制方格  // Graphics2D 类扩展了 Graphics 类,  // 提供了对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制  private void drawCheck(Graphics g, int i, int j) {   Graphics2D gg = (Graphics2D) g;   gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,     RenderingHints.VALUE_ANTIALIAS_ON);   gg.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,     RenderingHints.VALUE_STROKE_NORMALIZE);   Check check = checks[i][j];   gg.setColor(check.getBackground());   // 绘制圆角   // x - 要填充矩形的 x 坐标。   // y - 要填充矩形的 y 坐标。   // width - 要填充矩形的宽度。   // height - 要填充矩形的高度。   // arcwidth - 4 个角弧度的水平直径。   // archeight - 4 个角弧度的垂直直径。   gg.fillRoundRect(CHECK_GAP + (CHECK_GAP + CHECK_SIZE) * j,     CHECK_GAP + (CHECK_GAP + CHECK_SIZE) * i,     CHECK_SIZE, CHECK_SIZE, CHECK_ARC, CHECK_ARC);   gg.setColor(check.getForeground());   gg.setFont(check.getCheckFont());   // 对文字的长宽高测量。   FontMetrics fms = getFontMetrics(check.getCheckFont());   String value = String.valueOf(check.value);   //使用此图形上下文的当前颜色绘制由指定迭代器给定的文本。   //getAscent()是FontMetrics中的一个方法,   //它返回某字体的基线(baseline)到该字体中大多数字符的升部(ascender)之间的距离   //getDescent 为降部   gg.drawString(value,     CHECK_GAP + (CHECK_GAP + CHECK_SIZE) * j +       (CHECK_SIZE - fms.stringWidth(value)) / 2,     CHECK_GAP + (CHECK_GAP + CHECK_SIZE) * i +       (CHECK_SIZE - fms.getAscent() - fms.getDescent()) / 2       + fms.getAscent());  }  @Override  public void keyReleased(KeyEvent e) {  }  @Override  public void keyTyped(KeyEvent e) {  } } @Override public void showView() {  jFrameMain.setVisible(true); }}

Check类

package com.hsy.game;import java.awt.Color;import java.awt.Font;public class Check { public int value; public Check() {  clear(); } public void clear() {  value = 0; } public Color getForeground() {  switch (value) {   case 0:    return new Color(0xcdc1b4);   case 2:   case 4:    return Color.BLACK;   default:    return Color.WHITE;  } } public Color getBackground() {  switch (value) {   case 0:    return new Color(0xcdc1b4);   case 2:    return new Color(0xeee4da);   case 4:    return new Color(0xede0c8);   case 8:    return new Color(0xf2b179);   case 16:    return new Color(0xf59563);   case 32:    return new Color(0xf67c5f);   case 64:    return new Color(0xf65e3b);   case 128:    return new Color(0xedcf72);   case 256:    return new Color(0xedcc61);   case 512:    return new Color(0xedc850);   case 1024:    return new Color(0xedc53f);   case 2048:    return new Color(0xedc22e);   case 4096:    return new Color(0x65da92);   case 8192:    return new Color(0x5abc65);   case 16384:    return new Color(0x248c51);   default:    return new Color(0x248c51);  } } public Font getCheckFont() {  if (value < 10) {   return BaseData.font1;  }  if (value < 100) {   return BaseData.font2;  }  if (value < 1000) {   return BaseData.font3;  }  if (value < 10000) {   return BaseData.font4;  }  return BaseData.font5; }}

Test类

package com.hsy.game;public class Test { public static void main(String[] args) {  new GameView().showView(); }}

以上就是小编为大家带来的使用Java编写一个2048小游戏的全部内容了,希望大家多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯