本游戏代码参考【尚学堂】Java开发游戏_大鱼吃小鱼项目实战教程

目录

  • 游戏展示
  • 游戏脑图
  • 详细分析
    • GameUtils
    • Enemy
    • Myfish
    • GameWin
      • 键盘监听
      • 鼠标监听
      • 重绘界面
      • 游戏状态
      • 产生敌方鱼
      • 碰撞检测
      • 重新游戏
      • 添加背景音乐
  • 全部源代码

游戏展示

这是写好的游戏在idea里的运行结果

大鱼吃小鱼游戏视频

游戏脑图

写游戏时的思想框架

详细分析

GameUtils

用Image来绘制各种背景,各种鱼类的图片
用ArrayList集合来存储在游戏过程中会出现的各种鱼类,以便在主方法中获取里面的鱼,和在重新游戏的功能里清空游戏界面上的鱼类
定义静态的变量,以便在其他类中的使用

package EatGame;import java.awt.*;import java.util.ArrayList;import java.util.List;public class GameUtils {////方向//添加方向判定,对我方鱼的移动的控制static boolean UP = false;static boolean DOWN = false;static boolean LEFT = false;static boolean RIGHT = false;//分数static int count = 0;//ArrayList集合来存储在游戏过程中会出现的各种鱼类//创建敌方鱼类集合批量生产鱼类public static List<Enemy> EnemyList = new ArrayList<>();public static List<EnemyBoss> EnemyBossList = new ArrayList<>(); //背景图片public static Image img1 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\1.jpg");//开始游戏图片public static Image img2 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\2.jpg");//敌方鱼类A右public static Image img3 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\3.gif");//敌方鱼类A左public static Image img4 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\4.gif");//敌方鱼类B左public static Image img9 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\fish2_r.png");//敌方鱼类B左//敌方鱼类B右public static Image img12 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\fish2_l.png");//敌方鱼类B左//敌方鱼类C左public static Image img10 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\fish3_r.png");//敌方鱼类C右public static Image img13 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\fish3_l.png");//Boss鱼public static Image img11 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\boss.gif");//我方鱼类public static Image img5 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\myfish_left.gif");public static Image img6 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\myfish_right.gif");//胜利public static Image img7 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\win.jpg");//失败public static Image img8 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\fail.jpg");//结束public static Image img14 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\5.jpg");}

Enemy

Enemy类是所有敌方鱼类的父类,里面有对敌方鱼的描述和获得自身矩形以便碰撞检测的方法
x,y分别为鱼在画布上的坐标
width,height分别为绘制的鱼类图片的大小

import java.awt.*;public class Enemy {//定义图片Image img;//定义物体坐标int x;int y;int width;int height;//移动速度int speed;//方向向右为1;向左为-1int dir ;//类型int type;//吃了获得的分值int count;//等级int size;//绘制自身方法public void paintSelf(Graphics g){g.drawImage(img,x,y,width,height,null);}//获取自身矩形以用于检测碰撞public Rectangle getRec(){return new Rectangle(x,y,width,height);}}//敌方鱼类A左class EnemyAZ extends Enemy{EnemyAZ(){this.x = -45;this.y = (int)(Math.random()*700+100);this.width = 30;this.height = 50;this.speed = 8;this.dir = 1;this.count = 1;this.type = 1;this.size = 0;this.img = GameUtils.img4;}}//敌方鱼类A右class EnemyAY extends Enemy{EnemyAY(){this.x = 1440;this.y = (int)(Math.random()*700+100);this.width = 30;this.height = 50;this.speed = 8;this.dir = -1;this.count = 1;this.type = 1;this.size = 0;this.img = GameUtils.img3;}}//敌方鱼类B左class EnemyBZ extends Enemy{EnemyBZ(){this.x = -45;this.y = (int)(Math.random()*700+100);this.width = 50;this.height = 80;this.speed = 5;this.dir = 1;this.count = 3;this.type = 2;this.size = 15;this.img = GameUtils.img9;}}//敌方鱼类B右class EnemyBY extends Enemy{EnemyBY(){this.x = 1440;this.y = (int)(Math.random()*700+100);this.width = 50;this.height = 80;this.speed = 5;this.dir = -1;this.count = 3;this.type = 2;this.size = 15;this.img = GameUtils.img12;}}//敌方鱼类C左class EnemyCZ extends Enemy {EnemyCZ() {this.x = -400;this.y = (int) (Math.random() * 700 + 100);this.width = 300;this.height = 120;this.speed = 7;this.dir = 1;this.count = 10;this.type = 2;this.size = 100;this.img = GameUtils.img10;}}//敌方鱼类C右class EnemyCY extends Enemy {EnemyCY() {this.x = 1600;this.y = (int) (Math.random() * 700 + 100);this.width = 300;this.height = 120;this.speed = 7;this.dir = -1;this.count = 10;this.type = 2;this.size = 100;this.img = GameUtils.img13;}}//Boss鱼class EnemyBoss extends Enemy {EnemyBoss() {this.x = -1000;this.y = (int) (Math.random() * 700 + 100);this.width = 200;this.height = 220;this.speed = 60;this.dir = 1;this.count = 5;this.type = 2;this.size = 1000;this.img = GameUtils.img11;}}

Myfish

Myfish类是定义的自己的鱼的类
getRec方法可以获取自身矩形,用于碰撞检测
logic方法用if语句判断自己的鱼是不是超出定义的画布的范围,使自己的鱼可以一直在画布的范围内行动

import java.awt.*;public class MyFish {//图片Image img = GameUtils.img5;//坐标int x = 700;int y = 500;int width = 50;int height = 50;//移动速度int speed = 20;//等级int level = 1;//大小int size = 0;//生命int life = 3;void logic(){if(x<=0){if(GameUtils.UP){y = y - speed;}if(GameUtils.DOWN){y = y + speed;}if(GameUtils.RIGHT){x = x + speed;img = GameUtils.img6;}}else if(y<=0){if(GameUtils.DOWN){y = y + speed;}if(GameUtils.RIGHT){x = x + speed;img = GameUtils.img6;}if(GameUtils.LEFT){x = x - speed;img = GameUtils.img5;}}else if(x>=1400){if(GameUtils.UP){y = y - speed;}if(GameUtils.DOWN){y = y + speed;}if(GameUtils.LEFT){x = x - speed;img = GameUtils.img5;}}else if(y>=850){if(GameUtils.UP){y = y - speed;}if(GameUtils.RIGHT){x = x + speed;img = GameUtils.img6;}if(GameUtils.LEFT){x = x - speed;img = GameUtils.img5;}}else{if(GameUtils.UP){y = y - speed;}if(GameUtils.DOWN){y = y + speed;}if(GameUtils.RIGHT){x = x + speed;img = GameUtils.img6;}if(GameUtils.LEFT){x = x - speed;img = GameUtils.img5;}}}//绘制自身方法public void paintSelf(Graphics g){logic();g.drawImage(img,x,y,width+GameUtils.count/3,height+GameUtils.count/3,null);}//获取自身矩形,用于碰撞检测public Rectangle getRec(){return new Rectangle(x,y,width+GameUtils.count/3,height+GameUtils.count/3);}}

GameWin

GameWin是含有main方法的Java类,是小游戏的核心程序所在

键盘监听

使用键盘监听,重写keyPressed方法,使用if语句根据游戏所处状态以及键盘的抬起松开达到键盘控制游戏内容的能力
用WASD来控制我方鱼的移动
用空格键来暂停游戏

this.addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {//super.keyPressed(e);//WASD控制移动W 86S 83A 65Dif (e.getKeyCode() == 87) {GameUtils.UP = true;}if (e.getKeyCode() == 83) {GameUtils.DOWN = true;}if (e.getKeyCode() == 65) {GameUtils.LEFT = true;}if (e.getKeyCode() == 68) {GameUtils.RIGHT = true;}//游戏过程中暂停游戏if(e.getKeyCode() == 32){switch (state){case 1:state = 4;break;case 4:state = 1;break;}}}@Override// 抬起public void keyReleased(KeyEvent e) {//super.keyReleased(e);if (e.getKeyCode() == 87) {GameUtils.UP = false;}if (e.getKeyCode() == 83) {GameUtils.DOWN = false;}if (e.getKeyCode() == 65) {GameUtils.LEFT = false;}if (e.getKeyCode() == 68) {GameUtils.RIGHT = false;}}});

鼠标监听

使用键盘监听,重写mouseClicked方法,使用if语句根据游戏所处状态以及鼠标的左右键来实现游戏过程中的重新游戏,及胜利失败后是否要重新玩一局游戏

this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);this.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {super.mouseClicked(e);if (e.getButton() == 1 && state == 0) {state = 1;repaint();}if(e.getButton() == 1 && (state == 2||state == 3)){state = 5;System.out.println("*****");}//胜利或者结束后的界面右键重新开始游戏if(e.getButton() == 3 && state==5){System.out.println("=====");reGame();state = 1;}//游戏过程中右键重新开始if(e.getButton() == 3 && state==1){System.out.println("=====");reGame();state = 1;}}});

重绘界面

设置while(true)死循环
每30毫秒重绘一次游戏界面,以达到动态的效果

 while (true) {repaint();time++;try {Thread.sleep(30);} catch (InterruptedException e) {throw new RuntimeException(e);}}

游戏状态

用是switch判断游戏的状态
游戏状态: 0 未开始 1 游戏中 2 通关失败 3 通关成功 4 暂停 5 游戏结束
每个状态中绘制GameUtils中相应的图片

 switch (state) {case 0:gImage.drawImage(GameUtils.img2, 0, 0, null);break;case 1:gImage.drawImage(GameUtils.img1, 0, 0, null);//显示分数,生命bg.paintSelf(gImage);gImage.setColor(Color.MAGENTA);gImage.setFont(new Font("仿宋", Font.BOLD, 50));gImage.drawString("分数" + GameUtils.count, 200, 120);gImage.drawString("生命" + myFish.life, 1000, 120);myFish.paintSelf(gImage);logic();//循环遍历敌方鱼的生成for (Enemy enemy : GameUtils.EnemyList) {enemy.paintSelf(gImage);}for (EnemyBoss enemyBoss : GameUtils.EnemyBossList) {enemyBoss.paintSelf(gImage);if(enemyBoss.x<0){gImage.setColor(Color.red);gImage.fillRect(enemyBoss.x,enemyBoss.y+110,1440,2);}}break;case 2:gImage.drawImage(GameUtils.img8, 0, 0, null);break;case 3:gImage.drawImage(GameUtils.img7, 0, 0, null);break;case 4:return;case 5:gImage.drawImage(GameUtils.img14, 0, 0, null);break;}g.drawImage(offScreenImage, 0, 0, null);}

产生敌方鱼

根据游戏界面刷新的的次数不断产生敌方鱼类
例如:敌方海马的不断产生

 if (time%5 == 0) {if(time%10 ==0){EnemyAZ enemy = new EnemyAZ();GameUtils.EnemyList.add(enemy);}else{EnemyAY enemy = new EnemyAY();GameUtils.EnemyList.add(enemy);}}

碰撞检测

根据我方鱼类与敌方鱼类中绘制的自身矩形的方法,判断两个图层是否重叠,如果重叠,则一方被吃掉,当我方鱼类等级小于敌方鱼类的时候,我方鱼类会减去一条生命,并扣去相应的分数,减去我方鱼类图片相应的大小,而当被减去的分数小于等于零时,我方鱼类直接被吃掉,游戏失败。
当我方鱼类的等级高于敌方鱼类的时候,敌方鱼类会消失,并且我方鱼类的大小增加,分数增加。

if (myFish.getRec().intersects(enemy.getRec())) {System.out.println("碰撞了");if (myFish.size >= enemy.size) {//吃掉敌方鱼enemy.x = -200;enemy.y = -200;GameUtils.count = GameUtils.count + enemy.count;myFish.size += enemy.count;} else {//我方鱼等级小于敌方enemy.x = -200;enemy.y = -200;if(myFish.life < 2){System.out.println(myFish.life+"****");myFish.x = -200;myFish.y = -200;state = 2;}else{myFish.life--;System.out.println(myFish.life);if(enemy.count == 3){//等级减小myFish.size -= 5;//分数减少GameUtils.count = GameUtils.count - 5;//大小变小myFish.width = myFish.width - 5;myFish.height = myFish.height - 3;if(GameUtils.count<=0){//分数少于0,失败myFish.x = -200;myFish.y = -200;state = 2;}}if(enemy.count == 10){//等级减小myFish.size -= 20;//分数减少GameUtils.count = GameUtils.count - 20;//大小变小myFish.width = myFish.width - 10;myFish.height = myFish.height - 6;if(GameUtils.count<=0){//分数少于0,失败myFish.x = -200;myFish.y = -200;state = 2;}}}}}

重新游戏

清空数据,以达到重新游戏的效果

void reGame(){GameUtils.EnemyList.clear();GameUtils.EnemyBossList.clear();time= 0;myFish.size = 5;GameUtils.count = 0;myFish.x = 700;myFish.y = 500;myFish.height = 50;myFish.width = 50;myFish.life = 3;}

添加背景音乐

将启动游戏界面的方法放入一个线程内,在写一个播放音乐的代码,使两方同时进行,要特别注意音乐文件必须是wav格式

 public static void main(String[] args) {GameWin gameWin = new GameWin();//多线程运行游戏new Thread(()->{while(true){gameWin.launch();}}).start();//背景音乐try {Clip bgm = AudioSystem.getClip();InputStream is = Music.class.getClassLoader().getResourceAsStream("EatGame/bgm.wav");AudioInputStream ais = AudioSystem.getAudioInputStream(is);bgm.open(ais);bgm.start();bgm.loop(Clip.LOOP_CONTINUOUSLY);do {} while (true);} catch (LineUnavailableException | UnsupportedAudioFileException | IOException e) {e.printStackTrace();}}

全部源代码

import java.awt.*;import java.util.ArrayList;import java.util.List;public class Bg {void paintSelf(Graphics g){g.drawImage(GameUtils.img1,0,0,null);}}public class Enemy {//定义图片Image img;//定义物体坐标int x;int y;int width;int height;//移动速度int speed;//方向向右为1;向左为-1int dir ;//类型int type;//吃了获得的分值int count;//等级int size;//绘制自身方法public void paintSelf(Graphics g){g.drawImage(img,x,y,width,height,null);}//获取自身矩形以用于检测碰撞public Rectangle getRec(){return new Rectangle(x,y,width,height);}}//敌方鱼类A左class EnemyAZ extends Enemy{EnemyAZ(){this.x = -45;this.y = (int)(Math.random()*700+100);this.width = 30;this.height = 50;this.speed = 8;this.dir = 1;this.count = 1;this.type = 1;this.size = 0;this.img = GameUtils.img4;}}//敌方鱼类A右class EnemyAY extends Enemy{EnemyAY(){this.x = 1440;this.y = (int)(Math.random()*700+100);this.width = 30;this.height = 50;this.speed = 8;this.dir = -1;this.count = 1;this.type = 1;this.size = 0;this.img = GameUtils.img3;}}//敌方鱼类B左class EnemyBZ extends Enemy{EnemyBZ(){this.x = -45;this.y = (int)(Math.random()*700+100);this.width = 50;this.height = 80;this.speed = 5;this.dir = 1;this.count = 3;this.type = 2;this.size = 15;this.img = GameUtils.img9;}}//敌方鱼类B右class EnemyBY extends Enemy{EnemyBY(){this.x = 1440;this.y = (int)(Math.random()*700+100);this.width = 50;this.height = 80;this.speed = 5;this.dir = -1;this.count = 3;this.type = 2;this.size = 15;this.img = GameUtils.img12;}}//敌方鱼类C左class EnemyCZ extends Enemy {EnemyCZ() {this.x = -400;this.y = (int) (Math.random() * 700 + 100);this.width = 300;this.height = 120;this.speed = 7;this.dir = 1;this.count = 10;this.type = 2;this.size = 100;this.img = GameUtils.img10;}}//敌方鱼类C右class EnemyCY extends Enemy {EnemyCY() {this.x = 1600;this.y = (int) (Math.random() * 700 + 100);this.width = 300;this.height = 120;this.speed = 7;this.dir = -1;this.count = 10;this.type = 2;this.size = 100;this.img = GameUtils.img13;}}//Boss鱼class EnemyBoss extends Enemy {EnemyBoss() {this.x = -1000;this.y = (int) (Math.random() * 700 + 100);this.width = 200;this.height = 220;this.speed = 60;this.dir = 1;this.count = 5;this.type = 2;this.size = 1000;this.img = GameUtils.img11;}}public class MyFish {//图片Image img = GameUtils.img5;//坐标int x = 700;int y = 500;int width = 50;int height = 50;//移动速度int speed = 20;//等级int level = 1;//大小int size = 0;//生命int life = 3;void logic(){if(x<=0){if(GameUtils.UP){y = y - speed;}if(GameUtils.DOWN){y = y + speed;}if(GameUtils.RIGHT){x = x + speed;img = GameUtils.img6;}}else if(y<=0){if(GameUtils.DOWN){y = y + speed;}if(GameUtils.RIGHT){x = x + speed;img = GameUtils.img6;}if(GameUtils.LEFT){x = x - speed;img = GameUtils.img5;}}else if(x>=1400){if(GameUtils.UP){y = y - speed;}if(GameUtils.DOWN){y = y + speed;}if(GameUtils.LEFT){x = x - speed;img = GameUtils.img5;}}else if(y>=850){if(GameUtils.UP){y = y - speed;}if(GameUtils.RIGHT){x = x + speed;img = GameUtils.img6;}if(GameUtils.LEFT){x = x - speed;img = GameUtils.img5;}}else{if(GameUtils.UP){y = y - speed;}if(GameUtils.DOWN){y = y + speed;}if(GameUtils.RIGHT){x = x + speed;img = GameUtils.img6;}if(GameUtils.LEFT){x = x - speed;img = GameUtils.img5;}}}//绘制自身方法public void paintSelf(Graphics g){logic();g.drawImage(img,x,y,width+GameUtils.count/3,height+GameUtils.count/3,null);}//获取自身矩形,用于碰撞检测public Rectangle getRec(){return new Rectangle(x,y,width+GameUtils.count/3,height+GameUtils.count/3);}}public class GameUtils {//方向//添加方向判定,对我方鱼的移动的控制static boolean UP = false;static boolean DOWN = false;static boolean LEFT = false;static boolean RIGHT = false;//分数static int count = 0;//创建敌方鱼类集合批量生产鱼类public static List<Enemy> EnemyList = new ArrayList<>();public static List<EnemyBoss> EnemyBossList = new ArrayList<>(); /* public static List PlaneList = new ArrayList();public static List BombList = new ArrayList();public static List Explode6List = new ArrayList();*///背景图片public static Image img1 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\1.jpg");//开始游戏图片public static Image img2 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\2.jpg");//敌方鱼类A右public static Image img3 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\3.gif");//敌方鱼类A左public static Image img4 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\4.gif");//敌方鱼类B左public static Image img9 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\fish2_r.png");//敌方鱼类B左//敌方鱼类B右public static Image img12 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\fish2_l.png");//敌方鱼类B左//敌方鱼类C左public static Image img10 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\fish3_r.png");//敌方鱼类C右public static Image img13 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\fish3_l.png");//Boss鱼public static Image img11 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\boss.gif");//我方鱼类public static Image img5 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\myfish_left.gif");public static Image img6 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\myfish_right.gif");//胜利public static Image img7 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\win.jpg");//失败public static Image img8 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\fail.jpg");//结束public static Image img14 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\5.jpg");// 飞机public static Image img15 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\plane.png");//炸弹public static Image img16 = Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\bomb.png");public static Image e6= Toolkit.getDefaultToolkit().createImage("D:\\IDEACode\\untitled\\src\\EatGame\\picture\\explode\\e6.gif");}public class Music {}package EatGame;import sun.font.FontRunIterator;import javax.sound.sampled.*;import javax.swing.*;import java.awt.*;import java.awt.event.KeyAdapter;import java.awt.event.KeyEvent;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import java.util.List;public class GameWin extends JFrame {//游戏状态: 0 未开始1 游戏中2 通关失败3 通关成功4 暂停5 游戏结束//游戏默认状态 未开始static int state = 0;//解决频闪//思路:使用缓存的方式解决//重新创建一个新的图片,把所有的组件先绘制到空的图片上。然后把绘制好的图片一次性绘制到主窗口上Image offScreenImage;//宽高int width = 1440;int height = 900;//double random;---------------------------------------------------//计数器//记录游戏的重绘次数即paint的调用次数int time = 0;//背景Bg bg = new Bg();//我方鱼类MyFish myFish = new MyFish();//敌方鱼类Enemy enemy = new Enemy();EnemyBoss enemyBoss = new EnemyBoss();public void launch() {//设置窗口大小可见this.setVisible(true);//设置窗口大小宽高this.setSize(width, height);//设置窗口大小居中this.setLocationRelativeTo(null);//设置窗口大小不可改变this.setResizable(false);//设置标题this.setTitle("木木木大鱼吃小鱼");//使用 System exit 方法退出应用程序this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);this.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {super.mouseClicked(e);if (e.getButton() == 1 && state == 0) {state = 1;repaint();}if(e.getButton() == 1 && (state == 2||state == 3)){state = 5;System.out.println("*****");}//胜利或者结束后的界面右键重新开始游戏if(e.getButton() == 3 && state==5){System.out.println("=====");reGame();state = 1;}//游戏过程中右键重新开始if(e.getButton() == 3 && state==1){System.out.println("=====");reGame();state = 1;}}});//键盘移动this.addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {//super.keyPressed(e);//WASD控制移动W 86S 83A 65Dif (e.getKeyCode() == 87) {GameUtils.UP = true;}if (e.getKeyCode() == 83) {GameUtils.DOWN = true;}if (e.getKeyCode() == 65) {GameUtils.LEFT = true;}if (e.getKeyCode() == 68) {GameUtils.RIGHT = true;}//游戏过程中暂停游戏if(e.getKeyCode() == 32){switch (state){case 1:state = 4;break;case 4:state = 1;break;}}}@Override// 抬起public void keyReleased(KeyEvent e) {//super.keyReleased(e);if (e.getKeyCode() == 87) {GameUtils.UP = false;}if (e.getKeyCode() == 83) {GameUtils.DOWN = false;}if (e.getKeyCode() == 65) {GameUtils.LEFT = false;}if (e.getKeyCode() == 68) {GameUtils.RIGHT = false;}}});while (true) {repaint();time++;try {Thread.sleep(30);} catch (InterruptedException e) {throw new RuntimeException(e);}}}@Overridepublic void paint(Graphics g) {//加载模式初始化对象offScreenImage = createImage(width, height);Graphics gImage = offScreenImage.getGraphics();switch (state) {case 0:gImage.drawImage(GameUtils.img2, 0, 0, null);break;case 1:gImage.drawImage(GameUtils.img1, 0, 0, null);//显示分数,生命bg.paintSelf(gImage);gImage.setColor(Color.MAGENTA);gImage.setFont(new Font("仿宋", Font.BOLD, 50));gImage.drawString("分数" + GameUtils.count, 200, 120);gImage.drawString("生命" + myFish.life, 1000, 120);myFish.paintSelf(gImage);logic();//循环遍历敌方鱼的生成for (Enemy enemy : GameUtils.EnemyList) {enemy.paintSelf(gImage);}for (EnemyBoss enemyBoss : GameUtils.EnemyBossList) {enemyBoss.paintSelf(gImage);if(enemyBoss.x<0){gImage.setColor(Color.red);gImage.fillRect(enemyBoss.x,enemyBoss.y+110,1440,2);}}break;case 2:gImage.drawImage(GameUtils.img8, 0, 0, null);break;case 3:gImage.drawImage(GameUtils.img7, 0, 0, null);break;case 4:return;case 5:gImage.drawImage(GameUtils.img14, 0, 0, null);break;}g.drawImage(offScreenImage, 0, 0, null);}//不断创建鱼类void logic() {//分数大于300胜利if (GameUtils.count > 350) {state = 3;}//敌方的鱼生成if (time%5 == 0) {if(time%10 ==0){EnemyAZ enemy = new EnemyAZ();GameUtils.EnemyList.add(enemy);}else{EnemyAY enemy = new EnemyAY();GameUtils.EnemyList.add(enemy);}}if (time % 20 == 0) {if(time % 40 == 0){EnemyBZ enemy = new EnemyBZ();GameUtils.EnemyList.add(enemy);}else{EnemyBY enemy = new EnemyBY();GameUtils.EnemyList.add(enemy);}}if ((time) % 100 == 0) {if((time) % 200 == 0){EnemyCZ enemy = new EnemyCZ();GameUtils.EnemyList.add(enemy);}else{EnemyCY enemy = new EnemyCY();GameUtils.EnemyList.add(enemy);}}//用foreach循环定义敌方鱼的移动for (Enemy enemy : GameUtils.EnemyList) {enemy.x = enemy.x + enemy.dir * enemy.speed;//我方鱼与敌方鱼碰撞的检测if (myFish.getRec().intersects(enemy.getRec())) {System.out.println("碰撞了");if (myFish.size >= enemy.size) {//吃掉敌方鱼enemy.x = -200;enemy.y = -200;GameUtils.count = GameUtils.count + enemy.count;myFish.size += enemy.count;} else {//我方鱼等级小于敌方enemy.x = -200;enemy.y = -200;if(myFish.life < 2){System.out.println(myFish.life+"****");myFish.x = -200;myFish.y = -200;state = 2;}else{myFish.life--;System.out.println(myFish.life);if(enemy.count == 3){//等级减小myFish.size -= 5;//分数减少GameUtils.count = GameUtils.count - 5;//大小变小myFish.width = myFish.width - 5;myFish.height = myFish.height - 3;if(GameUtils.count<=0){//分数少于0,失败myFish.x = -200;myFish.y = -200;state = 2;}}if(enemy.count == 10){//等级减小myFish.size -= 20;//分数减少GameUtils.count = GameUtils.count - 20;//大小变小myFish.width = myFish.width - 10;myFish.height = myFish.height - 6;if(GameUtils.count<=0){//分数少于0,失败myFish.x = -200;myFish.y = -200;state = 2;}}}}}}if(time>800){if((time)%150==0){EnemyBoss enemyBoss = new EnemyBoss();GameUtils.EnemyBossList.add(enemyBoss);}}for (EnemyBoss enemyBoss : GameUtils.EnemyBossList) {enemyBoss.x = enemyBoss.x + enemyBoss.dir * enemyBoss.speed;//我方鱼与敌方鱼碰撞的检测if (myFish.getRec().intersects(enemyBoss.getRec())) {myFish.x = -200;myFish.y = -200;state = 2;}//Boss鱼吃掉敌方其他鱼for (Enemy enemy : GameUtils.EnemyList) {if (enemy.getRec().intersects(enemyBoss.getRec())) {enemy.x = -200;enemy.y = -200;}}}}//初始化游戏数据void reGame(){GameUtils.EnemyList.clear();GameUtils.EnemyBossList.clear(); /* GameUtils.BombList.clear();GameUtils.PlaneList.clear();*/time= 0;myFish.size = 5;GameUtils.count = 0;myFish.x = 700;myFish.y = 500;myFish.height = 50;myFish.width = 50;myFish.life = 3;}public static void main(String[] args) {GameWin gameWin = new GameWin();//多线程运行游戏new Thread(()->{while(true){gameWin.launch();}}).start();//背景音乐try {Clip bgm = AudioSystem.getClip();InputStream is = Music.class.getClassLoader().getResourceAsStream("EatGame/bgm.wav");AudioInputStream ais = AudioSystem.getAudioInputStream(is);bgm.open(ais);bgm.start();bgm.loop(Clip.LOOP_CONTINUOUSLY);do {} while (true);} catch (LineUnavailableException | UnsupportedAudioFileException | IOException e) {//throw new RuntimeException(e);e.printStackTrace();}}}