温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

使用Java编写一个2048小游戏

发布时间:2021-03-01 15:06:47 来源:亿速云 阅读:338 作者:戴恩恩 栏目:开发技术

本文章向大家介绍使用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小游戏的全部内容了,希望大家多多支持亿速云!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI