整体框架
文件的大体
分步实现
首先需要一个程序启动的入口
我这里命名的是FishGame.java
这里面主要功能就是创建一个窗体,然后将需要的鱼类,网类,鱼池类加入其中
final JFrame wel = new JFrame("欢迎界面");final WelcomePanel welcome = new WelcomePanel();wel.setSize(800, 480);wel.setLocationRelativeTo(null);wel.setResizable(false);wel.setUndecorated(true);wel.add(welcome);wel.setVisible(true);wel.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
以上是其中内容的一部分,完成在JFrame窗体中加入JPanel的欢迎面板。下面还有后续的加入鱼池等操作。
WelcomePanel.java类的作用
首先这个类继承了JPanel类,实现面板的基础功能,然后将这个面板加入JFrame窗体中。这里还有一个就是动态实现倒计时的功能。
public class WelcomePanel extends JPanel {BufferedImage image;int i = 4;public WelcomePanel(){try {image = ImageIO.read(new File("imgs/welcome.png"));} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public void paint(Graphics g){i--;g.drawImage(image, 0, 0, null);Font font = new Font("宋体", Font.BOLD, 24);g.setFont(font);g.setColor(Color.YELLOW);g.drawString(i + "秒后,游戏开始", 350, 50);}
}
Fish.java
这里个是整个项目中最复杂的一个部分,这里的的每一条鱼都是一个线程,然后使用多线程技术完成鱼类的动态游动效果,鱼类的游动效果就是实现图片的快速加载,重画。
public Fish(String name) {try {for (int i = 0; i < imgs.length; i++) {imgs[i] = ImageIO.read(new File(name + "_0" + i + ".png"));}currentImg = imgs[0];width = currentImg.getWidth();height = currentImg.getHeight();index = 0;x = rand.nextInt(800 - width);y = rand.nextInt(480 - height);speed = rand.nextInt(10) + 2;} catch (IOException e) {e.printStackTrace();}}
以上是实现鱼类的构造方法,可以看到,就是完成多张图片的存储,其实化鱼类的位置和当前鱼类图片的大小。具体内容,见文末链接。
Pool.java
这个类的主要作用就是实现鱼类的加载,鱼类线程的启动,面板的重新绘制。
public Pool() {//注册事件监听器//第一个this表示为pool添加事件监听器//第二个表示监听的对象为pool本身this.addMouseListener(this);this.addMouseMotionListener(this);try {bg = ImageIO.read(new File("imgs/bg.jpg"));}catch(IOException e) {e.printStackTrace();}power = 20;for(int i=0; i<9; i++) {fishes[i] = new Fish("imgs/fish0" + (i+1));fishes[i+11] = new Fish("imgs/fish0" + (i+1));}fishes[9] = new Fish("imgs/fish13");fishes[20] = new Fish("imgs/fish13");fishes[10] = new Fish("imgs/fish14");fishes[21] = new Fish("imgs/fish14");
// for(int i=9; i<11; i++) {
// fishes[i] = new Fish(i+4);
// fishes[i+11] = new Fish(i+4);
// }
// fish = new Fish(13);}public void paint(Graphics g) {super.paint(g);g.drawImage(bg, 0, 0, null);
// g.drawImage(fish.currentImg, fish.x, fish.y, null);for(int i=0; i<fishes.length; i++) {g.drawImage(fishes[i].currentImg, fishes[i].x, fishes[i].y, null);}if(net.show) {if(flag){g.drawImage(net.netImage, net.x - net.width/2, net.y - net.height/2, null);}else{g.drawImage(net.netImage, net.x - net.width/2/2, net.y - net.height/2/2, 80, 80, null);}}//绘制分数
// Font font = new Font("宋体", Font.BOLD, 24);
// g.setFont(font);
// g.setColor(Color.WHITE);
// g.drawString("分数: " + score, 350, 50);g.setColor(Color.YELLOW);Font font = new Font("宋体", Font.BOLD, 25);g.setFont(font);if(flag){g.drawString("当前网的状态:大网 ",0, 30);}else{g.drawString("当前网的状态:小网",0, 30);}g.setColor(Color.RED);g.drawString("当前体力值为:"+power, 400, 30);Font font1 = new Font("宋体", Font.BOLD, 15);g.setFont(font1);g.drawString("右击改变渔网大小", 0, 50);g.drawString("当前的条数为:"+fishCatched, 0, 70);g.drawString("得分为:" + score, 0, 90);}
这里只列举了其中主要实现的构造方法,和paint()方法的内容,具体内容见文末链接。
Net.java
这个模块应该是整个项目中比较简单的模块,完成网类的加载显示。其中最重要的一点就是捕鱼算法,这里算法的核心就是根据鱼类图片中心和网类图片中心点的距离与网图片宽度做对比来完成是抓到鱼的判断。
public boolean catched(Fish f, boolean flag) {boolean result;int dx = Math.abs(this.x - f.x - f.width/2);int dy = Math.abs(this.y - f.y - f.height/2);int distance = (int)Math.sqrt(dx*dx + dy*dy);if(flag){result = distance < this.width/2 ? true : false;}else {result = distance < this.width/2/2 ? true : false;}return result;}
最后放上最后效果的照片
源码下载地址