package xm1;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
public class GWindow extends JFrame {
// 游戏状态 0——未开始 1——游戏中 2——通关失败 3——通关成功 4——暂停
static int state = 0;// 游戏默认状态 利用switch语句定义游戏状态
// 获取背景类Bg的对象
Bg bg = new Bg();
// 创建一个空的图片,将所有的组件先绘制到空的图片上,将绘制好的图片一次性绘制到主窗口上----定义一个成员变量
Image offScreenImage;
// 敌方鱼
EnamyFish enamy;
// boss类
EnamyFish boss;
// 是否生成boss
boolean isboss = false;
// 控制敌方鱼的生成速度过快
int time = 0;// 记录游戏的重绘次数 即paint调用次数,while中进行自增
// 我方鱼类
MyFish myFish = new MyFish();
// 随机数
double random;
// 窗体宽高
int width = 1440;
int height = 900;
// 创建一个启动方法,设置窗口信息
public void launch() {
setSize(width, height);
setVisible(true);
setLocationRelativeTo(null);// 设置游戏窗口居中位置
setTitle("大鱼吃小鱼");
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
// 键盘事件
this.addKeyListener(new KeyAdapter() {
@Override // 按压
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
// WASD移动 W在键盘上对应的数值为87,S——83,A——65,D——68
if (e.getKeyCode() == 87) {
GUtils.UP = true;
}
if (e.getKeyCode() == 83) {
GUtils.DOWN = true;
}
if (e.getKeyCode() == 65) {
GUtils.LEFT = true;
}
if (e.getKeyCode() == 68) {
GUtils.RIGHT = true;
}
// 空格键的值为32
if (e.getKeyCode() == 32) {
// 如果游戏状态为运行则更改为暂停,反之
switch (state) {
case 1:
state = 4;
GUtils.drawWord(getGraphics(), "游戏暂停", Color.red, 50, 600, 400);
// 在游戏状态为4中,添加提示语
break;
case 4:
state = 1;
break;
}
}
}
@Override // 抬起
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
if (e.getKeyCode() == 87) {
GUtils.UP = false;
}
if (e.getKeyCode() == 83) {
GUtils.DOWN = false;
}
if (e.getKeyCode() == 65) {
GUtils.LEFT = false;
}
if (e.getKeyCode() == 68) {
GUtils.RIGHT = false;
}
}
});
// 鼠标事件
this.addMouseListener(new MouseAdapter() {// 使用MouseAdapter()可直接重写某个需要的方法
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
// 用if判断鼠标可否点击,并进入游戏运行状态
if (e.getButton() == 1 && state == 0) {
state = 1;// 鼠标点击了左键时,e.getButton()==1,进入游戏中修改state=1
repaint();// repaint()可再次调用paint方法,将改变后的窗口绘制出来
}
if (e.getButton() == 1 && (state == 2 || state == 3)) {
reGame();
state = 1;
}
}
});
// 背景图片的循环使用,需要重复调用paint()方法,在launch方法中添加一个while循环,每间隔40ms调用一次repaint方法
while (true) {
repaint();
time++;
try {
Thread.sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 窗体自带刷新方法,会使绘制前的图像 随着窗体的刷新而消失
// 重写paint方法,让图像随着窗体的刷新再次被绘制出来
@Override
public void paint(Graphics g) {
// 懒加载模式初始化对象
offScreenImage = createImage(width, height);
Graphics gImage = offScreenImage.getGraphics();// 获取图片对应的画笔对象,把组件绘制到新的图片中
bg.paintSelf(gImage, MyFish.grade);// 调用背景开始时界面的方法
switch (state) {
case 0:// 启动页面背景图
// 已在Bg类中定义
// gImage.drawImage(GUtils.image, 0, 0, null);//启动页面背景图
// gImage.setColor(Color.pink);//将画笔颜色改为粉色
// gImage.setFont(new Font("仿宋",Font.BOLD,60));//设置字体样式
// gImage.drawString("开始", 700, 500);//为启动页面添加文字
break;
case 1:
logic();// 由于鱼类需要不断地创建,所以调用logic()方法
myFish.paintSelf(gImage);
for (EnamyFish enamy : GUtils.EnamyList) {// 循环遍历敌方鱼的生成
enamy.paintSelf(gImage);// 绘制敌方鱼
}
if (isboss) {
boss.x = boss.x + boss.dir * boss.speed;
boss.paintSelf(gImage);
if (boss.x < 0) {// boss出现前预警
gImage.setColor(Color.red);
gImage.fillRect(boss.x, boss.y, 2400, boss.height / 30);
}
}
break;
case 2:
for (EnamyFish enamy : GUtils.EnamyList) {// 循环遍历敌方鱼的生成
enamy.paintSelf(gImage);// 绘制敌方鱼
}
if (isboss) {
boss.paintSelf(gImage);
}
break;
case 3:
myFish.paintSelf(gImage);
break;
case 4:
return;
default:
}
// 用画笔g绘制图片
// drawImage(Image img, int x, int y, ImageObserver
// observer)方法:绘制指定图像中当前可用的图像
g.drawImage(offScreenImage, 0, 0, null);// 将绘制好的新图片,一次性绘制到主窗口中
}
// 创建logic()方法批量添加敌方鱼类,鱼类需要不断地创建所以需要添加到游戏状态为1的代码块中
public void logic() {
// 关卡难度
if (GUtils.count < 10) {
GUtils.grade = 0;
MyFish.grade = 1;
} else if (GUtils.count <= 50) {
GUtils.grade = 1;
} else if (GUtils.count <= 100) {
GUtils.grade = 2;
MyFish.grade = 2;
} else if (GUtils.count <= 150) {
GUtils.grade = 3;
MyFish.grade = 3;
} else if (GUtils.count <= 200) {
GUtils.grade = 4;
MyFish.grade = 3;
} else if (GUtils.count > 200) {
state = 3;
}
// 定义一个随机数,让鱼类有一半的鱼从左右两边出来
random = Math.random();
// switch 实现鱼类在不同等级关卡的出现
switch (GUtils.grade) {
case 4:
if (time % 60 == 0) {
if (random > 0) {
boss = new Enamy_boss();
isboss = true;
}
}
case 3:
case 2:
if (time % 30 == 0) {
if (random > 0.5) {
enamy = new Enamy_3_L();
} else {
enamy = new Enamy_3_R();
}
GUtils.EnamyList.add(enamy);
}
case 1:
if (time % 20 == 0) {
if (random > 0.5) {
enamy = new Enamy_2_L();
} else {
enamy = new Enamy_2_R();
}
GUtils.EnamyList.add(enamy);
}
case 0:
// 每调用20次paint方法生成一条鱼
if (time % 20 == 0) {
if (random > 0.5) {
enamy = new Enamy_1_L();// 将小鱼添加到集合中
} else {
enamy = new Enamy_1_R();
}
GUtils.EnamyList.add(enamy);
}
break;
default:
}
// foreach循环定义鱼类移动方向
for (EnamyFish enamy : GUtils.EnamyList) {
enamy.x += enamy.dir * enamy.speed;
// 若boss鱼与其他鱼碰撞,其他鱼类消失
if (isboss) {
if (boss.getrRec().intersects(enamy.getrRec())) {
enamy.x = -200;
enamy.y = -200;
}
if (boss.getrRec().intersects(myFish.getRec())) {
state = 2;// 在state=2的代码块中添加boss
}
}
// 我方鱼与敌方鱼碰撞检测(检测两个物体的矩形是否有重合部分)//使用intersects()方法检验
if (myFish.getRec().intersects(enamy.getrRec())) {
if (myFish.grade >= enamy.type) {
System.out.println("碰撞了");
enamy.x = -200;
enamy.y = -200;
GUtils.count = GUtils.count + enamy.count;// 碰撞了,积分加碰撞的敌方鱼数
} else {
state = 2;// 游戏失败时,游戏界面只有敌方鱼,并显示失败
}
}
}
}
// 重新开始 ——敌方鱼清零,计时器清零,我方鱼等级为1....
void reGame() {
GUtils.EnamyList.clear();// 敌方鱼清零
time = 0;// 计时器清零
MyFish.grade = 1;// 我方鱼等级为1
GUtils.count = 0;
myFish.x = 700;// 我方鱼坐标初始化
myFish.y = 500;
myFish.width = 50;
myFish.height = 50;
boss = null;// boss鱼为空
isboss = false;
}
public static void main(String[] args) {
GWindow gw = new GWindow();
new Music("Relax.mp3").start();
gw.launch();
}
}
Java 大鱼吃小鱼 源代码
需积分: 0 50 浏览量
2023-06-29
19:47:17
上传
评论 2
收藏 7.27MB ZIP 举报
moon-Joe
- 粉丝: 241
- 资源: 11
最新资源
- 我分享个魔兽内存修改器
- Python毕业设计基于Django的网易云数据分析可视化大屏系统的设计与实现+使用说明+全部资料(优秀项目).zip
- Python毕业设计基于Django的网易云数据分析可视化大屏系统的设计与实现+使用说明+全部资料(高分项目).zip
- JavaScript实现的鼠标手势
- 人工兔优化算法ARO MATLAB源码, 应用案例为函数极值求解以及优化svm进行分类,代码注释详细,可结合自身需求进行应用
- 人才网站设计-asp.net+sql-(系统源码)
- asp.net+sql人才网站设计-含系统源码
- C#应用的用户配置窗体方案
- python实现绘制爱心图形的代码
- JAVAWEB项目-校园订餐系统项目源码.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈