本文主要是介绍用JAVA实现2048小游戏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
用JAVA实现2048小游戏
- 前言
- 一、代码
- 运行结果
前言
今天给大家分享一个简单的游戏——2048,想必大家平常都玩过这款,那么今天我就给大家分享一下这游戏的代码吧。下面直接给大家上代码展示!!
一、代码
package com.company;import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;
//继承 JPanel 用于我们游戏界面布局
//tips:JPanel 是 Java图形用户界面(GUI)工具包swing中的面板容器类
/*** 2048小游戏* 游戏玩法:通过上下左右方向键移动图块,使得数字合出2048则获胜*/
public class Game2048 extends JPanel {//枚举:开始,获胜,正在进行游戏,游戏结束enum State {start, won, running, over}final Color[] colorTable = {new Color(0x701710), new Color(0xFFE4C3), new Color(0xfff4d3),new Color(0xffdac3), new Color(0xe7b08e), new Color(0xe7bf8e),new Color(0xffc4c3), new Color(0xE7948e), new Color(0xbe7e56),new Color(0xbe5e56), new Color(0x9c3931), new Color(0x701710)};final static int target = 2048;//游戏最终目标static int higheNum;//最高数static int score;private Color gridColor = new Color(0xBBADA0);//网格颜色private Color emptyColor = new Color(0xCDC1B4);//没有图块的格子的颜色private Color startColor = new Color(0xFFEBCD);//开始界面框的颜色private Random rand = new Random();private Tile[][] tiles;private int side = 4;private State gamestate = State.start;private boolean checkingAvailableMoves;public Game2048() {setPreferredSize(new Dimension(900, 700));setBackground(new Color(0xFAF8EF));setFont(new Font("SansSerif", Font.BOLD, 48));setFocusable(true);addMouseListener(new MouseAdapter() {@Overridepublic void mousePressed(MouseEvent e) {startGame();repaint();}});addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {switch (e.getKeyCode()) {case KeyEvent.VK_UP:moveUp();break;case KeyEvent.VK_DOWN:moveDown();break;case KeyEvent.VK_LEFT:moveLeft();break;case KeyEvent.VK_RIGHT:moveRight();break;}repaint();}});}//复写JPanel里面的paintComponent方法,创建一个我们自己想要的界面@Overridepublic void paintComponent(Graphics gg) {super.paintComponent(gg);Graphics2D g = (Graphics2D) gg;g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);drawGrid(g);}//开始游戏void startGame() {if (gamestate != State.running) {score = 0;higheNum = 0;gamestate = State.running;tiles = new Tile[side][side];//执行两次,生成两个随机数addRandomTile();addRandomTile();}}//生成框及里面内容void drawGrid(Graphics2D g) {g.setColor(gridColor);g.fillRoundRect(200, 100, 499, 499, 15, 15);if (gamestate == State.running) {for (int r = 0; r < side; r++) {for (int c = 0; c < side; c++) {if (tiles[r][c] == null) {g.setColor(emptyColor);g.fillRoundRect(215 + c * 121, 115 + r * 121, 106, 106, 7, 7);} else {drawTile(g, r, c);}}}} else {g.setColor(startColor);g.fillRoundRect(215, 115, 469, 469, 7, 7);g.setColor(gridColor.darker());//设置一个比当前颜色深一级的Colorg.setFont(new Font("SansSerif", Font.BOLD, 128));g.drawString("2048", 310, 270);g.setFont(new Font("SansSerif", Font.BOLD, 20));if (gamestate == State.won) {g.drawString("恭喜你,你成功得到2048!!", 330, 350);} else if (gamestate == State.over)g.drawString("你失败了,请重新开始游戏", 330, 350);g.setColor(gridColor);g.drawString("开始游戏", 390, 470);g.drawString("tips:使用上下左右箭头移动图块", 310, 530);}}void drawTile(Graphics2D g, int r, int c) {int value = tiles[r][c].getValue();g.setColor(colorTable[(int) (Math.log(value) / Math.log(2)) + 1]);g.fillRoundRect(215 + c * 121, 115 + r * 121, 106, 106, 7, 7);String s = String.valueOf(value);g.setColor(value < 128 ? colorTable[0] : colorTable[1]);FontMetrics fm = g.getFontMetrics();int asc = fm.getAscent();int dec = fm.getDescent();int x = 215 + c * 121 + (106 - fm.stringWidth(s)) / 2;int y = 115 + r * 121 + (asc + (106 - (asc + dec)) / 2);g.drawString(s, x, y);}private void addRandomTile() {int pos = rand.nextInt(side * side);int row, col;do {pos = (pos + 1) % (side * side);row = pos / side;col = pos % side;} while (tiles[row][col] != null);int val = rand.nextInt(10) == 0 ? 4 : 2;tiles[row][col] = new Tile(val);}private boolean move(int countDownFrom, int yIncr, int xIncr) {boolean moved = false;for (int i = 0; i < side * side; i++) {int j = Math.abs(countDownFrom - i);int r = j / side;int c = j % side;if (tiles[r][c] == null)continue;int nextR = r + yIncr;int nextC = c + xIncr;while (nextR >= 0 && nextR < side && nextC >= 0 && nextC < side) {Tile next = tiles[nextR][nextC];Tile curr = tiles[r][c];if (next == null) {if (checkingAvailableMoves)return true;tiles[nextR][nextC] = curr;tiles[r][c] = null;r = nextR;c = nextC;nextR += yIncr;nextC += xIncr;moved = true;} else if (next.canMergeWith(curr)) {if (checkingAvailableMoves)return true;int value = next.mergeWith(curr);if (value > higheNum)higheNum = value;score += value;tiles[r][c] = null;moved = true;break;} elsebreak;}}if (moved) {if (higheNum < target) {clearMerged();addRandomTile();if (!movesAvailable()) {//如果不能再移动图块,则则把游戏状态变成游戏失败gamestate = State.over;}} else if (higheNum == target)//如果最高数=2048,则把游戏状态变成游戏成功gamestate = State.won;}return moved;}boolean moveUp() {return move(0, -1, 0);}boolean moveDown() {return move(side * side - 1, 1, 0);}boolean moveLeft() {return move(0, 0, -1);}boolean moveRight() {return move(side * side - 1, 0, 1);}void clearMerged() {for (Tile[] row : tiles)for (Tile tile : row)if (tile != null)tile.setMerged(false);}//判断是否还能继续移动图块boolean movesAvailable() {checkingAvailableMoves = true;boolean hasMoves = moveUp() || moveDown() || moveLeft() || moveRight();checkingAvailableMoves = false;return hasMoves;}public static void main(String[] args) {SwingUtilities.invokeLater(() -> {JFrame f = new JFrame();f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.setTitle("2048小游戏");f.setResizable(true);f.add(new Game2048(), BorderLayout.CENTER);f.pack();f.setLocationRelativeTo(null);f.setVisible(true);});}
}class Tile {private boolean merged;private int value;Tile(int val) {value = val;}boolean canMergeWith(Tile other) {return !merged && other != null && !other.merged && value == other.getValue();}int mergeWith(Tile other) {if (canMergeWith(other)) {value *= 2;merged = true;return value;}return -1;}//set getint getValue() {return value;}void setMerged(boolean m) {merged = m;}
}
运行结果
1.开始界面
2.游戏界面
3.失败后界面
这篇关于用JAVA实现2048小游戏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!