java项目之捕鱼达人简单实现

一、源代码

我为大家手写了捕鱼达人Java的简单实现,包含最基本的功能,界面采用Java GUI编程,使用了JFrame框架,代码如下:

package com.fishgame;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.*;
import java.awt.image.*;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * 捕鱼项目界面类
 */
public class Main {
	public static void main(String[] args) {

		JFrame frame = new JFrame("捕鱼达人"); // 创建一个窗体
		frame.setSize(800, 510); // 设置窗体的大小
		frame.setResizable(false); // 禁止窗口最大化
		frame.setLocationRelativeTo(null); // 让窗体居中
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置窗体默认关闭事件
		Pool pool = new Pool(); // 创建鱼池对象
		frame.add(pool); // 将鱼池添加到窗体上
		frame.setVisible(true); // 显示窗体
		pool.action(); // 调用鱼池的控制方法
	}
}

/**
 * 捕鱼项目的鱼池,及捕鱼控制程序
 */
class Pool extends JPanel {
	BufferedImage background; // 背景图
	Fish[] fishes; // 声明一个鱼的数组
	Net net; // 声明一个渔网
	int count; // 计数
	int score; // 计分

	/** Pool类的构造方法, 用来给背景、鱼、网进行赋值 */
	public Pool() {
		try {
			background = ImageIO.read(new File("images/bg.jpg")); // 加载背景图片
			fishes = new Fish[9 + 9 + 9 + 2]; // 创建鱼数组,长度29
			for (int i = 0; i < 9; i++) { // 创建鱼对象,并放入数组
				fishes[i] = new Fish("fish0" + (i + 1));
				fishes[i + 9] = new Fish("fish0" + (i + 1));
				fishes[i + 9 + 9] = new Fish("fish0" + (i + 1));
			}
			fishes[fishes.length - 2] = new Fish("fish13");
			fishes[fishes.length - 1] = new Fish("fish14");
			net = new Net(); // 创建渔网对象

		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/** 绘图方法,系统自动调用 */
	public void paint(Graphics g) {

		g.drawImage(background, 0, 0, null); // 绘制背景图片
		for (int i = 0; i < fishes.length; i++) { // 绘制数组中所有的鱼
			g.drawImage(fishes[i].image, fishes[i].x, fishes[i].y, null);
		}

		/** 通过渔网中心点x,y,计算渔网的位置,并将渔网绘制出来 */
		if (net.show) {
			int x = net.x - net.width / 2;
			int y = net.y - net.height / 2;
			g.drawImage(net.image, x, y, null);
		}

		/** 绘制捕鱼的数量和分数 */
		Font f = new Font("", Font.BOLD, 30);
		g.setFont(f);
		g.setColor(Color.WHITE);
		g.drawString("count:" + count, 20, 30);
		g.drawString("score:" + score, 20, 60);
	}

	/** 在Pool类中增加捕鱼方法 */
	public void catchFish() {
		for (int i = fishes.length - 1; i >= 0; i--) {
			/** 判断鱼是否被捕获 */
			if (net.catchThe(fishes[i])) {
				count++; // 计数
				if (fishes[i].width > 100) { // 计分
					score += 15;
				} else {
					score += fishes[i].width / 10;
				}
				fishes[i].catched = true; // 鱼属性catched=true;
				break; // 退出循环
			}
		}
	}

	/** 控制鱼游动的方法 */
	public void action() {
		// 鼠标事件类
		MouseAdapter ma = new MouseAdapter() {
			// 鼠标按下
			@Override
			public void mousePressed(MouseEvent e) {
				catchFish();// 在Pool中增加捕鱼方法
			}

			// 鼠标进入
			@Override
			public void mouseEntered(MouseEvent e) {
				net.show = true;
			}

			// 鼠标移出
			@Override
			public void mouseExited(MouseEvent e) {
				net.show = false;
			}

			// 鼠标移动
			@Override
			public void mouseMoved(MouseEvent e) {
				int x = e.getX();
				int y = e.getY();
				net.moveTo(x, y);
			}
		};
		
		/** 添加鼠标监听事件 */
		this.addMouseListener(ma);// 鼠标事件
		this.addMouseMotionListener(ma);// 拖动事件
		// 启动线程
		for (int i = 0; i < fishes.length; i++) {
			fishes[i].start();
		}
		while (true) {
			repaint();// 重新绘制界面
			try {
				Thread.sleep(20); // 线程休眠20ms
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

/**
 * 鱼对象类
 */
class Fish extends Thread { // 将鱼作为一个独立线程
	BufferedImage[] images; // 鱼图片的数组
	BufferedImage image; // 鱼显示的当前图片
	int width; // 鱼图片的宽度
	int height; // 鱼图片的高度
	int x; // 鱼的x坐标
	int y; // 鱼的y坐标
	int step; // 鱼游动的速度
	int index; // 鱼图片轮转
	boolean catched; // 鱼是否被捕获
	BufferedImage catch01;
	BufferedImage catch02;

	/** Fish类的构造方法,用来给属性赋值 */
	public Fish(String name) throws Exception {
		// 创建鱼图片数组
		images = new BufferedImage[10];
		// 加载每条鱼的10张图片,并放入数组
		for (int i = 0; i < 10; i++) {
			String file = "images/" + name + "_0" + i + ".png";
			images[i] = ImageIO.read(new File(file));
		}
		image = images[0]; // 将数组的第一张图片赋给当前图片
		width = image.getWidth(); // 获取当前图片的宽度
		height = image.getHeight(); // 获取当前图片的高度
		Random r = new Random();
		x = r.nextInt(800 - width); // 给鱼的x坐标赋值
		y = r.nextInt(480 - height); // 给鱼的y坐标赋值
		step = r.nextInt(5) + 1; // 初始化鱼的速度(1~5)
		index = 0; // 图片轮转的初始值为0
		catched = false;
		catch01 = ImageIO.read(new File("images/" + name + "_catch_01.png"));
		catch02 = ImageIO.read(new File("images/" + name + "_catch_02.png"));
	}

	/** 鱼游动的方法 */
	public void move() {
		index++; // 鱼游动时10张图片轮转,达到游动效果
		image = images[index % images.length];
		x -= step; // 让鱼从右向左游动
		if (x < -width) { // 当鱼游出界面,重新从右边进入
			x = 800;
			Random r = new Random();
			y = r.nextInt(480 - height);
			step = r.nextInt(5) + 1;
		}
	}

	// 线程方法,系统自动调用
	public void run() {
		while (true) {
			try {
				// 如果鱼被捕获
				if (catched) {
					turnOver(); // 1、原地翻腾
					catched = false; // 2、catched=false;
					getOut(); // 3、鱼消失
				} else {
					move(); // 否则鱼继续游动
					Thread.sleep(100);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/** 鱼原地翻腾的方法 */
	public void turnOver() {
		try {
			for (int i = 0; i < 5; i++) {
				image = catch01;
				Thread.sleep(100);
				image = catch02;
				Thread.sleep(100);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/** 鱼滚出界面 */
	public void getOut() {
		x = 800;
		Random r = new Random();
		y = r.nextInt(480 - height);
		step = r.nextInt(5) + 1;
	}
}

class Net {
	BufferedImage image; // 渔网的图片
	int width; // 渔网的宽度
	int height; // 渔网的高度
	int x; // 渔网的中心点x坐标
	int y; // 渔网的中心点y坐标
	boolean show; // 渔网是否显示

	/** Net类构造方法,用来给网的属性赋值 */
	public Net() throws Exception {
		image = ImageIO.read( // 加载网的图片
				new File("images/net09.png"));
		width = image.getWidth(); // 获取图片的宽度
		height = image.getHeight(); // 获取图片的高度
		Random r = new Random();
		x = r.nextInt(800 - width); // 设置网第一次出现时的x坐标
		y = r.nextInt(480 - height); // 设置网第一次出现时的y坐标
		show = true; // 程序一开始让渔网处于显示状态
	}

	/** 渔网移动的方法 将渔网新位置的x,y 赋值给渔网的x,y属性 */
	public void moveTo(int x, int y) {
		this.x = x; // this.x表示渔网的属性,x表示渔网的新位置x坐标
		this.y = y; // this.y表示渔网的属性,y表示渔网的新位置y坐标
	}

	/** 判断鱼是否被捕获 判断网的中心点是否在鱼图片之上 如果被捕获就返回true 否则返回false */
	public boolean catchThe(Fish fish) {
		int dx = x - fish.x;
		int dy = y - fish.y;
		return dx > 0 && dx < fish.width && dy > 0 && dy < fish.height;
	}
}


二、效果演示

1.效果图

java项目之捕鱼达人简单实现_第1张图片

2.项目代码托管

点击下载


你可能感兴趣的:(JavaSE,捕鱼达人)