修改row和col可以改变大小,如果棋盘太小可以更改frame的长和宽
按 a 可以让电脑按上左下右的规则一直运行到游戏结束 // 暂时不知道怎么变成动态的,并且row和col大于6时就会运行很久
上下左右都是通过 先合并,再移动 的方式实现的 // 可能比较复杂
这是类的代码,要运行直接再main函数里面实例化对象就行了
package com.game.frame;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class GameFrame implements KeyListener {
private static final int row = 4;
private static final int col = 4;
private static final int totalNum = 12;
int aiCount = 0;
long Score = 0;
Font fontSongti = new Font("宋体", Font.BOLD, 24); // 加粗
Color backgroundColor = new Color(188, 177, 159);
Color numberColor[] = new Color[totalNum];
long[] gameBoard = new long[row * col];
JFrame frame = new JFrame("2048");
JLabel[] jl = new JLabel[row * col];
JPanel jp = new JPanel();
boolean moved = false;
public GameFrame() {
// 初始化棋盘
initGameBoard();
// 初始化各种颜色
setColor();
// 设置窗体属性
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 关闭就结束程序
jp.setLayout(new GridLayout(row, col, 10, 10));
jp.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
jp.setBackground(backgroundColor);
frame.setVisible(true);
frame.setSize(600, 600);
frame.setResizable(false); // 无法最大化
frame.setLocationRelativeTo(null); // 居中显示
frame.setFocusable(true);
// 添加组件
frame.add(jp);
loadBoard();
frame.addKeyListener(this);
}
public void initGameBoard() {
for (int i = 0; i < row * col; ++i) {
gameBoard[i] = 0;
}
// 随机生成两个地方
generateRandomNum();
generateRandomNum();
}
public boolean check() {
boolean dead = true;
for(int i = 0; i < row; ++i) {
for(int j = 0; j < col; ++j) {
if(0 == gameBoard[i * row + j]) {
return false;
}
}
}
for(int i = 0; i < row; ++i) {
for(int j = 0; j < col - 1; ++j) {
if(gameBoard[i * row + j] == gameBoard[i * row + (j + 1)]) {
dead = false;
}
}
}
for(int i = 0; i < row; ++i) {
for(int j = 0; j < col - 1; ++j) {
if(gameBoard[i + j * col] == gameBoard[i + (j + 1) * col]) {
dead = false;
}
}
}
return dead;
}
public void setJLabelColor(JLabel jl) {
switch (jl.getText()) {
case "0":
jl.setBackground(numberColor[0]);
break;
case "2":
jl.setBackground(numberColor[1]);
break;
case "4":
jl.setBackground(numberColor[2]);
break;
case "8":
jl.setBackground(numberColor[3]);
break;
case "16":
jl.setBackground(numberColor[4]);
break;
case "32":
jl.setBackground(numberColor[5]);
break;
case "64":
jl.setBackground(numberColor[6]);
break;
case "128":
jl.setBackground(numberColor[7]);
break;
case "256":
jl.setBackground(numberColor[8]);
break;
case "512":
jl.setBackground(numberColor[9]);
break;
case "1024":
jl.setBackground(numberColor[10]);
break;
case "2048":
jl.setBackground(numberColor[11]);
break;
default:
jl.setBackground(Color.yellow);
break;
}
}
public void setColor() {
numberColor[0] = new Color(204, 192, 178); // 空白
numberColor[1] = new Color(238, 228, 218); // 2
numberColor[2] = new Color(236, 224, 202); // 4
numberColor[3] = new Color(245, 149, 101); // 8
numberColor[4] = new Color(243, 176, 121); // 16
numberColor[5] = new Color(245, 124, 59); // 32
numberColor[6] = new Color(250, 91, 60); // 64
numberColor[7] = new Color(239, 206, 109); // 128
numberColor[8] = new Color(242, 205, 92); // 256
numberColor[9] = new Color(240, 198, 84); // 512
numberColor[10] = new Color(235, 198, 66); // 1024
numberColor[11] = new Color(235, 195, 45); // 2048
}
public void loadBoard() {
for (int i = 0; i < row * col; ++i) {
jl[i] = new JLabel(gameBoard[i] + "", JLabel.CENTER);
jl[i].setFont(fontSongti);
jl[i].setOpaque(true);
jl[i].setBorder(new EmptyBorder(10, 10, 10, 10));
setJLabelColor(jl[i]);
jp.add(jl[i]);
}
}
public void up() {
for (int i = 0; i < col; ++i) { // 第 i 列
for (int j = 0; j < row - 1; ++j) { // 从第 j 行往下
if (gameBoard[i + j * row] != 0) {
for (int k = j + 1; k < row; k++) {
if (gameBoard[i + k * row] != 0) {
if (gameBoard[i + k * row] == gameBoard[i + j * row]) {
Score += gameBoard[i + j * row];
gameBoard[i + j * row] *= 2;
gameBoard[i + k * row] = 0;
} else {
break;
}
}
}
}
}
for (int j = 0; j < row - 1; ++j) {
if (gameBoard[i + j * row] == 0) {
for (int k = j + 1; k < row; k++) {
if (gameBoard[i + k * row] != 0) {
moved = true;
long temp = gameBoard[i + k * row];
gameBoard[i + k * row] = 0;
gameBoard[i + j * row] = temp;
break;
}
}
}
}
}
}
public void down() {
for (int i = 0; i < col; ++i) { // 第 i 列
for (int j = row - 1; j > 0; --j) { // 从第 j 行往上
if (gameBoard[i + j * row] != 0) {
for (int k = j - 1; k >= 0; --k) {
if (gameBoard[i + k * row] != 0) {
if (gameBoard[i + k * row] == gameBoard[i + j * row]) {
Score += gameBoard[i + j * row];
gameBoard[i + j * row] *= 2;
gameBoard[i + k * row] = 0;
} else {
break;
}
}
}
}
}
for (int j = row - 1; j > 0; --j) {
if (gameBoard[i + j * row] == 0) {
for (int k = j - 1; k >= 0; --k) {
if (gameBoard[i + k * row] != 0) {
moved = true;
long temp = gameBoard[i + k * row];
gameBoard[i + k * row] = 0;
gameBoard[i + j * row] = temp;
break;
}
}
}
}
}
}
public void left() {
for (int i = 0; i < row; ++i) { // 第 i 行
for (int j = 0; j < col - 1; ++j) { // 从第 j 列往左
if (gameBoard[i * row + j] != 0) {
for (int k = j + 1; k < col; ++k) {
if (gameBoard[i * row + k] != 0) {
if (gameBoard[i * row + k] == gameBoard[i * row + j]) {
Score += gameBoard[i * row + j];
gameBoard[i * row + j] *= 2;
gameBoard[i * row + k] = 0;
} else {
break;
}
}
}
}
}
for (int j = 0; j < col; ++j) {
if (gameBoard[i * row + j] == 0) {
for (int k = j + 1; k < col; ++k) {
if (gameBoard[i * row + k] != 0) {
moved = true;
long temp = gameBoard[i * row + k];
gameBoard[i * row + k] = 0;
gameBoard[i * row + j] = temp;
break;
}
}
}
}
}
}
public void right() {
for (int i = 0; i < row; ++i) { // 第 i 行
for (int j = col - 1; j > 0; --j) { // 从第 j 列往右
if (gameBoard[i * row + j] != 0) {
for (int k = j - 1; k >= 0; --k) {
if (gameBoard[i * row + k] != 0) {
if (gameBoard[i * row + k] == gameBoard[i * row + j]) {
Score += gameBoard[i * row + j];
gameBoard[i * row + j] *= 2;
gameBoard[i * row + k] = 0;
} else {
break;
}
}
}
}
}
for (int j = col - 1; j > 0; --j) {
if (gameBoard[i * row + j] == 0) {
for (int k = j - 1; k >= 0; --k) {
if (gameBoard[i * row + k] != 0) {
moved = true;
long temp = gameBoard[i * row + k];
gameBoard[i * row + k] = 0;
gameBoard[i * row + j] = temp;
break;
}
}
}
}
}
}
public void generateRandomNum() {
int temp;
while (true) {
for (int i = 0; i < row * col; ++i) {
temp = (int) (Math.random() * row * col) % (row * col);
if (gameBoard[temp] == 0) {
if (Math.random() < 0.8) {
gameBoard[temp] = 2;
} else {
gameBoard[temp] = 4;
}
return;
}
}
}
}
public void showBoard() {
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
System.out.print(gameBoard[i * row + j] + "");
}
System.out.println();
}
}
@Override
public void keyTyped(KeyEvent e) {
// do nothing
if(e.getKeyChar() == 'a') {
while (!check()) {
moved = false;
switch(aiCount) {
case 0:
up();
aiCount++;
break;
case 1:
left();
aiCount++;
break;
case 2:
down();
aiCount++;
break;
case 3:
right();
aiCount = 0;
break;
default:
break;
}
jp.removeAll();
if (moved) {
generateRandomNum();
}
loadBoard();
jp.updateUI();
}
JOptionPane.showMessageDialog(frame, "最终得分" + Score, "Game Over!", JOptionPane.YES_OPTION);
System.exit(0);
}
}
@Override
public void keyPressed(KeyEvent e) {
moved = false;
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
down();
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
up();
} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
left();
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
right();
}
jp.removeAll();
if (moved) {
generateRandomNum();
}
loadBoard();
jp.updateUI();
if(check()) {
JOptionPane.showMessageDialog(frame, "最终得分" + Score, "Game Over!", JOptionPane.YES_OPTION);
System.exit(0);
}
}
@Override
public void keyReleased(KeyEvent e) {
// do nothing
}
}