Java实现大鱼吃小鱼游戏(开源)

Java实现大鱼吃小鱼游戏(开源)前言 游戏参考于 B 站 尚学堂 大鱼吃小鱼 主体框架不变 代码稍有改动 大鱼吃小鱼 又称吞食鱼 是一款动作类小游戏 通过不断的吞吃比自己小的鱼类快速成长 最终成为海洋霸主 游戏主要 Java 知识 变量 数据类型 判断语句 循环结构 类的继承 简单窗口创建 图形图片绘制 双缓存技术

大家好,我是讯享网,很高兴认识大家。

前言 :

游戏参考于B站_【尚学堂】大鱼吃小鱼,主体框架不变,代码稍有改动。

大鱼吃小鱼:又称吞食鱼,是一款动作类小游戏。通过不断的吞吃比自己小的鱼类快速成长,最终成为海洋霸主。

游戏主要Java知识:变量、数据类型、判断语句、循环结构、类的继承、简单窗口创建、图形图片绘制、双缓存技术、鼠标事件、键盘事件。

非常适合在同学Java学习结束后,作为不错的结课作业或者练手项目。

源码已经在文章结束语后打包,有兴趣的同学可以免费下载,创作不易,点个免费的赞支持一下!

运行环境:jdk-17.05

操作方法:w,s,a,d (英文输入法)控制小鱼方向


讯享网

游戏主要框架:

游戏素材:

游戏代码:

(1)Bg类

import java.awt.*; public class Bg { void paintSelf(Graphics g, int fishLevel) { g.drawImage(GameUtils.bgimg, 0, 0, null); switch (GameWin.state) { case 0: GameUtils.drawWord(g, "开始", Color.red, 80, 600, 400); break; case 1: GameUtils.drawWord(g, "积分" + GameUtils.count, Color.ORANGE, 50, 200, 120); GameUtils.drawWord(g, "难度" + GameUtils.level, Color.ORANGE, 50, 600, 120); GameUtils.drawWord(g, "等级" + fishLevel, Color.ORANGE, 50, 1000, 120); break; case 2: GameUtils.drawWord(g, "积分" + GameUtils.count, Color.ORANGE, 50, 200, 120); GameUtils.drawWord(g, "难度" + GameUtils.level, Color.ORANGE, 50, 600, 120); GameUtils.drawWord(g, "等级" + fishLevel, Color.ORANGE, 50, 1000, 120); GameUtils.drawWord(g, "失败", Color.red, 80, 580, 450); break; case 3: GameUtils.drawWord(g, "积分" + GameUtils.count, Color.ORANGE, 50, 200, 120); GameUtils.drawWord(g, "难度" + GameUtils.level, Color.ORANGE, 50, 600, 120); GameUtils.drawWord(g, "等级" + fishLevel, Color.ORANGE, 50, 1000, 120); GameUtils.drawWord(g, "胜利了!", Color.ORANGE, 80, 580, 450); case 4: break; default: } } }

讯享网

(2)Enamy类

讯享网import java.awt.*; //敌方鱼父类 public class Enamy { //定义图片 Image img; //物体坐标 int x; int y; int width; int height; //移动速度 int speed; //方向 int dir = 1; //类型 int type; //分值 int count; //绘制自身方法 public void paintSelf(Graphics g) { g.drawImage(img, x, y, width, height, null); } //获取自身矩形,用于碰撞检测 public Rectangle getRec() { return new Rectangle(x, y, width - 45, height - 30); } } //敌方鱼左类 class Enamy_1_L extends Enamy { Enamy_1_L() { this.x = -45; this.y = (int) (Math.random() * 980); this.width = 40; this.height = 55; this.speed = 1; this.count = 1; this.type = 1; this.img = GameUtils.enamyl_1img; } @Override public Rectangle getRec() { return new Rectangle(x, y, width, height); } } //敌方鱼右类 class Enamy_1_R extends Enamy_1_L { Enamy_1_R() { this.x = 1400; dir = -1; this.img = GameUtils.enamyr_1img; } } class Enamy_2_L extends Enamy { Enamy_2_L() { this.x = -100; this.y = (int) (Math.random() * 900 + 100); this.width = 180; this.height = 80; this.speed = 5; this.count = 3; this.type = 2; this.img = GameUtils.enamyl_2img; } } class Enamy_2_R extends Enamy_2_L { Enamy_2_R() { this.x = 1400; dir = -1; this.img = GameUtils.enamyr_2img; } } class Enamy_3_L extends Enamy { Enamy_3_L() { this.x = -300; this.y = (int) (Math.random() * 980); this.width = 250; this.height = 150; this.speed = 3; this.count = 10; this.type = 3; this.img = GameUtils.enamyl_3img; } } class Enamy_3_R extends Enamy_3_L { Enamy_3_R() { this.x = 1400; dir = -1; this.img = GameUtils.enamyr_3img; } } class Enamy_Boss extends Enamy { Enamy_Boss() { this.x = -1200; this.y = (int) (Math.random() * 700 + 100); this.width = 250; this.height = 200; this.speed = 80; this.type = 10; this.img = GameUtils.bossimg; } }

(3)GameUtils类

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; //关卡等级 static int level = 0; //背景图 public static Image bgimg = Toolkit.getDefaultToolkit().createImage("src/images/sea.jpg"); //敌方鱼类集合 public static List<Enamy> EnamyList = new ArrayList<>(); //敌方鱼类 public static Image enamyl_1img = Toolkit.getDefaultToolkit().createImage("src/images/enemyFish/fish1_r.gif"); public static Image enamyr_1img = Toolkit.getDefaultToolkit().createImage("src/images/enemyFish/fish1_l.gif"); public static Image enamyl_2img = Toolkit.getDefaultToolkit().createImage("src/images/enemyFish/fish2_r.png"); public static Image enamyr_2img = Toolkit.getDefaultToolkit().createImage("src/images/enemyFish/fish2_l.png"); public static Image enamyl_3img = Toolkit.getDefaultToolkit().createImage("src/images/enemyFish/fish3_r.gif"); public static Image enamyr_3img = Toolkit.getDefaultToolkit().createImage("src/images/enemyFish/fish3_l.gif"); public static Image bossimg = Toolkit.getDefaultToolkit().createImage("src/images/enemyFish/boss.gif"); //我方鱼类 public static Image MyFishimg_L = Toolkit.getDefaultToolkit().createImage("src/images/myFish/myfish_left.gif"); public static Image MyFishimg_R = Toolkit.getDefaultToolkit().createImage("src/images/myFish/myfish_right.gif"); //绘制文字的工具类 public static void drawWord(Graphics g, String str, Color color, int size, int x, int y) { g.setColor(color); g.setFont(new Font("宋体", Font.BOLD, size)); g.drawString(str, x, y); } }

(4)GameWin类

讯享网package com.mzy; 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; public class GameWin extends JFrame { / * 游戏状态 0未开始,1游戏中,2通关失败,3通关成功,4暂停,5重新开始 */ //定义游戏默认状态 static int state = 0; //双缓存图片 Image offScreenImage; //窗口宽高 int width = 1320; int height = 780; //计数器 double random; int time = 0; //背景对象 Bg bg = new Bg(); //敌方鱼类 Enamy enamy = new Enamy_1_L(); //我方鱼类 MyFish myFish = new MyFish(); //boss鱼类 Enamy boss; //是否生成boss boolean isboss = false; / * 游戏操作方法 */ public void launch() { Music audioPlayWave = new Music("src/皇家萌卫.wav"); audioPlayWave.start(); @SuppressWarnings("unused") int musicOpenLab = 1; //界面布局 this.setVisible(true); this.setSize(width, height); this.setLocationRelativeTo(null); this.setTitle("大鱼吃小鱼"); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //开始或者失败后重新游戏 this.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { super.mouseClicked(e); if (e.getButton() == 1 && state == 0) { state = 1; repaint(); } if (e.getButton() == 1 && (state == 2 || state == 3)) { reGame(); state = 1; } } }); //键盘移动我方鱼类 this.addKeyListener(new KeyAdapter() { @Override //按压 public void keyPressed(KeyEvent e) { super.keyPressed(e); if (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; GameUtils.drawWord(getGraphics(), "游戏暂停!", Color.red, 50, 580, 450); break; case 4: state = 1; break; } } } @Override //抬起 public void keyReleased(KeyEvent 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(40); } catch (InterruptedException e) { e.printStackTrace(); } } } / * 游戏阶段绘制鱼类 */ @Override public void paint(Graphics g) { //双缓存加载图片 offScreenImage = createImage(width, height); Graphics gImage = offScreenImage.getGraphics(); bg.paintSelf(gImage, myFish.level); switch (state) { case 0: break; case 1: myFish.paintSelf(gImage); logic(); for (Enamy enamy : GameUtils.EnamyList) { enamy.paintSelf(gImage); } if (isboss) { boss.x = boss.x + boss.dir * boss.speed; boss.paintSelf(gImage); if (boss.x < 0) { gImage.setColor(Color.red); gImage.fillRect(boss.x, boss.y + 100, 2400, boss.height / 20); } } break; case 2: for (Enamy enamy : GameUtils.EnamyList) { enamy.paintSelf(gImage); } if (isboss) { boss.paintSelf(gImage); } break; case 3: myFish.paintSelf(gImage); break; case 4: return; default: } g.drawImage(offScreenImage, 0, 0, null); } / * 游戏关卡难度逻辑 */ void logic() { //关卡难度 if (GameUtils.count < 5) { GameUtils.level = 0; } else if (GameUtils.count < 15) { GameUtils.level = 1; } else if (GameUtils.count < 40) { GameUtils.level = 2; } else if (GameUtils.count < 75) { GameUtils.level = 3; } else if (GameUtils.count > 150) { state = 3; } //我方鱼升级 if (29 < GameUtils.count && GameUtils.count < 79) { myFish.level = 2; } else if (GameUtils.count > 79) { myFish.level = 3; } //阶段生成敌方鱼 random = Math.random(); switch (GameUtils.level) { case 3: if (time % 120 == 0) { boss = new Enamy_Boss(); isboss = true; } case 2: if (time % 120 == 0) { if (random < 0.5) { enamy = new Enamy_3_L(); } else { enamy = new Enamy_3_R(); } } GameUtils.EnamyList.add(enamy); case 1: if (time % 60 == 0) { if (random < 0.5) { enamy = new Enamy_2_L(); } else { enamy = new Enamy_2_R(); } } GameUtils.EnamyList.add(enamy); case 0: if (time % 10 == 0) { if (random < 0.5) { enamy = new Enamy_1_L(); } else { enamy = new Enamy_1_R(); } } GameUtils.EnamyList.add(enamy); break; default: } //生成敌方鱼 for (Enamy enamy : GameUtils.EnamyList) { enamy.x = enamy.x + enamy.dir * enamy.speed; //boss鱼碰撞检测 if (isboss) { if (boss.getRec().intersects(enamy.getRec())) { enamy.x = -200; enamy.y = -200; } if (boss.getRec().intersects(myFish.getRec())) { state = 2; } } //我方鱼与敌方鱼碰撞检测 if (myFish.getRec().intersects(enamy.getRec())) { if (myFish.level >= enamy.type) { enamy.x = -200; enamy.y = -200; GameUtils.count += enamy.count; } else { state = 2; } } } } public static void main(String[] args) { GameWin gameWin = new GameWin(); gameWin.launch(); } //重新开始 void reGame() { GameUtils.EnamyList.clear(); time = 0; myFish.level = 1; GameUtils.count = 0; myFish.x = 650; myFish.y = 400; myFish.width = 45; myFish.height = 45; boss = null; isboss = false; } } 

(5)Music类

package com.mzy; import java.io.File; import java.io.IOException; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.FloatControl; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; import javax.sound.sampled.UnsupportedAudioFileException; public class Music extends Thread { private String fileName; private final int EXTERNAL_BUFFER_SIZE = ; public Music(String wavFile) { this.fileName = wavFile; } @SuppressWarnings("unused") public void run() { System.out.println("音乐播放"); File soundFile = new File(fileName); // 播放音乐的文件名 if (!soundFile.exists()) { System.err.println("Wave file not found:" + fileName); return; } while (true) { // 设置循环播放 AudioInputStream audioInputStream = null; // 创建音频输入流对象 try { audioInputStream = AudioSystem.getAudioInputStream(soundFile); // 创建音频对象 } catch (UnsupportedAudioFileException e1) { e1.printStackTrace(); return; } catch (IOException e1) { e1.printStackTrace(); return; } AudioFormat format = audioInputStream.getFormat(); // 音频格式 SourceDataLine auline = null; // 源数据线 DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); try { auline = (SourceDataLine) AudioSystem.getLine(info); auline.open(format); } catch (LineUnavailableException e) { e.printStackTrace(); return; } catch (Exception e) { e.printStackTrace(); return; } if (auline.isControlSupported(FloatControl.Type.PAN)) { FloatControl pan = (FloatControl) auline.getControl(FloatControl.Type.PAN); } auline.start(); int nBytesRead = 0; byte[] abData = new byte[EXTERNAL_BUFFER_SIZE]; try { while (nBytesRead != -1) { nBytesRead = audioInputStream.read(abData, 0, abData.length); if (nBytesRead >= 0) auline.write(abData, 0, nBytesRead); } } catch (IOException e) { e.printStackTrace(); return; } finally { auline.drain(); // auline.close(); } } } }

(6)MyFish类

讯享网import java.awt.*; public class MyFish { //图片 Image img = GameUtils.MyFishimg_L; //坐标 int x = 650; int y = 400; int width = 45; int height = 45; //移动速度 int speed = 20; //等级 int level = 1; //移动 void logic() { if (GameUtils.UP) { y = y - speed; } if (GameUtils.DOWN) { y = y + speed; } if (GameUtils.LEFT) { x = x - speed; img = GameUtils.MyFishimg_L; } if (GameUtils.RIGHT) { x = x + speed; img = GameUtils.MyFishimg_R; } } //绘制自身方法 public void paintSelf(Graphics g) { logic(); g.drawImage(img, x, y, width + GameUtils.count, height + GameUtils.count, null); } //获取自身矩形方法,用于碰撞检测 public Rectangle getRec() { return new Rectangle(x, y, width + GameUtils.count, height + GameUtils.count); } }

结束语:

游戏还有很多缺陷地方,比如我方鱼可以离开界面,敌方鱼在离开界面后没有及时清除,游戏玩法过于简单。都需要小伙伴们自己去改进,挖掘。

游戏源码下载解压后,注意打开项目的文件夹位置,出现报错,游戏界面白屏等问题,都可以私信帮忙解决。

源码:

小讯
上一篇 2025-01-24 22:53
下一篇 2025-02-23 18:31

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/30030.html