自己制作的 java 版 2048游戏


游戏运行界面:





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();
		}
	}
}

猜你喜欢

转载自592713711.iteye.com/blog/2186662