游戏运行界面:
1. 主窗体
/**
* 2048游戏主界面
* @author zzc
*
*/
public class GamePlay extends JFrame {
URL url11 = GamePlay.class.getResource("上1.png");
URL url12 = GamePlay.class.getResource("上2.png");
URL url13 = GamePlay.class.getResource("上3.png");
URL url21 = GamePlay.class.getResource("下1.png");
URL url22 = GamePlay.class.getResource("下2.png");
URL url23 = GamePlay.class.getResource("下3.png");
URL url31 = GamePlay.class.getResource("左1.png");
URL url32 = GamePlay.class.getResource("左2.png");
URL url33 = GamePlay.class.getResource("左3.png");
URL url41 = GamePlay.class.getResource("右1.png");
URL url42 = GamePlay.class.getResource("右2.png");
URL url43 = GamePlay.class.getResource("右3.png");
public static void main(String[] args) {
GamePlay play=new GamePlay();
play.Init();
}
public void Init(){
this.setSize(590, 500);
this.setLocation(300, 160);
this.setTitle("2048");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel mypanel=new MyPanel();
mypanel.setLayout(null);
mypanel.setBackground(Color.white);
this.add(mypanel);
//方向按钮
JButton bt1=new JButton();
bt1.setBounds(480,290, 35, 35);
bt1.setBackground(Color.white);
bt1.setIcon(new ImageIcon(url11));
bt1.setRolloverIcon(new ImageIcon(url12));
bt1.setPressedIcon(new ImageIcon(url13));
bt1.setBorderPainted(false);
bt1.setActionCommand("up");
bt1.addActionListener(mypanel);
mypanel.add(bt1);
JButton bt2=new JButton();
bt2.setBounds(480,390, 35, 35);
bt2.setBackground(Color.white);
bt2.setIcon(new ImageIcon(url21));
bt2.setRolloverIcon(new ImageIcon(url22));
bt2.setPressedIcon(new ImageIcon(url23));
bt2.setBorderPainted(false);
bt2.setActionCommand("down");
bt2.addActionListener(mypanel);
mypanel.add(bt2);
JButton bt3=new JButton();
bt3.setBounds(435,340, 35, 35);
bt3.setBackground(Color.white);
bt3.setIcon(new ImageIcon(url31));
bt3.setRolloverIcon(new ImageIcon(url32));
bt3.setPressedIcon(new ImageIcon(url33));
bt3.setBorderPainted(false);
bt3.setActionCommand("left");
bt3.addActionListener(mypanel);
mypanel.add(bt3);
JButton bt4=new JButton();
bt4.setBounds(525,340, 35, 35);
bt4.setBackground(Color.white);
bt4.setIcon(new ImageIcon(url41));
bt4.setRolloverIcon(new ImageIcon(url42));
bt4.setPressedIcon(new ImageIcon(url43));
bt4.setBorderPainted(false);
bt4.setActionCommand("right");
bt4.addActionListener(mypanel);
mypanel.add(bt4);
this.setVisible(true);
}
}
2 主面板类
/**
* 自定义面板类
*
* @author zzc
*
*/
public class MyPanel extends JPanel implements ActionListener {
// 格子起始位置 每个格子的大小
int size = 100;
int X0 = 20, Y0 = 30;
// 每个格子对应的数字
int arr[][] = new int[4][4];
//总分数
int score=0;
// 随机数字类
Randompic random = new Randompic();
// 判断游戏是否结束
boolean isover = false;
//音效类
Music mu;
URL url1 = MyPanel.class.getResource("1图标.png");
URL url2 = MyPanel.class.getResource("2图标.png");
URL url4 = MyPanel.class.getResource("4图标.png");
URL url8 = MyPanel.class.getResource("8图标.png");
URL url16 = MyPanel.class.getResource("16图标.png");
URL url32 = MyPanel.class.getResource("32图标.png");
URL url64 = MyPanel.class.getResource("64图标.png");
URL url128 = MyPanel.class.getResource("128图标.png");
URL url256 = MyPanel.class.getResource("256图标.png");
URL url512 = MyPanel.class.getResource("512图标.png");
URL url1024 = MyPanel.class.getResource("1024图标.png");
URL url2048 = MyPanel.class.getResource("2048图标.png");
URL urlscore = MyPanel.class.getResource("分数图标.png");
Image image1;
Image image2;
Image image4;
Image image8;
Image image16;
Image image32;
Image image64;
Image image128;
Image imagescore;
Image image256;
Image image512;
Image image1024;
Image image2048;
public MyPanel() {
// 初始化数组
for (int i = 0; i < arr.length; i++)
for (int j = 0; j < arr[i].length; j++)
arr[i][j] = -1;
/*
* arr[2][2] = 2; arr[2][1] = 4; arr[1][3] = 8; arr[0][2] = 16;
*/
// 初始化图片
image1 = new ImageIcon(url1).getImage();
image2 = new ImageIcon(url2).getImage();
image4 = new ImageIcon(url4).getImage();
image8 = new ImageIcon(url8).getImage();
image16 = new ImageIcon(url16).getImage();
image32 = new ImageIcon(url32).getImage();
image64 = new ImageIcon(url64).getImage();
image128 = new ImageIcon(url128).getImage();
image256 = new ImageIcon(url256).getImage();
image512 = new ImageIcon(url512).getImage();
image1024 = new ImageIcon(url1024).getImage();
image2048 = new ImageIcon(url2048).getImage();
imagescore=new ImageIcon(urlscore).getImage();
random.Found(arr);
Point p = random.random();
arr[p.x][p.y] = 2;
//初始化音效类
mu=new Music("音效.mp3");
}
@Override
public void paint(Graphics g) {
super.paint(g);
//打印数字
Print(g);
//显示分数
Fontscore(g);
if (isover) {
Font font = new Font("华文行楷 ", Font.BOLD, 38);
g.setColor(Color.ORANGE);
g.setFont(font);
g.drawString("游戏结束", 170, 250);
}
}
//动作监听器
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String command = e.getActionCommand();
// 用于判断是否移动 合并
boolean b1 = true;
boolean b2 = true;
if ("up".equals(command)) {
b1 = check1(0);
b2 = HeBing(0);
} else if ("down".equals(command)) {
b1 = check1(1);
b2 = HeBing(1);
} else if ("left".equals(command)) {
b1 = check1(2);
b2 = HeBing(2);
} else if ("right".equals(command)) {
// 先全部向右移 返回的是 是否移动
b1 = check1(3);
// 然后再合并 返回的是是否合并
b2 = HeBing(3);
}
// 只要移动或合并 就要随机在-1的位置出现数字
if (b1 || b2){
//播放音效
mu.start();
// 随机数字
randompic();
}
// 重绘
repaint();
}
// 随机数字
public void randompic() {
random.Found(arr);
// 得到要随机数字的位置
Point p = random.random();
if (p.x != -1) {
arr[p.x][p.y] = random.randomInt();
} else
isover = true;
}
// 遍历数组(移动时) 若都不移动 则返回false
// 上 0 下 1 左 2 右3
public boolean check1(int direct) {
boolean b = false;
if (direct == 0 || direct == 2) {
// 向上移动或向左 从下到上 从右到左 遍历
for (int i = arr.length - 1; i >= 0; i--)
for (int j = arr[i].length - 1; j >= 0; j--) {
if (arr[i][j] == -1) {
// 当位置为空时 移动
boolean b1 = remove(i, j, direct);
// 只要有一个位置移动了 就改变b的值
if (b1)
b = b1;
}
}
} else if (direct == 1 || direct == 3) {
// 向下移动或向右移动 从上到下 从左到右遍历
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
if (arr[i][j] == -1) {
boolean b1 = remove(i, j, direct);
// 只要有一个位置移动了 就改变b的值
if (b1)
b = b1;
}
}
}
}
return b;
}
// 向指定方向移动 若不移动则返回false
public boolean remove(int a, int b, int direct) {
int count = 0;
if (direct == 0) {
// ***********************向上移动*************************
// 先检测当前位置下边是否全为空
for (int i = a; i < arr.length - 1; i++) {
if (arr[i + 1][b] == -1)
// 为空时count+1
count++;
}
// 全为-1的话 就不需要移动 返回false
if (count == 3 - a)
return false;
else {
// 向上移动
for (int i = a; i < arr.length - 1; i++) {
arr[i][b] = arr[i + 1][b];
}
arr[3][b] = -1;
return true;
}
} else if (direct == 1) {
// ******************************向下移动**********************
// 先检测当前位置上边是否全为空
for (int i = a; i > 0; i--) {
if (arr[i - 1][b] == -1)
// 为空时count+1
count++;
}
// 全为-1的话 就不需要移动 返回false
if (count == a)
return false;
else {
for (int i = a; i > 0; i--) {
arr[i][b] = arr[i - 1][b];
}
arr[0][b] = -1;
return true;
}
} else if (direct == 2) {
// ******************************向左移动***************************
// 先检测当前位置右边是否全为空
for (int i = b; i < arr.length - 1; i++) {
if (arr[a][i + 1] == -1)
// 为空时count+1
count++;
}
// 全为-1的话 就不需要移动 返回false
if (count == 3 - b)
return false;
else {
for (int i = b; i < arr.length - 1; i++) {
arr[a][i] = arr[a][i + 1];
}
arr[a][3] = -1;
return true;
}
} else {
// *****************************向右移动********************************
// 先检测当前位置左边是否全为空
for (int i = b; i > 0; i--) {
if (arr[a][i - 1] == -1)
// 为空时count+1
count++;
}
// 全为-1的话 就不需要移动 返回false
if (count == b)
return false;
else {
// 向右移动一格
for (int i = b; i > 0; i--) {
arr[a][i] = arr[a][i - 1];
}
arr[a][0] = -1;
return true;
}
}
}
// 遍历数组 (合并时) 按规律合并相同的数字 如果合并了 则返回true 否则 返回false
public boolean HeBing(int direct) {
boolean b = false;
if (direct == 0) {
// 向上合并
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length; j++) {
if (arr[i][j] != -1) {
// 当前位置数字和下边的相同时
if (arr[i][j] == arr[i + 1][j]) {
//分数增加
score+=(arr[i][j]*2);
// 当前位置数字翻倍
arr[i][j] *= 2;
// 下边的数字置空
arr[i + 1][j] = -1;
// 如果下边的位置不是最后一个的话 就右移
if (i + 1 != 3)
remove(i + 1, j, 0);
b = true;
}
}
}
}
} else if (direct == 1) {
// 向下合并
for (int i = arr.length - 1; i > 0; i--) {
for (int j = 0; j < arr[i].length; j++) {
if (arr[i][j] != -1) {
// 当前位置数字和上边的相同时
if (arr[i][j] == arr[i - 1][j]) {
//分数增加
score+=(arr[i][j]*2);
// 当前位置数字翻倍
arr[i][j] *= 2;
// 上边的数字置空
arr[i - 1][j] = -1;
// 如果下边的位置不是最后一个的话 就右移
if (i - 1 != 0)
remove(i - 1, j, 1);
b = true;
}
}
}
}
} else if (direct == 2) {
// 向左合并
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length - 1; j++) {
if (arr[i][j] != -1) {
// 当前位置数字和右边的相同时
if (arr[i][j] == arr[i][j + 1]) {
//分数增加
score+=(arr[i][j]*2);
// 当前位置数字翻倍
arr[i][j] *= 2;
// 右边的数字置空
arr[i][j + 1] = -1;
// 如果左边的位置不是最后一个的话 就右移
if (j + 1 != 3)
remove(i, j + 1, 2);
b = true;
}
}
}
}
} else if (direct == 3) {
// 向右合并
for (int i = 0; i < arr.length; i++) {
for (int j = arr[i].length - 1; j > 0; j--) {
// 当前位置不为空时
if (arr[i][j] != -1) {
// 当前位置数字和左边的相同时
if (arr[i][j] == arr[i][j - 1]) {
//分数增加
score+=(arr[i][j]*2);
// 当前位置数字翻倍
arr[i][j] *= 2;
// 左边的数字置空
arr[i][j - 1] = -1;
// 如果左边的位置不是最后一个的话 就右移
if (j - 1 != 0)
remove(i, j - 1, 3);
b = true;
}
}
}
}
}
return b;
}
//打印数组数字
public void Print(Graphics g){
// 打印数字
for (int i = 0; i < arr.length; i++)
for (int j = 0; j < arr[i].length; j++) {
if (arr[i][j] != -1) {
if (arr[i][j] == 2)
g.drawImage(image2, X0 + j * size, Y0 + i * size, size,
size, null);
else if (arr[i][j] == 4)
g.drawImage(image4, X0 + j * size, Y0 + i * size, size,
size, null);
else if (arr[i][j] == 8)
g.drawImage(image8, X0 + j * size, Y0 + i * size, size,
size, null);
else if (arr[i][j] == 16)
g.drawImage(image16, X0 + j * size, Y0 + i * size,
size, size, null);
else if (arr[i][j] == 32)
g.drawImage(image32, X0 + j * size, Y0 + i * size,
size, size, null);
else if (arr[i][j] == 64)
g.drawImage(image64, X0 + j * size, Y0 + i * size,
size, size, null);
else if (arr[i][j] == 128)
g.drawImage(image128, X0 + j * size, Y0 + i * size,
size, size, null);
else if (arr[i][j] == 256)
g.drawImage(image256, X0 + j * size, Y0 + i * size,
size, size, null);
else if (arr[i][j] == 512)
g.drawImage(image512, X0 + j * size, Y0 + i * size,
size, size, null);
else if (arr[i][j] == 1024)
g.drawImage(image1024, X0 + j * size, Y0 + i * size,
size, size, null);
else if (arr[i][j] == 2048)
g.drawImage(image2048, X0 + j * size, Y0 + i * size,
size, size, null);
} else
g.drawImage(image1, X0 + j * size, Y0 + i * size, size,
size, null);
}
}
//显示分数
public void Fontscore(Graphics g){
g.drawImage(imagescore, X0+4*size+30, 20, size,size,null);
g.setColor(Color.white);
int len;
int fontsize=35;
if(score<10)
len=70;
else if(score>=10&&score<100)
len=60;
else if(score>=100&&score<1000)
len=50;
else if(score>=1000&&score<10000){
len=45;
fontsize=30;
}else{
len=45;
fontsize=25;
}
Font font=new Font("楷体",Font.ITALIC|Font.BOLD,fontsize);
g.setFont(font);
g.drawString(Integer.toString(score), X0+4*size+len, Y0+55);
}
}
3.随机图片类
/**
* 用来随机出现图片的类
*
* @author zzc
*
*/
public class Randompic {
Random r;
ArrayList<Point> list = new ArrayList<Point>();
public Randompic() {
r = new Random();
}
// 根据传入数组 为arr添加项
public void Found(int arr[][]) {
// 先清空数组
list.removeAll(list);
for (int i = 0; i < arr.length; i++)
for (int j = 0; j < arr[i].length; j++) {
if (arr[i][j] == -1) {
Point p = new Point(i, j);
list.add(p);
}
}
}
// 随机一个坐标 返回point
public Point random() {
if (list.size() > 0) {
int n = r.nextInt(list.size());
return list.get(n);
} else
return new Point(-1, -1);
}
// 随机一个数字 2或4
public int randomInt() {
int n = r.nextInt(12);
if (n % 5 == 0)
return 4;
else
return 2;
}
}
4 音效类
/**
* 音效类
* @author zzc
*
*/
public class Music {
// 播放器 jmf提供的
Player p;
String path;
File f;
public Music(String path) {
f = new File(path);
}
public void start() {
// 1.构建一个文件
try {
// 2.创建播放器
p = Manager.createPlayer(new MediaLocator((f).toURI().toURL()));
p.prefetch();//预读文件
// 3.播放器已经准备好
//p.realize();
// 4.开始播放
p.start();
} catch (NoPlayerException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}