Java《大鱼吃小鱼》游戏思路及实现(含源码)

本游戏代码参考【尚学堂】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;向左为-1
    int 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() {
            @Override
            public void keyPressed(KeyEvent e) {
                //super.keyPressed(e);
                //WASD控制移动  W 86  S 83  A 65  D
                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;
                            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() {
            @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)){
                    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;向左为-1
    int 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<Plane> PlaneList = new ArrayList<>();

    public static List<Bomb> BombList = new ArrayList<>();
    public static List<Explode6> 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() {
            @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)){
                    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() {
            @Override
            public void keyPressed(KeyEvent e) {
                //super.keyPressed(e);
                //WASD控制移动  W 86  S 83  A 65  D
                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;
                            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);
            }
        }
    }

    @Override
    public 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();
        }
    }
}






文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
扎眼的阳光的头像扎眼的阳光普通用户
上一篇 2023年12月8日
下一篇 2023年12月8日

相关推荐