Netjava Myproject 能力源自模仿——POPSTAR

从蓝杰做完总结,突然感觉生活平静了下来,但是要是学完了不去运用,慢慢地就全会忘记,所以大家在家也要加油哦!

上面这都是题外话,今天我们来做的是最近网上很火的手机游戏——POPSTAR。


Netjava Myproject 能力源自模仿——POPSTAR
 
Netjava Myproject 能力源自模仿——POPSTAR
 
Netjava Myproject 能力源自模仿——POPSTAR
 

游戏规则自然不用多说,只需点击两个或两个以上颜色相同的方块即可消除,没有时间限制。每次消除的砖块越多,所得到的分也越多。到最后如果剩下10个以下的砖块,还会有额外加分。

 

下面我们开始写程序:

首先我们建立一个常量接口来存储信息:

/**
 * 常量接口
 * @author Administrator
 *
 */
public interface Config {
	int SIZE = 30;// 砖块大小
	int X = 10;// 砖块横向的个数
	int Y = 10;// 砖块纵向的个数
	int[][] array = new int[X][Y];// 砖块数组
	// 红1 -1
	// 黄2 -2
	// 蓝3 -3
	// 绿4 -4
	// 桃5 -5
	// 无0
	JLabel[][] jparray = new JLabel[X][Y];// 面板数组
	JTextField jtfscore = new JTextField("0", 5);//分数文本框
	JTextField jtmax = new JTextField("0", 5);//最高分文本框
}

 

 

然后我们建立主窗体:

/**
 * 主界面
 * 
 * @author Administrator
 * 
 */
public class MainFrame extends JPanel implements Config {
	private Random r = new Random();// 实例化随机数对象
	private GameRule gr = new GameRule();// 实例化游戏规则对象

	public static void main(String[] args) {
		MainFrame mf = new MainFrame();
		mf.initGUI();
	}

	/**
	 * 实例化窗体
	 */
	public void initGUI() {
		final JFrame jf = new JFrame("POPSTAR");// 创建一个窗体
		jf.setSize(new Dimension(400, 400));// 设置窗体大小
		jf.setResizable(false);// 设置窗体不可调节
		jf.setLocationRelativeTo(null);// 设置窗体位置居中
		jf.setDefaultCloseOperation(3);// 设置窗体关闭按钮
		jf.setIconImage(new ImageIcon("assets/icon36.png").getImage());// 设置窗体的图标
		this.setLayout(null);// 设置面板布局为空
		BrickListener bl = new BrickListener(this);// 实例化监听器
		// 循环给面板添加标签
		for (int i = 0; i < X; i++) {
			for (int j = 0; j < Y; j++) {
				jparray[i][j] = new JLabel() // 给标签设置重绘方法
				{
					public void paint(Graphics g) {
						super.paint(g);
						drawbricks(g);// 画砖块的方法
					}
				};
				jparray[i][j].setBounds(i * SIZE, 72 + j * SIZE, SIZE, SIZE);// 给标签设置绝对位置
				jparray[i][j].setOpaque(true);// 设置标签透明
				jparray[i][j].addMouseListener(bl);// 给标签添加鼠标监听器
				this.add(jparray[i][j]);// 将标签添加到面板上
			}
		}
		this.setBackground(Color.black);// 设置面板背景为黑色
		jf.add(this, BorderLayout.CENTER);// 将面板添加到窗体中部
		JPanel jpeast = new JPanel();// 创建东边面板
		jpeast.setLayout(new FlowLayout(FlowLayout.CENTER, 50, 20));// 设置布局为流式布局
		jpeast.setBackground(Color.black);// 设置背景为黑色
		jpeast.setPreferredSize(new Dimension(94, 0));// 设置东部面板的大小
		JButton jbustart = new JButton("开始");// 实例化开始按钮
		// 给西部面板添加监听器
		jbustart.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				jtfscore.setText("0");// 初始化分数
				for (int i = 0; i < X; i++) {
					for (int j = 0; j < Y; j++) {
						array[i][j] = r.nextInt(4) + 1;// 随机给标签添加颜色
					}
					jf.repaint();// 重回面板
				}
			}
		});
		JLabel jlscore = new JLabel("当前分数");// 实例化分数标签
		jlscore.setFont(new Font("微软雅黑", Font.BOLD, 12));// 设置标签字体
		jlscore.setForeground(Color.white);// 设置字体颜色
		JLabel jlmax = new JLabel("最高分");// 实例化最高分标签
		jlmax.setFont(new Font("微软雅黑", Font.BOLD, 12));// 设置字体属性
		jlmax.setForeground(Color.white);// 设置字体颜色
		jtfscore.setEditable(false);// 设置分数标签不可编辑
		jtfscore.setHorizontalAlignment(JTextField.CENTER);// 设置水平居中
		jtfscore.setOpaque(false);// 设置透明
		jtfscore.setBorder(null);// 设置无边框
		jtfscore.setForeground(Color.white);// 设置字体为白色
		jtfscore.setFont(new Font("微软雅黑", Font.BOLD, 12));// 设置字体属性
		jtmax.setEditable(false);// 设置分数标签不可编辑
		jtmax.setOpaque(false);// 设置透明
		jtmax.setBorder(null);// 设置无边框
		jtmax.setHorizontalAlignment(JTextField.CENTER);// 设置水平居中
		jtmax.setText(gr.getmaxscore() + "");// 设置内容
		jtmax.setFont(new Font("微软雅黑", Font.BOLD, 12));// 设置字体属性
		jtmax.setForeground(Color.white);// 设置字体为白色

		// 将组件加到容器上
		jpeast.add(jbustart);
		jpeast.add(jlscore);
		jpeast.add(jtfscore);
		jpeast.add(jlmax);
		jpeast.add(jtmax);
		jf.add(jpeast, BorderLayout.EAST);// 将东部面板添加到窗体上
		jf.setVisible(true);// 设置窗体可见

	}

	/**
	 * 画砖块的方法
	 * 
	 * @param g
	 */
	private void drawbricks(Graphics g) {
		for (int i = 0; i < X; i++) {
			for (int j = 0; j < Y; j++) {
				if (array[i][j] != 0) {
					jparray[i][j].setIcon(new ImageIcon("image/" + array[i][j]
							+ ".png"));
				} else if (array[i][j] == 0) {
					jparray[i][j].setIcon(null);
					jparray[i][j].setBackground(Color.black);
				}
			}
		}
	}
}

 

 

下面我们给星星面板添加监听器:

/**
 * 星星面板监听器
 * 
 * @author Administrator
 * 
 */
public class BrickListener extends MouseAdapter implements Config {

	private GameRule gr = new GameRule();// 实例化游戏规则对象
	private MainFrame mf;// 声明窗体对象
	private AudioClip audio;// 生命声音对象

	/**
	 * 构造方法
	 * 
	 * @param mf主面板
	 */
	public BrickListener(MainFrame mf) {
		this.mf = mf;
	}

	/**
	 * 鼠标按下监听器
	 */
	public void mousePressed(MouseEvent e) {
		JLabel jl = (JLabel) e.getSource();// 实例化标签
		int x0 = jl.getBounds().x / SIZE;// 得到标签的x坐标
		int y0 = (jl.getBounds().y - 72) / SIZE;// 得到标签的y坐标
		if (array[x0][y0] < 0) // 如果已经被选中
		{
			int score = (int) (5 * Math.pow(gr.getscore(x0, y0), 2));// 得到此方块的分数
			gr.clean();// 将方块清除并落下
			mf.repaint();// 重回面板
			// 播放方块破裂的声音
			try {
				audio = Applet.newAudioClip(new File("assets/broken.wav")
						.toURL());
				audio.play();
			} catch (MalformedURLException e1) {
				e1.printStackTrace();
			}
			jtfscore.setText(Integer.parseInt(jtfscore.getText()) + score + "");// 记录分数文本框
			if (Integer.parseInt(jtfscore.getText()) > Integer.parseInt(jtmax
					.getText())) // 如果此时分数大于最高分
			{
				gr.savamaxscore();// 保存最高分到文件
				jtmax.setText(Integer.parseInt(jtfscore.getText()) + "");// 设置当前分数到最高分
			}
			if (gr.judge()) // 如果游戏结束
			{
				jtfscore.setText(Integer.parseInt(jtfscore.getText())
						+ gr.getresidue() + "");// 添加附加分数
				if (Integer.parseInt(jtfscore.getText()) > Integer
						.parseInt(jtmax.getText())) // 如果此时分数大于最高分
				{
					gr.savamaxscore();// 保存最高分到文件
					jtmax.setText(Integer.parseInt(jtfscore.getText()) + "");// 设置最高分
				}
				// 播放游戏结束声音
				try {
					audio = Applet.newAudioClip(new File("assets/win.wav")
							.toURL());
					audio.play();
				} catch (MalformedURLException e1) {
					e1.printStackTrace();
				}
				JOptionPane.showMessageDialog(null, "游戏结束!");// 弹出游戏结束对话框
			}
		} else if (array[x0][y0] > 0)// 如果该标签没有被选中
		{
			gr.returnback();// 重置被选中的标签
			// 播放选择声音
			try {
				audio = Applet.newAudioClip(new File("assets/select.wav")
						.toURL());
				audio.play();
			} catch (MalformedURLException e1) {
				e1.printStackTrace();
			}
			// 如果该标签只连接一个
			if (gr.find(array[x0][y0], x0, y0) == 1) {
				gr.returnback();// 重置被选中标签
			}
		}
	}
}

 

 

最后,也是最重要的一步,就是建立游戏规则,我们建立游戏规则类:

 

/**
 * 记录游戏规则
 * @author Administrator
 *
 */
public class GameRule implements Config {

	/**
	 * 自动掉落
	 */
	public void drop() {
		for (int i = 0; i < X; i++) {
			for (int j = 1; j < Y; j++) {
				// 如果上一行有空格
				if (array[i][j] == 0) {
					// 把那一列向下移空格数
					for (int k = j; k > 0; k--) {
						array[i][k] = array[i][k - 1];
					}
					array[i][0] = 0;
				}
			}
		}
		turnleft();
	}

	/**
	 * 右边的自动左移
	 */
	public void turnleft() {
		for (int i = 0; i < X - 1; i++) {
			if (sumline(i) == 0) {
				int line = 1;
				for (int k = i + 1; k < X; k++) {
					if (sumline(k) == 0) {
						line++;
					} else {
						break;
					}
				}
				for (int k = i; k < X - line; k++) {
					for (int j = 0; j < Y; j++) {
						array[k][j] = array[k + line][j];
					}
				}
				for (int j = 0; j < Y; j++) {
					array[X - 1][j] = 0;
				}
			}
		}
	}

	/**
	 * 求第i列的和
	 * 
	 * @param i列数
	 * @return
	 */
	public int sumline(int i) {
		int sum = 0;
		for (int j = 0; j < Y; j++) {
			sum += array[i][j];
		}
		return sum;
	}

	/**
	 * 得到这个砖块的个数
	 * 
	 * @param x
	 * @param y
	 * @return
	 */
	public int getscore(int x, int y) {
		int count = 0;
		for (int i = 0; i < X; i++) {
			for (int j = 0; j < Y; j++) {
				if (array[i][j] < 0) {
					count++;
				}
			}
		}
		return count;
	}

	/**
	 * 根据颜色将砖块及周围的都变成相反数
	 * 
	 * @param color
	 * @param x
	 * @param y
	 * @return
	 */
	public int find(int color, int x, int y) {
		int count = 0;
		if (array[x][y] == color) {
			count++;
			array[x][y] = -array[x][y];
		} else {
			return 0;
		}
		if (x >= 1) {
			count += find(color, x - 1, y);
		}
		if (x < X - 1) {
			count += find(color, x + 1, y);
		}
		if (y >= 1) {
			count += find(color, x, y - 1);
		}
		if (y < Y - 1) {
			count += find(color, x, y + 1);
		}
		return count;
	}

	/**
	 * 判断输赢
	 * 
	 * @return
	 */
	public boolean judge() {
		for (int i = 0; i < X; i++) {
			for (int j = 0; j < Y; j++) {
				if (array[i][j] != 0) {
					if (i >= 1) {
						if (array[i - 1][j] == array[i][j]) {
							return false;
						}
					}
					if (j >= 1) {
						if (array[i][j - 1] == array[i][j]) {
							return false;
						}
					}
					if (i < X - 1) {
						if (array[i + 1][j] == array[i][j]) {
							return false;
						}
					}
					if (j < Y - 1) {
						if (array[i][j + 1] == array[i][j]) {
							return false;
						}
					}
				}
			}
		}
		return true;
	}

	/**
	 * 保存最高分到文件
	 * 
	 * @throws Exception
	 */
	public void savamaxscore() {
		try {
			File file = new File("src/bricks/save");
			if (!file.exists()) {
				file.createNewFile();
			}
			OutputStream os = new FileOutputStream(file);
			DataOutputStream dos = new DataOutputStream(os);
			dos.writeInt(Integer.parseInt(jtfscore.getText()));
			dos.flush();
			os.close();
		} catch (Exception e) {
		}
	}

	/**
	 * 从文件中读取最高分
	 * 
	 * @return 最高分
	 * @throws Exception
	 */
	public int getmaxscore() {
		try {
			File file = new File("src/bricks/save");
			if (!file.exists()) {
				file.createNewFile();
			}
			InputStream is = new FileInputStream(file);
			DataInputStream dis = new DataInputStream(is);
			int score = dis.readInt();
			jtmax.setText(score + "");
			dis.close();
			is.close();
			return score;
		} catch (Exception e) {
		}
		return 0;
	}

	/**
	 * 将选中的砖块清除
	 */
	public void clean() {
		for (int i = 0; i < X; i++) {
			for (int j = 0; j < Y; j++) {
				if (array[i][j] < 0) {
					array[i][j] = 0;
				}
			}
		}
		drop();
	}

	/**
	 * 将选中的砖块还原
	 */
	public void returnback() {
		for (int i = 0; i < X; i++) {
			for (int j = 0; j < Y; j++) {
				if (array[i][j] < 0) {
					array[i][j] = -array[i][j];
				}
			}
		}
	}

	/**
	 * 得到最后要加的分数
	 * 
	 * @return 最后要加的分数
	 */
	public int getresidue() {
		int count = 0;
		for (int i = 0; i < X; i++) {
			for (int j = 0; j < Y; j++) {
				if (array[i][j] > 0) {
					count++;
				}
			}
		}
		int a[] = { 2000, 1980, 1920, 1820, 1680, 1500, 1280, 1020, 720, 380 };
		if (count < 10) {
			return a[count];
		}
		return 0;
	}
}

 

这样,我们做的简单的POPSTAR就完成了!声音和图片我都在附件中给出,大家自己动手做一做吧~

你可能感兴趣的:(project)