效果图如下:
图片资源:
链接:https://pan.baidu.com/s/197orGk1P2UG9wi9ef4MDlw
提取码:a77d
源代码分享:
测试类:
package game;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
/**
* 测试类
* @author Lenovo
*
*/
public class Client {
public static void main(String[] args) throws IOException {
//创建窗口
JFrame gameFrame = new JFrame("捕鱼达人");
//将池塘放入到界面中去
Pool pool = new Pool();
gameFrame.setContentPane(pool);
//创建窗口图标,绝对路径
BufferedImage icon = ImageIO.read(new File("E:/New_life/fish_game/resource/images/fish07_03.png"));
gameFrame.setIconImage(icon);
//设置窗口的尺寸
gameFrame.setSize(800, 500);
//窗口的位置
gameFrame.setLocation(10, 10);
//设置窗口不可拖拽
gameFrame.setResizable(false);
//设置窗口可以关闭
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//让窗口显示
gameFrame.setVisible(true);
//调用方法
pool.action();
}
}
大炮的设置:
package game;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Cannon {
//大炮的图片
private BufferedImage image;
//坐标值
private int x;
private int y;
public Cannon() throws IOException {
this.image = ImageIO.read(new File("resource/images/barrel.png"));
this.x = 420;
this.y = 400;
}
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
与鱼塘的设置:
package game;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class Pool extends JPanel{
private static final long serialVersionUID = 1L;
/**
* 背景图片
* 海王
* 鱼
* 大炮
* 状态栏
*/
//池塘
private BufferedImage backgroud;
//单条鱼
// private Fish fish;
//多条与
private Fish[] fishes;
//状态栏
private BufferedImage statusImage;
//大炮
private Cannon cannon;
//鼠标x轴
private int mouseX;
//鼠标Y轴
private int mouseY;
//渔网
private Net net;
//子弹发射的角度
private double theta;
//子弹
private LinkedList<Bullet> bullets;
//反射原点
public Pool() throws IOException {
this.backgroud = ImageIO.read(new File("resource/images/bg.jpg"));
// this.fish = new Fish("fish08");
//设置10条鱼
this.fishes = new Fish[11];
for (int i = 0; i < 9; i++) {
String fishName = "fish0" + (i+1);
Fish fish = new Fish(fishName);
this.fishes[i] = fish;
}
this.fishes[9] = new Fish("fish13");
this.fishes[10] = new Fish("fish14");
//初始化状态栏
this.statusImage = ImageIO.read(new File("resource/images/bottom-bar.png"));
//初始化大炮
this.cannon = new Cannon();
//调用监听器
this.addListener();
//创建网
this.net = new Net();
//数组定义
this.bullets = new LinkedList<Bullet>();
}
private void addListener() {
//添加监听器
this.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
System.out.println("发射子弹!");
try {
//创建子弹
Bullet bullet = new Bullet(cannon.getX(), cannon.getY(), theta, Pool.this);
//启动线程
bullet.start();
//将对象添加到集合中去
bullets.add(bullet);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void mouseEntered(MouseEvent arg0) {
//进入,让渔网显示
net.setShow(true);
}
@Override
public void mouseExited(MouseEvent arg0) {
//退出,让渔网消失
net.setShow(false);
}
});
//鼠标移动监听
this.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
mouseX = e.getX() + 20;
mouseY = e.getY();
System.out.println("(" + mouseX+ "," +mouseY +")");
//渔网移动
net.move(mouseX, mouseY);
}
});
}
/**
* 画界面
*/
@Override
public void paint(Graphics arg0) {
super.paint(arg0);
arg0.drawImage(backgroud, 0, 0, backgroud.getWidth(), backgroud.getHeight(), null);
for (int i = 0; i < fishes.length; i++) {
Fish fish = this.fishes[i];
arg0.drawImage(fish.getImage(),
fish.getX(),
fish.getY(),
fish.getWidth(),
fish.getHeight(), null);
}
// arg0.drawImage(this.fish.getImage(), this.fish.getX(), this.fish.getY(), this.fish.getWidth(), this.fish.getHeight(), null);
//画状态栏
arg0.drawImage(statusImage,15, 400, statusImage.getWidth(), statusImage.getHeight(), null);
//画大炮
//Graphics:不能画旋转的图片,画旋转的图片需要Graphics2D,创建画笔
Graphics2D graphics2d = (Graphics2D) arg0.create();
//设置画笔的角度
//计算大炮的旋转中心
double centerX = this.cannon.getX() + this.cannon.getImage().getWidth()/2;
double centerY = this.cannon.getY() + this.cannon.getImage().getHeight()/4*3;
double xx = this.mouseX - centerX;
double yy = this.mouseY - centerY;
//求反切角度
this.theta =-Math.atan(xx/yy);
graphics2d.rotate(theta, centerX ,centerY);
graphics2d.drawImage(this.cannon.getImage(),
this.cannon.getX(),
this.cannon.getY(),
this.cannon.getImage().getWidth(),
this.cannon.getImage().getHeight(), null);
//画大炮结束
//画渔网,drawImage是参数是int类型,所以进行强制转换
if (this.net.isShow()) {
arg0.drawImage(this.net.getImage(),
(int)this.net.getX(),
(int)this.net.getY(),
(int)this.net.getImage().getWidth(),
(int)this.net.getImage().getHeight(),null);
}
//画子弹
//子弹没有发射子弹之前
for (Bullet bullet : bullets) {
Graphics2D graphics2d2 = (Graphics2D)arg0.create();
graphics2d2.rotate(bullet.getThread(), centerX, centerY);
graphics2d2.drawImage(bullet.getImage(),
bullet.getX(),
bullet.getY(),
bullet.getWidth(),
bullet.getHeight(), null);
}
}
/**
* 请开始你的表演
*/
public void action() {
//让鱼动起来
// this.fish.start();
for (Fish fish : this.fishes) {
fish.start();
}
//重新画界面,匿名内部类
new Thread() {
public void run() {
while (true) {
repaint();
}
};
}.start();
}
public LinkedList<Bullet> getBullets() {
return bullets;
}
public void setBullets(LinkedList<Bullet> bullets) {
this.bullets = bullets;
}
public Fish[] getFishes() {
return fishes;
}
public void setFishes(Fish[] fishes) {
this.fishes = fishes;
}
}
鱼类的设置:
package game;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
public class Fish extends Thread{
//宽度
@SuppressWarnings("unused")
private int width;
@SuppressWarnings("unused")
private int height;
//位置
//x坐标
@SuppressWarnings("unused")
private int x;
//y坐标
@SuppressWarnings("unused")
private int y;
//图片
@SuppressWarnings("unused")
private BufferedImage image;
//速度
@SuppressWarnings("unused")
private int step;
//是否被抓
@SuppressWarnings("unused")
private boolean isCatch;
//鱼游动的图片数组
@SuppressWarnings("unused")
private BufferedImage[] images;
//抓获鱼的图片
private BufferedImage[] catchImages;
//图片的下标
@SuppressWarnings("unused")
private int imagesIndex;
/**
*鱼的构造方法
* @param name 鱼的图片名称
* @throws IOException
*/
public Fish(String imageName) throws IOException {
//鱼游动的初始化
this.images = new BufferedImage[10];
for (int i = 0; i < 10; i++) {
String fishName = imageName + "_0" + i + ".png";
BufferedImage tempImage = ImageIO.read(new File("resource/images/" + fishName));
images[i] = tempImage;
}
//初始化图片下标
this.imagesIndex = 0;
this.image = this.images[this.imagesIndex];
//初始化鱼的宽度和高度
this.width = this.image.getWidth();
this.height = this.image.getHeight();
//初始化x和y的坐标
this.x = 800;
Random random = new Random();
int nextInt = random.nextInt(400);
this.y = nextInt;
//初始化速度
this.step = random.nextInt(5);
//初始化是否被抓住
this.isCatch = false;
this.catchImages = new BufferedImage[2];
this.catchImages[0] = ImageIO.read(new File("resource/images/" + imageName + "_catch_01.png"));
// this.width = image.getWidth();
}
/**
* 鱼的游动
*/
public void move() {
//坐标减去游动的速度
this.x = this.x - this.step;
//切换鱼的图片
this.image = this.images[this.imagesIndex ++ % this.images.length];
//重新游一遍,小于鱼与横坐标则返回
if (this.x < -this.width) {
//重置x坐标
this.x = 800;
//重置y坐标
Random random = new Random();
this.y = random.nextInt(375);
//重置鱼游的速度
this.step = random.nextInt(5) + 1;
}
//休眠
try {
sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 被捕获时翻滚
*/
public void turnOver() {
//切换鱼被捕获时鱼的图片
for (int i = 0; i < 6; i++) {
this.image = this.catchImages[i % this.catchImages.length];
try {
sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//重置鱼的属性,坐标,速度,是否被抓
this.x = 800;
Random random = new Random();
this.y = random.nextInt(375);
this.step = random.nextInt(5) + 1;
this.isCatch = false;
}
@Override
public void run() {
while (true) {
if (this.isCatch) {
turnOver();
}else {
move();
}
}
}
/**
* 生成了鱼的属性set和get方法
* @return
*/
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
}
public boolean isCatch() {
return isCatch;
}
public void setCatch(boolean isCatch) {
this.isCatch = isCatch;
}
}
鱼网的设置(这里渔网是静态的,有缺陷):
package game;
/**
* 捕鱼网
* @author Lenovo
*
*/
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Net {
//图片
private BufferedImage image;
//X坐标
private double x;
//Y坐标
private double y;
//宽度
private double width;
//高度
private double height;
//是否展示
private boolean isShow;
/**
* 渔网构造方法
* @throws IOException
*/
public Net() throws IOException {
//初始化图片
this.image = ImageIO.read(new File("resource/images/net09.png"));
this.x = 100;
this.y = 100;
this.width = this.image.getWidth();
this.height = this.image.getHeight();
this.isShow = true;
}
/**
* 渔网的移动
* @param mouseX
* @param mouseY
*/
public void move(double mouseX, double mouseY) {
//求渔网的中心点
double centerX = this.x + this.width/2;
double centerY = this.y + this.height/2;
//中心点与离鼠标的x位置
double xx = mouseX - centerX;
//中心点与离鼠标的y位置
double yy = mouseY - centerY;
//左上角点平移
this.x = this.x + xx;
this.y = this.y + yy;
}
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public boolean isShow() {
return isShow;
}
public void setShow(boolean isShow) {
this.isShow = isShow;
}
}
发射的子弹
package game;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
/**
* 发射的子弹
* @author zouzhuo
*
*/
public class Bullet extends Thread{
//图片
private BufferedImage image;
//坐标值
private int x;
private int y;
//大小
private int width;
private int height;
//是否活着
private boolean isAlive;
//速度
private int step;
//角度
private double thread;
//子弹发射的原点
private Point point;
//池塘
private Pool pool;
public Bullet(int x, int y, Double thread, Pool pool) throws IOException {
this.image = ImageIO.read(new File("resource/images/bullet1.png"));
this.width = this.image.getWidth();
this.height = this.image.getHeight();
this.isAlive = true;
this.step = 10;
this.x = x;
this.y = y;
this.thread = thread;
this.point = new Point(x, y);
// this.point.x = x;
// this.point.y =y;
this.pool = pool;
}
/**
* 子弹移动的速度
*/
public void move() {
this.y = this.y - this.step;
//判断出界
int distance = this.point.y - this.y;
//求xx,需要进一步进行强制转换
int xx = (int) (distance * Math.sin(this.thread));
int xxx = this.point.x + xx;
//求yy坐标
int yy = (int) (distance * Math.cos(this.thread));
int yyy = this.point.y - yy;
//判断是否出界
if (xxx < 0 || xxx > 800 || yyy < 0) {
//将子弹置为死亡
this.isAlive = false;
//在数组中删除子弹
this.pool.getBullets().remove(this);
}
//判断是否击中鱼
Fish[] fishs = pool.getFishes();
for (Fish fish : fishs) {
//鱼的x坐标范围
int maxX = fish.getX() + fish.getWidth();
//鱼的y坐标范围
int mayY = fish.getY() + fish.getHeight();
if (xxx > fish.getX() && xxx < maxX && fish.getY() < yyy && yyy < mayY) {
//设置鱼被抓到
fish.setCatch(true);
//设置让子弹消失
this.isAlive = false;
//在数组中删除子弹
this.pool.getBullets().remove(this);
}
}
try {
sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
super.run();
while (true) {
//让子弹飞一会
if (isAlive) {
move();
}else {
//直接结束线程
return;
}
}
}
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public double getThread() {
return thread;
}
public void setThread(double thread) {
this.thread = thread;
}
}
还有一个计分板没有写上,没有开始结束的界面,渔网是静态的,这些功能都还没有实现,日后更新