赞
踩
游戏参考于B站_【尚学堂】大鱼吃小鱼,主体框架不变,代码稍有改动。
大鱼吃小鱼:又称吞食鱼,是一款动作类小游戏。通过不断的吞吃比自己小的鱼类快速成长,最终成为海洋霸主。
游戏主要Java知识:变量、数据类型、判断语句、循环结构、类的继承、简单窗口创建、图形图片绘制、双缓存技术、鼠标事件、键盘事件。
非常适合在同学Java学习结束后,作为不错的结课作业或者练手项目。
源码已经在文章结束语后打包,有兴趣的同学可以免费下载,创作不易,点个免费的赞支持一下!
运行环境:jdk-17.05
操作方法:w,s,a,d (英文输入法)控制小鱼方向
- 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:
- }
- }
- }
- 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;
- }
- }
- 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);
- }
- }
- 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;
- }
-
- }
- 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 = 524288;
-
- 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();
- }
- }
- }
- }
- 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);
- }
- }
游戏还有很多缺陷地方,比如我方鱼可以离开界面,敌方鱼在离开界面后没有及时清除,游戏玩法过于简单。都需要小伙伴们自己去改进,挖掘。
游戏源码下载解压后,注意打开项目的文件夹位置,出现报错,游戏界面白屏等问题,都可以私信帮忙解决。
源码:
链接:https://pan.baidu.com/s/1QyuhE1KaM_RupqLpUkr1JA
提取码:2czk
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。