zoukankan      html  css  js  c++  java
  • Java Swing 实现300行捕鱼达人游戏

    package org.wf.game.fish;
    
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.Random;
    
    import javax.imageio.ImageIO;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class FishGame {
    
        public static void main(String[] args) {
            //游戏画框
            JFrame jf = new JFrame("疯狂捕鱼");
            jf.setSize(800, 480);
            jf.setLocationRelativeTo(null);
            jf.setResizable(false);
            jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            jf.setAlwaysOnTop(true);
            //加载鱼池
            Pool pool = new Pool();
            jf.add(pool);
            //显示框架
            jf.setVisible(true);
            pool.action();
        }
    }
    
    //鱼池类
    class Pool extends JPanel {
        private static final long serialVersionUID = 1L;
        BufferedImage bgImage;    //背景图片
        Fish[] fishs = new Fish[20];    //所有的鱼
        Net net = new Net();    //渔网
        boolean isExit;    //鼠标是否在游戏界面
        int score, bullet = 50;    //游戏得分,子弹数
    
        public Pool() {
            super();
            File bg = new File("images/bg.jpg");
            try {
                bgImage = ImageIO.read(bg);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //0-8,9-17对应1-9号鱼
            for (int i = 0; i < fishs.length / 2 - 1; i++) {
                fishs[i] = new Fish(i + 1);
                fishs[i + 9] = new Fish(i + 1);
            }
            fishs[18] = new Fish(10);
            fishs[19] = new Fish(11);
        }
    
        //画游戏元素
        @Override
        public void paint(Graphics g) {
            g.drawImage(bgImage, 0, 0, null);    //画背景
            for (Fish fish : fishs) {
                g.drawImage(fish.fishImage, fish.fish_x, fish.fish_y, null);    //画鱼
            }
            if (!isExit) {
                g.drawImage(net.netImage, net.netX, net.netY, null);    //画网
            }
    
            //画游戏说明文字
            g.setColor(Color.GREEN);
            g.setFont(new Font("楷体", Font.ITALIC, 20));
            g.drawString("疯狂捕鱼V1.0 By~Synchronized", 10, 25);
            g.drawString("子弹数:" + bullet + "   得分:" + score, 350, 25);
            g.drawString("右键切换渔网  VIP:" + (net.power % 7 + 1), 590, 25);
            if (bullet <= 0) {
                g.setColor(Color.RED);
                g.setFont(new Font("楷体", Font.BOLD, 100));
                g.drawString("Game Over", 150, 250);
                bullet = 0;
                isExit = true;
                net.power = -1;
            }
        }
    
        //游戏启动方法
        public void action() {
            for (Fish fish : fishs) {
                fish.start();
            }
            //鼠标监听器
            MouseAdapter adapter = new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    int event = e.getModifiers();
                    if (event == 4) {
                        net.change();    //切换网大小
                        super.mousePressed(e);
                    } else if (event == 16) {
                        //减子弹
                        if (bullet - (net.power % 7 + 1) <= 0) {
                            bullet = 0;
                        } else {
                            bullet -= (net.power % 7 + 1);
                        }
    
                        //捕鱼
                        for (Fish fish : fishs) {
                            if (!fish.catched) {
                                catchFish(fish);
                            }
                        }
                    }
                }
    
                @Override
                public void mouseMoved(MouseEvent e) {
                    net.moveTo(e.getX(), e.getY());
                    super.mouseMoved(e);
                }
    
                @Override
                public void mouseEntered(MouseEvent e) {
                    isExit = false;
                    super.mouseEntered(e);
                }
    
                @Override
                public void mouseExited(MouseEvent e) {
                    isExit = true;
                    super.mouseExited(e);
                }
            };
            this.addMouseListener(adapter);
            this.addMouseMotionListener(adapter);
            while (true) {
                repaint();
            }
        }
    
        //封装捕鱼的方法
        public void catchFish(Fish fish) {
            fish.catched = net.catchFish(fish);
            if (fish.catched) {
                score += 2 * fish.k;
                bullet += 2 * fish.k;
            }
        }
    }
    
    //鱼类
    class Fish extends Thread {
        int fish_x, fish_y;    //鱼的坐标
        BufferedImage fishImage;    //鱼的图片
        BufferedImage[] fishImages = new BufferedImage[10];    //鱼动作的图片
        BufferedImage[] catchImages;    //鱼的被捕的图片
        int fish_width, fish_height;    //鱼的宽高
        Random r = new Random();    //鱼y坐标的随机数
        int blood;    //鱼的血量值
        boolean catched;    //鱼是否被捕
        int k, step_size;    //鱼的血量等级,移动速度
    
        public Fish(int m) {
            super();
            String preName = m > 9 ? m + "" : "0" + m;
            //通过for循环读取鱼动作图片数组
            for (int i = 0; i < fishImages.length; i++) {
                int j = i + 1;
                String lastName = j > 9 ? "10" : "0" + j;
                File file = new File("images/fish" + preName + "_" + lastName + ".png");
                try {
                    fishImages[i] = ImageIO.read(file);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            fishImage = fishImages[0];
            fish_width = this.fishImage.getWidth();
            fish_height = this.fishImage.getHeight();
            fish_x = 800;
            fish_y = r.nextInt(450 - fish_height);
            blood = m * 3;
            this.k = m;
            step_size = r.nextInt(5) + 1;
            //初始化catchImages
            if (m > 7) {
                catchImages = new BufferedImage[4];
            } else if (m <= 7) {
                catchImages = new BufferedImage[2];
            }
            //通过for循环读取鱼被捕图片数组
            for (int i = 1; i <= catchImages.length; i++) {
                File file = new File("images/fish" + preName + "_catch_0" + i + ".png");
                try {
                    catchImages[i - 1] = ImageIO.read(file);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        //鱼移动的方法
        public void move() {
            fish_x -= step_size;
        }
    
        @Override
        public void run() {
            super.run();
            while (true) {
                move();    //调用鱼移动的方法
                //如果鱼出界,重新生成
                if (fish_x < -fish_width || catched) {
                    turnOut();    //鱼被捕,颤动
                    newFish();
                }
                change();    //调用鱼摇摆游动的方法
                try {
                    Thread.sleep(15);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        //重新生成一条鱼
        public void newFish() {
            fish_x = 800;
            fish_y = r.nextInt(450 - fish_height);
            if (fish_y >= 450) {
                // System.out.println(fish_height + "  " + fish_y);
            }
            catched = false;
            blood = k * 3;
            step_size = r.nextInt(5) + 1;
        }
    
        // 鱼摇摆游动的方法
        int index = 0;
    
        public void change() {
            index++;
            fishImage = fishImages[index / 3 % 10];
        }
    
        //鱼被捕动画的方法
        public void turnOut() {
            for (int i = 0; i < catchImages.length; i++) {
                fishImage = catchImages[i];
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    //渔网类
    class Net {
        int netX, netY;//网的坐标
        int netWidth, netHeight;//网的宽高
        BufferedImage netImage;//网的图片
    
        public Net() {
            super();
            File file = new File("images/net_" + 1 + ".png");
            try {
                netImage = ImageIO.read(file);
            } catch (IOException e) {
                e.printStackTrace();
            }
            netX = 300;
            netY = 300;
            netWidth = netImage.getWidth();
            netHeight = netImage.getHeight();
        }
    
        // 鱼网切换的方法
        int power = 0;
    
        public void change() {
            power++;
            int x = this.netX + this.netWidth / 2;
            int y = this.netY + this.netHeight / 2;
            File file = new File("images/net_" + (power % 7 + 1) + ".png");
            try {
                netImage = ImageIO.read(file);
            } catch (IOException e) {
                e.printStackTrace();
            }
            this.netWidth = netImage.getWidth();
            this.netHeight = netImage.getHeight();
            moveTo(x, y);
        }
    
        //渔网移动的方法
        public void moveTo(int x, int y) {
            this.netX = x - this.netWidth / 2;
            this.netY = y - this.netHeight / 2;
        }
    
        //捕鱼
        public boolean catchFish(Fish fish) {
            //网的中心坐标
            int zX = netX + netWidth / 2;
            int zY = netY + netHeight / 2;
            //鱼的身体部分中心坐标
            int fX = fish.fish_x + fish.fish_width * 2 / 3;
            int fY = fish.fish_y + fish.fish_height / 2;
            //如果网的中心坐标在鱼的身体部分
            if (zX > fish.fish_x && zX < fish.fish_x + fish.fish_width * 2 / 3
                    && zY > fish.fish_y && zY < fish.fish_y + fish.fish_height) {
                fish.blood -= ((power % 7 + 1) * 2);
                // System.out.println(fish.blood);
            } else if (fX > netX && fX < netX + netWidth
                    && fY > netY && fY < netY + netHeight) {
                //如果鱼的身体部分中心坐标在网里
                fish.blood -= ((power % 7 + 1) * 2);
                // System.out.println(fish.blood);
            }
            return fish.blood <= 0;
        }
    }
  • 相关阅读:
    [转载]浅谈多态机制的意义及实现
    [转载]浅析Java虚拟机结构与机制
    为什么调用 FragmentPagerAdapter.notifyDataSetChanged() 并不能更新其 Fragment?
    Android-- FragmentStatePagerAdapter分页
    android-点击空白或点击除EditText之外的控件隐藏软键盘
    populating-next-right-pointers-in-each-node
    roman-to-integer
    same-tree
    palindrome-number
    best-time-to-buy-and-sell-stock
  • 原文地址:https://www.cnblogs.com/dgwblog/p/14023853.html
Copyright © 2011-2022 走看看