从蓝杰做完总结,突然感觉生活平静了下来,但是要是学完了不去运用,慢慢地就全会忘记,所以大家在家也要加油哦!
上面这都是题外话,今天我们来做的是最近网上很火的手机游戏——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就完成了!声音和图片我都在附件中给出,大家自己动手做一做吧~
相关推荐
【标题】"手工完成java项目(一)——J2SE项目"揭示了这个压缩包文件是关于使用Java标准版(J2SE)进行项目开发的教程。在Java领域,J2SE代表Java 2 Platform, Standard Edition,它是Java平台的核心,主要用于桌面...
该项目名为"myproject03.zip",是一个使用Java编程语言构建的文本界面应用程序,主要用于模拟开发团队的调度管理。这个项目并不涉及任何数据库操作,也不是一个手机应用(APP),其核心交互是通过命令行(控制台)...
我的项目代码。 自用,有密码。就不告诉你
【标题】"myProject"是一个综合性的项目,很可能包含了各种IT技术的应用,这可能是个人或团队进行软件开发、数据分析或网站构建等任务的工作空间。在深入探讨这个项目的具体知识点之前,我们首先要理解一个项目通常...
这个系统由Java编程语言实现,展示了Java在开发此类业务应用中的强大能力。Java以其跨平台兼容性、面向对象特性以及丰富的类库,成为了开发此类管理系统的首选语言。 在本项目中,"myproject02.rar"是一个压缩包...
java根据路径直接读取excel/csv文件,并遍历获取sheet中的所有信息,通过数据处理后重新生成新的文件。是个十分快捷方便的工具类。(当年不想手工做重复的生成处理数据时候,写个懒人必备的程序一键帮你解决)
【标题】"MyProject"是一个综合性的项目,可能包含了各种编程元素和工具的使用,旨在提供一个学习和实践的平台。从"源码"和"工具"这两个标签来看,我们可以推测这个项目涉及到软件开发的各个环节,包括代码编写、...
【标题】"Myproject003_java_"是一个与Java编程相关的项目,可能是一个小型的实践应用,用于展示和学习Java编程的基本概念和技术。这个项目强调了"分层"设计原则,这是软件工程中一个重要的架构模式,特别是在大型...
【MyProject6】是一个使用Kotlin编程语言构建的Android应用项目,它采用了现代移动开发的最佳实践,如Model-View-Presenter (MVP) 设计模式、依赖注入框架Dagger、反应式编程库RxJava以及网络请求库Retrofit和OkHttp...
本项目"MyProject.zip"提供了一个纯JavaScript实现的地址级联查询功能,无需数据库支持,也不依赖后端接口,可以直接在您的项目中使用。下面将详细解析这一实现过程。 地址级联查询通常指的是根据用户输入的省份...
【标题】"MyProject3" 是一个基于Android平台的开发项目,它采用了当前业界流行的MVP(Model-View-Presenter)架构模式,并结合了Dagger依赖注入库、RxJava响应式编程库、Retrofit网络请求库以及OkHttp网络访问库。...
开发者可以在这个目录下找到AndroidManifest.xml(应用配置文件)、java目录(存放Java代码)、res目录(资源文件)以及其他必要的文件和子目录,它们共同构成了一个完整的Android应用。 总结起来,"MyProject1"是...
【标题】"MyProject5"是一个综合性的Kotlin项目,采用了现代Android开发中的多个核心技术,如Model-View-Presenter(MVP)架构模式、Dagger依赖注入框架、RxJava响应式编程、Retrofit网络请求库以及OkHttp网络访问库...
此外,还能了解到如何组织和管理多模块的Java项目,这对于提升你的软件工程实践能力非常有帮助。在实践中,可以逐步熟悉这些框架的高级特性,并根据需求进行定制和优化,为你的职业发展打下坚实基础。
下面我们将深入探讨这个压缩包中的三个主要文件夹——Source、Config和Content,以及它们在UE4项目中的作用。 1. **Source** 文件夹: Source 文件夹是存放游戏源代码的地方。在这个项目中,你将找到用C++编写的源...
【标题】"MyProject8"是一个综合性的Android应用开发项目,使用了Kotlin语言,并结合了多种流行的技术框架,如MVP(Model-View-Presenter)设计模式、Dagger依赖注入库、RxJava响应式编程、Retrofit网络请求库、...
《CocosCreator学习资源——"MyProject2"详解》 CocosCreator,作为一个强大的2D游戏开发引擎,深受开发者喜爱,尤其对于初学者而言,它提供了直观易用的图形化编辑器,使得游戏开发变得更加简单。本文将围绕名为...
【标题】"myprojectmyproject" 提示我们可能在讨论一个名为 "myproject" 的软件开发项目。在IT行业中,项目通常指的是一个有特定目标、时间表和资源限制的计划,尤其是在软件工程领域,它代表着一系列任务和技术实现...