`
felixour
  • 浏览: 32892 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

Netjava Myproject 能力源自模仿——POPSTAR

 
阅读更多

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

上面这都是题外话,今天我们来做的是最近网上很火的手机游戏——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就完成了!声音和图片我都在附件中给出,大家自己动手做一做吧~

  • 大小: 94.6 KB
  • 大小: 46.6 KB
  • 大小: 35.8 KB
3
6
分享到:
评论

相关推荐

    手工完成java项目(一)——J2SE项目

    【标题】"手工完成java项目(一)——J2SE项目"揭示了这个压缩包文件是关于使用Java标准版(J2SE)进行项目开发的教程。在Java领域,J2SE代表Java 2 Platform, Standard Edition,它是Java平台的核心,主要用于桌面...

    myproject03.zip

    该项目名为"myproject03.zip",是一个使用Java编程语言构建的文本界面应用程序,主要用于模拟开发团队的调度管理。这个项目并不涉及任何数据库操作,也不是一个手机应用(APP),其核心交互是通过命令行(控制台)...

    myproject——wuliu

    我的项目代码。 自用,有密码。就不告诉你

    myProject

    【标题】"myProject"是一个综合性的项目,很可能包含了各种IT技术的应用,这可能是个人或团队进行软件开发、数据分析或网站构建等任务的工作空间。在深入探讨这个项目的具体知识点之前,我们首先要理解一个项目通常...

    myproject02.rar

    这个系统由Java编程语言实现,展示了Java在开发此类业务应用中的强大能力。Java以其跨平台兼容性、面向对象特性以及丰富的类库,成为了开发此类管理系统的首选语言。 在本项目中,"myproject02.rar"是一个压缩包...

    myProject.zip

    java根据路径直接读取excel/csv文件,并遍历获取sheet中的所有信息,通过数据处理后重新生成新的文件。是个十分快捷方便的工具类。(当年不想手工做重复的生成处理数据时候,写个懒人必备的程序一键帮你解决)

    MyProject

    【标题】"MyProject"是一个综合性的项目,可能包含了各种编程元素和工具的使用,旨在提供一个学习和实践的平台。从"源码"和"工具"这两个标签来看,我们可以推测这个项目涉及到软件开发的各个环节,包括代码编写、...

    Myproject003_java_

    【标题】"Myproject003_java_"是一个与Java编程相关的项目,可能是一个小型的实践应用,用于展示和学习Java编程的基本概念和技术。这个项目强调了"分层"设计原则,这是软件工程中一个重要的架构模式,特别是在大型...

    MyProject6

    【MyProject6】是一个使用Kotlin编程语言构建的Android应用项目,它采用了现代移动开发的最佳实践,如Model-View-Presenter (MVP) 设计模式、依赖注入框架Dagger、反应式编程库RxJava以及网络请求库Retrofit和OkHttp...

    MyProject.zip

    本项目"MyProject.zip"提供了一个纯JavaScript实现的地址级联查询功能,无需数据库支持,也不依赖后端接口,可以直接在您的项目中使用。下面将详细解析这一实现过程。 地址级联查询通常指的是根据用户输入的省份...

    MyProject3

    【标题】"MyProject3" 是一个基于Android平台的开发项目,它采用了当前业界流行的MVP(Model-View-Presenter)架构模式,并结合了Dagger依赖注入库、RxJava响应式编程库、Retrofit网络请求库以及OkHttp网络访问库。...

    MyProject1

    开发者可以在这个目录下找到AndroidManifest.xml(应用配置文件)、java目录(存放Java代码)、res目录(资源文件)以及其他必要的文件和子目录,它们共同构成了一个完整的Android应用。 总结起来,"MyProject1"是...

    MyProject5

    【标题】"MyProject5"是一个综合性的Kotlin项目,采用了现代Android开发中的多个核心技术,如Model-View-Presenter(MVP)架构模式、Dagger依赖注入框架、RxJava响应式编程、Retrofit网络请求库以及OkHttp网络访问库...

    myproject.rar

    此外,还能了解到如何组织和管理多模块的Java项目,这对于提升你的软件工程实践能力非常有帮助。在实践中,可以逐步熟悉这些框架的高级特性,并根据需求进行定制和优化,为你的职业发展打下坚实基础。

    myProject.rar

    下面我们将深入探讨这个压缩包中的三个主要文件夹——Source、Config和Content,以及它们在UE4项目中的作用。 1. **Source** 文件夹: Source 文件夹是存放游戏源代码的地方。在这个项目中,你将找到用C++编写的源...

    MyProject8

    【标题】"MyProject8"是一个综合性的Android应用开发项目,使用了Kotlin语言,并结合了多种流行的技术框架,如MVP(Model-View-Presenter)设计模式、Dagger依赖注入库、RxJava响应式编程、Retrofit网络请求库、...

    MyProject2.rar

    《CocosCreator学习资源——"MyProject2"详解》 CocosCreator,作为一个强大的2D游戏开发引擎,深受开发者喜爱,尤其对于初学者而言,它提供了直观易用的图形化编辑器,使得游戏开发变得更加简单。本文将围绕名为...

    myprojectmyproject

    【标题】"myprojectmyproject" 提示我们可能在讨论一个名为 "myproject" 的软件开发项目。在IT行业中,项目通常指的是一个有特定目标、时间表和资源限制的计划,尤其是在软件工程领域,它代表着一系列任务和技术实现...

Global site tag (gtag.js) - Google Analytics