1.花了半天写的,得心应手,实现了所有功能,包括最高分的本地存储
2.很适合j2se阶段新手学习
3.算法一般,没做太多优化
4.效果如下
##主类——GUI
package yy.game2048;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class GUI {
static JFrame jFrame;
static GamePanel game2048;
static int pressDir;
static Cell onlyCell;
static int highest;
static int ifNew;
static String dialog;
static File highestFile;
static FileOutputStream foStream;
static FileInputStream fIStream;
static DataOutputStream highestOS;
static DataInputStream highestIS;
public static void main(String[] args) throws InterruptedException, IOException {
init();
while (ifNew==0) {
game2048.repaint();
newGame();
highestOS.writeInt(highest);
}
jFrame.dispose();
highestIS.close();
highestOS.close();
}
private static void newGame() throws InterruptedException, IOException {
Cell.cellsMap.put((int) (Math.random()*4)+1, new Cell(2));
while (!Cell.ifGameOver()) {
while (pressDir==0) {
Thread.sleep(200);}//
Cell.move(pressDir);
if (Cell.cellsMap.size()!=16) {
onlyCell = new Cell(pressDir);
Cell.cellMap.put(onlyCell.getCellKey(), false);
Cell.cellsMap.put(onlyCell.getCellKey(), onlyCell);
}
game2048.repaint();
GUI.pressDir = 0;
}
if (Cell.scores()>highest) {
highest = Cell.scores();
highestOS.writeInt(highest);
dialog = "你的得分为:"+Cell.scores()+", 创造了历史,想继续打破吗?";
}else {
dialog = "你的得分为:"+Cell.scores()+", 不及历史最高分:"+highest+", 要再来一局吗?";
}
String[] options = {"再来一局吧","不玩了"};
ifNew = JOptionPane.showOptionDialog(null, dialog, "Game Over",
JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
Cell.cellsMap.clear();
for (int i = 1; i <=16; i++) {
Cell.cellMap.put(i, true);
}
}
public static void init() throws InterruptedException, IOException {
jFrame = new JFrame("2048小游戏");
game2048 = new GamePanel();
pressDir = 0;
jFrame.setBounds(700, 240, 515, 543);
jFrame.add(game2048);
jFrame.setVisible(true);
jFrame.addKeyListener(new DirListener());
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
highestFile = new File("C:\\Users\\鳗鱼\\Desktop\\笔记\\2048HighetScore.txt");
fIStream = new FileInputStream(highestFile);
highestIS = new DataInputStream(fIStream);
try {
highest = highestIS.readInt();
} catch (java.io.EOFException e) {
highest = 0;
}
System.out.println(highest);
foStream = new FileOutputStream(highestFile);
highestOS = new DataOutputStream(foStream);
}
static class GamePanel extends JPanel{
private static final long serialVersionUID = 1L;
@Override
public void paint(Graphics g) {
super.paint(g);
for (Integer cellPosition : Cell.cellsMap.keySet()) {
int cellNum = Cell.cellsMap.get(cellPosition).sum;
switch (cellNum) {
case 2:g.setColor(Color.PINK);break;
case 4:g.setColor(Color.BLUE);break;
case 8:g.setColor(Color.RED);break;
case 16:g.setColor(Color.GRAY);break;
case 32:g.setColor(Color.YELLOW);break;
case 64:g.setColor(Color.ORANGE);break;
default:g.setColor(Color.CYAN);break;}
g.fillRoundRect((Cell.PosToCol(cellPosition)-1)*125, (Cell.PosToRow(cellPosition)-1)*125, 122, 122, 25, 25);
g.setColor(Color.BLACK);
g.setFont(new Font("score",Font.BOLD, 50));
g.drawString(cellNum+"", (Cell.PosToCol(cellPosition)-1)*125+45-16*(int)Math.log10(cellNum),
(Cell.PosToRow(cellPosition)-1)*125+80);
}
}
}
static class DirListener extends KeyAdapter{
@Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
if (pressDir==0) {
pressDir = 1;
}break;
case KeyEvent.VK_DOWN:
if (pressDir==0) {
pressDir = 2;
}
break;
case KeyEvent.VK_LEFT:
if (pressDir==0) {
pressDir = 3;
}break;
case KeyEvent.VK_RIGHT:
if (pressDir==0) {
pressDir = 4;
}break;
default:break;
}
}
}
}
##方块类——Cell
package yy.game2048;
import java.util.Arrays;
import java.util.HashMap;
public class Cell {
int sum;
int row;
int col;
static final int MAXROW = 4;
static final int MAXCOL = 4;
static HashMap<Integer, Cell> cellsMap;
static HashMap<Integer, Boolean> cellMap;
static{
cellsMap = new HashMap<>();
cellMap = new HashMap<>();
for (int i = 1; i <=MAXCOL*MAXROW; i++) {
cellMap.put(i, true);
}
}
public Cell(int dir) {
int sum = (int) (Math.random()*4)==3?4:2;
switch (dir) {
case 1:
int beginCol1 = (int)(Math.random()*4)+13;
while (!cellMap.get(beginCol1)) {
beginCol1 = (int)(Math.random()*4)+13;}
this.row = 4;this.col = beginCol1-12;this.sum = sum;
break;
case 2:
int beginCol2 = (int)(Math.random()*4)+1;
while (!cellMap.get(beginCol2)) {
beginCol2 = (int)(Math.random()*4)+1;}
this.row = 1;this.col = beginCol2;this.sum = sum;
break;
case 3:
int beginCol3 = ((int)(Math.random()*4)+1)*4;
while (!cellMap.get(beginCol3)) {
beginCol3 = ((int)(Math.random()*4)+1)*4;}
this.row = 1;this.col = beginCol3;this.sum = sum;
break;
case 4:
int beginCol4 = ((int)(Math.random()*4))*4+1;
while (!cellMap.get(beginCol4)) {
beginCol4 = ((int)(Math.random()*4))*4+1;}
this.row = 1;this.col = beginCol4;this.sum = sum;
break;
default:GUI.pressDir = 0;break;
}
}
public Cell(int position,int sum) {
int ifStartOrEnd = position%MAXCOL==0?0:1;
this.row = position/MAXCOL + ifStartOrEnd;
this.col = position%MAXCOL + (1-ifStartOrEnd)*4;
this.sum = sum;
}
public static void move(int pressDir) {
switch (pressDir) {
case 1:moveToHead();break;
case 2:moveToEnd();break;
case 3:moveToLeft();break;
case 4:moveToRight();break;
default:break;
}
}
private static void moveToRight() {
int[] clearYet = {0,0,0,0};
Integer[] cellKey = new Integer[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int cellKeyIndex = 0;
for (int i : Cell.cellsMap.keySet()) {
cellKey[cellKeyIndex++] = i;
}
for (int i = 0; i < 15; i++) {
for (int j = i+1; j < 16; j++) {
if (Cell.helpSort2(cellKey[j],cellKey[i])) {
int temp=cellKey[j]; cellKey[j]=cellKey[i]; cellKey[i]=temp;
}
}
}
for (int i=0;i<16&&cellKey[i]>0;i++) {
Cell.cellMap.put(cellKey[i], true);
int cellSum = Cell.cellsMap.get(cellKey[i]).sum;
Cell.cellsMap.remove(cellKey[i]);
while(Cell.PosToCol(cellKey[i])<4 && Cell.cellMap.get(cellKey[i]+1)){
cellKey[i]=cellKey[i]+1;
}
if(Cell.PosToCol(cellKey[i])<4 && !Cell.cellMap.get(cellKey[i]+1) && clearYet[Cell.PosToCol(cellKey[i])-1]==0){
if (cellSum==Cell.cellsMap.get(cellKey[i]+1).sum) {
cellSum = cellSum*2;
cellKey[i]=cellKey[i]+1;
clearYet[Cell.PosToCol(cellKey[i])-1]=1;
}
}
Cell.cellMap.put(cellKey[i], false);
Cell.cellsMap.put(cellKey[i], new Cell(cellKey[i],cellSum));
}
}
private static void moveToLeft() {
int[] clearYet = {0,0,0,0};
Integer[] cellKey = new Integer[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int cellKeyIndex = 0;
for (int i : Cell.cellsMap.keySet()) {
cellKey[cellKeyIndex++] = i;
}
for (int i = 0; i < 15; i++) {
for (int j = i+1; j < 16; j++) {
if (Cell.helpSort(cellKey[j],cellKey[i])) {
int temp=cellKey[j]; cellKey[j]=cellKey[i]; cellKey[i]=temp;
}
}
}
for (int i=0;i<16&&cellKey[i]>0;i++) {
Cell.cellMap.put(cellKey[i], true);
int cellSum = Cell.cellsMap.get(cellKey[i]).sum;
Cell.cellsMap.remove(cellKey[i]);
while(Cell.PosToCol(cellKey[i])>1 && Cell.cellMap.get(cellKey[i]-1)){
cellKey[i]=cellKey[i]-1;
}
if(Cell.PosToCol(cellKey[i])>1 && !Cell.cellMap.get(cellKey[i]-1) && clearYet[Cell.PosToCol(cellKey[i])-1]==0){
if (cellSum==Cell.cellsMap.get(cellKey[i]-1).sum) {
cellSum = cellSum*2;
cellKey[i]=cellKey[i]-1;
clearYet[Cell.PosToCol(cellKey[i])-1]=1;
}
}
Cell.cellMap.put(cellKey[i], false);
Cell.cellsMap.put(cellKey[i], new Cell(cellKey[i],cellSum));
}
}
private static void moveToHead() {
int[] clearYet = {0,0,0,0};
Integer[] cellKey = new Integer[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int cellKeyIndex = 0;
for (int i : Cell.cellsMap.keySet()) {
cellKey[cellKeyIndex++] = i;
}
Arrays.sort(cellKey);
for (int i=0;i<cellKey.length;i++) {
if(cellKey[i]==0) continue;
Cell.cellMap.put(cellKey[i], true);
int cellSum = Cell.cellsMap.get(cellKey[i]).sum;
Cell.cellsMap.remove(cellKey[i]);
while(cellKey[i]>MAXCOL && Cell.cellMap.get(cellKey[i]-MAXCOL)){
cellKey[i]=cellKey[i]-MAXCOL;
}
if(cellKey[i]>MAXCOL && !Cell.cellMap.get(cellKey[i]-MAXCOL) && clearYet[cellKey[i]%MAXCOL]==0){
if (cellSum==Cell.cellsMap.get(cellKey[i]-MAXCOL).sum) {
cellSum = cellSum*2;
cellKey[i]=cellKey[i]-MAXCOL;
clearYet[cellKey[i]%MAXCOL]=1;
}
}
Cell.cellMap.put(cellKey[i], false);
Cell.cellsMap.put(cellKey[i], new Cell(cellKey[i],cellSum));
}
}
private static void moveToEnd() {
int[] clearYet = {0,0,0,0};
Integer[] cellKey = new Integer[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int cellKeyIndex = 0;
for (int i : Cell.cellsMap.keySet()) {
cellKey[cellKeyIndex++] = i;
}
Arrays.sort(cellKey);
for (int i=cellKey.length-1;i>=0&&cellKey[i]>0;i--) {
Cell.cellMap.put(cellKey[i], true);
int cellSum = Cell.cellsMap.get(cellKey[i]).sum;
Cell.cellsMap.remove(cellKey[i]);
while(cellKey[i]<13 && Cell.cellMap.get(cellKey[i]+MAXCOL)){
cellKey[i]=cellKey[i]+MAXCOL;
}
if(cellKey[i]<13 && !Cell.cellMap.get(cellKey[i]+MAXCOL) && clearYet[cellKey[i]%MAXCOL]==0){
if (cellSum==Cell.cellsMap.get(cellKey[i]+MAXCOL).sum) {
cellSum = cellSum*2;
cellKey[i]=cellKey[i]+MAXCOL;
clearYet[cellKey[i]%MAXCOL]=1;
}
}
Cell.cellMap.put(cellKey[i], false);
Cell.cellsMap.put(cellKey[i], new Cell(cellKey[i],cellSum));
}
}
public static boolean ifGameOver() {
if (cellsMap.size()==16) {
for (int i = 1; i <= 16; i++) {
if(i<=12 && Cell.cellsMap.get(i).sum==Cell.cellsMap.get(i+MAXCOL).sum) return false;
if(i%4!=0 && Cell.cellsMap.get(i).sum==Cell.cellsMap.get(i+1).sum) return false;
}
return true;
}
return false;
}
public int getCellKey() {
return (this.row-1)*MAXCOL + this.col;
}
public static int PosToRow(int pos) {
return pos%MAXCOL==0?pos/MAXCOL:pos/MAXCOL+1;
}
public static int PosToCol(int pos) {
return pos%MAXCOL==0?4:pos%MAXCOL;
}
public static boolean helpSort(int value1,int value2) {
if(value2==0) return true;
return (value1%4==0?0:4-value1%4)>(value2%4==0?0:4-value2%4);
}
public static boolean helpSort2(int value1,int value2) {
if(value2==0) return true;
if(value1==0) return false;
return (value1%4==0?4:value1%4)>(value2%4==0?4:value2%4);
}
public static int scores() {
int score = 0;
for (int i = 1; i <= 16; i++) {
score = score + cellsMap.get(i).sum;
}
return score;
}
}