java實現2048

修改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
	}

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章