首页 > 编程语言 >黄金矿工小游戏(Java)

黄金矿工小游戏(Java)

时间:2025-01-20 12:57:54浏览次数:3  
标签:Bg Java int Color 小游戏 obj new 黄金矿工 public

        在游戏开发的世界里,用代码构建一个充满趣味的游戏是一次极具挑战与收获的旅程。今天,我将带大家深入了解我用 Java 开发的 “黄金矿工” 游戏背后的代码逻辑和实现细节,一同领略编程与游戏结合的魅力。

一、引言

        这款 “黄金矿工” 游戏拥有经典的玩法,玩家通过操控钩子抓取屏幕中的各种物体,包括黄金、石头和炸弹等,目标是在规定时间内达到一定的积分以进入下一关。同时,游戏还配备了登录注册系统,确保玩家数据的记录和管理,为游戏增添了一份完整性和个性化体验。

        以回忆经典游戏 “黄金矿工” 引入,提到这款游戏曾经带给我们的欢乐和挑战,然后引出自己通过代码实现这款游戏的经历,激发读者兴趣。

二、登录注册模块

        登录注册模块是玩家进入游戏的门户,其界面设计和功能实现都经过精心构思。基本代码如下:

import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.sql.*;
public class LoginFrame extends JFrame {
    JTextField usernameField;
    private JPasswordField passwordField;

    public LoginFrame() {
        createUI();
    }

    private void createUI() {
        setTitle("登录界面");
        setSize(400, 250);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new GridBagLayout());
        GridBagConstraints gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
        gridBagConstraints.insets = new Insets(10, 10, 10, 10);

        JLabel background = new JLabel(new ImageIcon("imgs/LogBg.png"));
        background.setLayout(null);
        setContentPane(background);

        Font customFont = loadCustomFont("Fonts/Uranus_Pixel_11Px.ttf");

        JLabel usernameLabel = new JLabel("用户名:");
        usernameLabel.setHorizontalAlignment(JLabel.RIGHT);
        usernameLabel.setFont(customFont);
        usernameLabel.setBounds(30, 50, 80, 25);
        usernameLabel.setBackground(new Color(0, 0, 139));
        background.add(usernameLabel);

        usernameField = new JTextField(20);
        usernameField.setBounds(120, 50, 180, 25);
        background.add(usernameField);

        JLabel passwordLabel = new JLabel("密码:");
        passwordLabel.setHorizontalAlignment(JLabel.RIGHT);
        passwordLabel.setFont(customFont);
        passwordLabel.setBounds(30, 100, 80, 25);
        background.add(passwordLabel);

        passwordField = new JPasswordField(20);
        passwordField.setBounds(120, 100, 180, 25);
        background.add(passwordField);

        JButton loginButton = new JButton("登录");
        loginButton.setBounds(120, 150, 80, 25);
        background.add(loginButton);
        loginButton.addActionListener(e -> login());
        loginButton.setFont(customFont);
        loginButton.setBackground(new Color(238, 246, 140, 255));
        loginButton.setForeground(Color.black);
        loginButton.setBorder(createRoundedBorder(0, new Color(0, 120, 215), new Color(255, 255, 255)));
        loginButton.setFocusPainted(false);

        JButton registerButton = new JButton("注册");
        registerButton.setBounds(220, 150, 80, 25);
        background.add(registerButton);
        registerButton.addActionListener(e -> register());
        registerButton.setFont(customFont);
        registerButton.setBackground(new Color(238, 246, 140, 255));
        registerButton.setForeground(Color.black);
        registerButton.setBorder(createRoundedBorder(0, new Color(0, 120, 215), new Color(255, 255, 255)));
        registerButton.setFocusPainted(false);

        JButton closeButton = new JButton();
        closeButton.setIcon(new ImageIcon("imgs/close.png"));
        closeButton.setBounds(380, 5, 15, 15);
        background.add(closeButton);
        closeButton.addActionListener(e -> System.exit(0));
        closeButton.setBackground(new Color(220, 20, 60, 116));
        closeButton.setForeground(Color.WHITE);
        closeButton.setBorder(BorderFactory.createLineBorder(Color.GRAY));

        getRootPane().setWindowDecorationStyle(JRootPane.NONE);
        setUndecorated(true);

        Timer timer = new Timer(10, null);
        timer.addActionListener(e -> {
            if (getOpacity() < 1.0) {
                setOpacity((float) (getOpacity() + 0.1));
            } else {
                timer.stop();
            }
        });
        timer.start();

        setVisible(true);
    }

    private Border createRoundedBorder(int radius, Color borderColor, Color backgroundColor) {
        return new Border() {
            @Override
            public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setColor(borderColor);
                g2d.drawRoundRect(x, y, width - 1, height - 1, radius, radius);
                g2d.dispose();
            }

            @Override
            public Insets getBorderInsets(Component c) {
                return new Insets(radius, radius, radius, radius);
            }

            @Override
            public boolean isBorderOpaque() {
                return true;
            }
        };
    }

    void login() {
        String username = usernameField.getText();
        String password = new String(passwordField.getPassword());

        if (checkLogin(username, password)) {
            JOptionPane.showMessageDialog(this, "登录成功!");
            dispose();
            callAfterLogin();
            new Thread(() -> {
                MusicPlayer player = new MusicPlayer();
                try {
                    player.playBgMusic("sounds/background.mp3");
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }).start();
        } else {
            JOptionPane.showMessageDialog(this, "登录失败,请检查用户名和密码!", "错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    private boolean checkLogin(String username, String password) {
        String DB_URL = "jdbc:sqlserver://localhost:1433;DatabaseName=text;encrypt=true;trustServerCertificate=true;";
        String USER = "sa";
        String PASS = "1";

        try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT * FROM info WHERE username='" + username + "' AND password='" + password + "'")) {

            if (rs.next()) {
                return true;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return false;
    }

    private void callAfterLogin() {
        new Thread(() -> {
            new GameWin().launch();
        }).start();
    }

    private void register() {
        String username = usernameField.getText();
        String password = new String(passwordField.getPassword());

        if (username.isEmpty() || password.isEmpty()) {
            JOptionPane.showMessageDialog(this, "用户名和密码不能为空!", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }

        String DB_URL = "jdbc:sqlserver://localhost:1433;DatabaseName=text;encrypt=true;trustServerCertificate=true;";
        String USER = "sa";
        String PASS = "1";

        try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
             Statement stmt = conn.createStatement()) {

            String sql = "INSERT INTO info (username, password) VALUES ('" + username + "', '" + password + "')";
            int result = stmt.executeUpdate(sql);
            if (result > 0) {
                JOptionPane.showMessageDialog(this, "注册成功!");
            } else {
                JOptionPane.showMessageDialog(this, "注册失败,请重试。", "错误", JOptionPane.ERROR_MESSAGE);
            }
        } catch (SQLException e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(this, "数据库连接失败,请检查配置。", "错误", JOptionPane.ERROR_MESSAGE);
        }
    }
    static Font loadCustomFont(String fontPath) {
        try {
            Font customFont = Font.createFont(Font.TRUETYPE_FONT, new java.io.File(fontPath));
            customFont = customFont.deriveFont(Font.PLAIN, 16f);
            GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(customFont);
            return customFont;
        } catch (Exception e) {
            e.printStackTrace();
            return new Font("SansSerif", Font.PLAIN, 16);
        }
    }

    public static void main(String[] args) {
        new LoginFrame();
    }

}

        在这段代码中,LoginFrame 类负责构建登录界面,通过 GridBagLayout 和自定义布局设置,将背景图片、标签、文本框、按钮等组件合理地放置在界面上,营造出美观且易用的登录环境。createRoundedBorder 方法创建了独特的圆形边框样式,为按钮增添了一份精致感。登录和注册功能分别通过 login 和 register 方法实现,它们与数据库进行交互,验证登录信息或插入新用户数据,确保用户认证的准确性和安全性。

三、游戏主界面与核心玩法

1.背景绘制

import java.awt.*;

public class Bg {
    static int level = 1;
    int goal = level * 15;
    static int count = 0;
    static int waterNum = 3;
    static boolean waterFlag = false;
    long startTime;
    long endTime;
    int price = (int) (Math.random() * 10);
    boolean shop = false;
    Image bg = Toolkit.getDefaultToolkit().getImage("imgs/bg.png");
    Image bg2 = Toolkit.getDefaultToolkit().getImage("imgs/Bg2.png");
    Image peo = Toolkit.getDefaultToolkit().getImage("imgs/peo.png");
    Image water = Toolkit.getDefaultToolkit().getImage("imgs/water.png");
    Image victory = Toolkit.getDefaultToolkit().getImage("imgs/victory.png");
    Image failed = Toolkit.getDefaultToolkit().getImage("imgs/failed.png");

    void paintSelf(Graphics g) {
        Image curBg = (GameWin.state % 2 == 1 ? bg : bg2);
        g.drawImage(curBg, 0, 0, null);

        switch (GameWin.state) {
            case 0:
                Bg.drawWord(g, 40, Color.BLACK, "单击右键", 260, 360);
                Bg.drawWord(g, 80, Color.black, "开始游戏", 200, 460);
                break;
            case 1:
                g.drawImage(peo, 310, 65, null);
                Bg.drawWord(g, 30, Color.black, "积分:" + count, 30, 150);
                g.drawImage(water, 450, 40, null);
                Bg.drawWord(g, 30, Color.black, "*" + waterNum, 510, 70);
                Bg.drawWord(g, 20, Color.black, "第" + level + "关", 30, 60);
                Bg.drawWord(g, 30, Color.black, "目标" + goal, 30, 110);
                endTime = System.currentTimeMillis();
                long tim = 20 - (endTime - startTime) / 1000;
                Bg.drawWord(g, 30, Color.black, "时间:" + (tim > 0 ? tim : 0), 520, 150);
                break;
            case 2:
                g.drawImage(water, 300, 400, null);
                Bg.drawWord(g, 30, Color.black, "价格:" + price, 300, 500);
                Bg.drawWord(g, 30, Color.black, "是否购买?", 300, 550);
                if (shop) {
                    count = count - price;
                    waterNum++;
                    shop = false;
                    GameWin.state = 1;
                    startTime = System.currentTimeMillis();
                }
                break;
            case 3:
                g.drawImage(failed, 210, 220, null);
                Bg.drawWord(g, 70, Color.red, "积分:" + count, 260, 420);
                Bg.drawWord(g, 40, Color.orange, "单击左键重新开始游戏", 160, 480);
                break;
            case 4:
                g.drawImage(victory, 190, 220, null);
                Bg.drawWord(g, 40, Color.red, "您获得的积分为:" + count, 200, 420);
                Bg.drawWord(g, 30, Color.black, "单击左键重新开始游戏", 220, 480);
                break;
        }
    }

    boolean gameTime() {
        long tim = (endTime - startTime) / 1000;
        return tim > 20;
    }

    void reGame() {
        level = 1;
        goal = level * 15;
        count = 0;
        waterNum = 3;
        waterFlag = false;
    }

    public static void drawWord(Graphics g, int size, Color color, String str, int x, int y) {
        g.setColor(color);
        g.setFont(new Font("Uranus_Pixel_11Px", Font.PLAIN, size));
        g.drawString(str, x, y);
    }
}

2.游戏逻辑

描述游戏的基本逻辑,包括如何使用Swing组件来绘制游戏界面,以及如何处理用户交互

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

public class GameWin extends JFrame {
    static int state;
    List<Object> objectList = new ArrayList<>();
    Bg bg = new Bg();
    Line line = new Line(this);

    {
        boolean isPlace = true;
        for (int i = 0; i < 11; i++) {
            double random = Math.random();
            Gold gold;
            if (random < 0.3) {
                gold = new GoldMini();
            } else if (random < 0.7) {
                gold = new Gold();
            } else {
                gold = new GoldPlus();
            }

            for (Object obj : objectList) {
                if (gold.getRec().intersects(obj.getRec())) {
                    isPlace = false;
                }
            }
            if (isPlace) {
                objectList.add(gold);
            } else {
                isPlace = true;
                i--;
            }
        }
        for (int i = 0; i < 5; i++) {
            Rock rock = new Rock();
            for (Object obj : objectList) {
                if (rock.getRec().intersects(obj.getRec())) {
                    isPlace = false;
                }
            }
            if (isPlace) {
                objectList.add(rock);
            } else {
                isPlace = true;
                i--;
            }
        }
        for (int i = 0; i < 2; i++) {
            Bomb bomb = new Bomb();
            isPlace = true;
            for (Object obj : objectList) {
                if (bomb.getRec().intersects(obj.getRec())) {
                    isPlace = false;
                }
            }
            if (isPlace) {
                objectList.add(bomb);
            }
            else {
                i--;
            }
        }
    }

    Image offScreenImage;

    public void launch() {
        setTitle("黄金矿工");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(768, 1000);
        setLocationRelativeTo(null);

        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                switch (state) {
                    case 0:
                        if (e.getButton() == 3) {
                            state = 1;
                            bg.startTime = System.currentTimeMillis();
                        }
                        break;
                    case 1:
                        if (e.getButton() == 1 && line.state == 0) {
                            line.state = 1;
                        }
                        if (e.getButton() == 3 && line.state == 3 && Bg.waterNum > 0) {
                            Bg.waterFlag = true;
                            Bg.waterNum--;
                            new Thread(() -> {
                                MusicPlayer player = new MusicPlayer();
                                try {
                                    player.playMusic("sounds/water.mp3");
                                } catch (InterruptedException a) {
                                    throw new RuntimeException(a);
                                }
                            }).start();
                        }
                        break;
                    case 2:
                        if (e.getButton() == 1) {
                            bg.shop = true;
                        }
                        if (e.getButton() == 3) {
                            state = 1;
                            bg.startTime = System.currentTimeMillis();
                        }
                        break;
                    case 3:
                    case 4:
                        if (e.getButton() == 1) {
                            state = 0;
                            bg.reGame();
                            line.reGame();
                        }
                        break;
                }
            }
        });

        setVisible(true);

        while (true) {
            repaint();
            nextLevel();
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void nextLevel() {
        if (bg.gameTime() && state == 1) {
            if (Bg.count >= bg.goal) {
                if (Bg.level == 5) {
                    state = 4;
                    new Thread(() -> {
                        MusicPlayer player = new MusicPlayer();
                        try {
                            player.playMusic("sounds/victory.mp3");
                        } catch (InterruptedException a) {
                            throw new RuntimeException(a);
                        }
                    }).start();
                } else {
                    state = 2;
                    Bg.level++;
                }
            } else {
                state = 3;
                new Thread(() -> {
                    MusicPlayer player = new MusicPlayer();
                    try {
                        player.playMusic("sounds/fail.mp3");
                    } catch (InterruptedException a) {
                        throw new RuntimeException(a);
                    }
                }).start();
            }
            dispose();
            GameWin gameWin1 = new GameWin();
            gameWin1.launch();
        }
    }

    @Override
    public void paint(Graphics g) {
        offScreenImage = this.createImage(768, 1000);
        Graphics gImage = offScreenImage.getGraphics();

        bg.paintSelf(gImage);

        if (line.currentExplosion!= null) {
            line.currentExplosion.update();
            if (!line.currentExplosion.isActive()) {
                line.currentExplosion = null;  // 释放爆炸实例,等待下次触发新的爆炸
            }
        }

        if (state == 1) {
            for (Object obj : objectList) {
                obj.paintSelf(gImage);
            }

            line.paintSelf(gImage);
        }
        g.drawImage(offScreenImage, 0, 0, null);
    }
}

        在 GameWin 类中,首先通过一系列随机算法初始化游戏中的物体列表,确保各种物体在屏幕上的分布合理且不重叠。launch 方法设置了游戏窗口的基本属性,并添加了鼠标点击事件监听器,根据游戏的不同状态(如准备阶段、游戏进行阶段、商店阶段、胜利或失败阶段)处理玩家的鼠标操作,例如点击右键开始游戏、点击左键发射钩子、使用道具等。nextLevel 方法实时检查游戏时间和得分情况,判断是否进入下一关、胜利或失败,并进行相应的界面切换和音乐播放。paint 方法则负责绘制游戏画面,通过双缓冲技术(使用 offScreenImage)先在后台绘制所有元素,然后一次性将完整画面绘制到屏幕上,提高了画面的绘制效率和流畅性。

2.游戏对象和碰撞检测

        介绍游戏中的对象(如金块、岩石、炸药桶)以及如何实现它们之间的碰撞检测

import java.awt.*;

public class Object {
    int x;
    int y;
    int width;
    int height;
    Image img;
    boolean flag;
    int m;
    int count;
    int type;
    boolean isBomb = false;
    int bombRadius;

    void paintSelf(Graphics g) {
        g.drawImage(img, x, y, null);
    }

    public int getWidth() {
        return width;
    }

    public Rectangle getRec() {
        return new Rectangle(x, y, width, height);
    }

    public int getBombRadius() {
        return bombRadius;
    }
}

        介绍炸药桶对象

import java.awt.*;

public class Bomb extends Object {
    Bomb() {
        this.x = (int) (Math.random() * 700);
        this.y = (int) (Math.random() * 550 + 300);
        this.width = 123;
        this.height = 133;
        this.flag = false;
        this.m = 30;
        this.count = 0;
        this.type = 3;
        this.img = Toolkit.getDefaultToolkit().getImage("imgs/炸药桶.png");
        this.isBomb = true;
        this.bombRadius = 50;
    }

}

        介绍金块对象

import java.awt.*;

public class Gold extends Object {
    Gold() {
        this.x = (int) (Math.random() * 700);
        this.y = (int) (Math.random() * 520 + 400);
        this.width = 52;
        this.height = 52;
        this.flag = false;
        this.m = 30;
        this.count = 4;
        this.type = 1;
        this.img = Toolkit.getDefaultToolkit().getImage("imgs/gold1.gif");
    }
}
import java.awt.*;

public class GoldMini extends Gold {
    GoldMini() {
        this.width = 36;
        this.height = 36;
        this.m = 15;
        this.count = 2;
        this.img = Toolkit.getDefaultToolkit().getImage("imgs/gold0.gif");
    }
}
import java.awt.*;

public class GoldPlus extends Gold {
    GoldPlus() {
        this.x = (int) (Math.random() * 650);
        this.width = 105;
        this.height = 105;
        this.m = 60;
        this.count = 8;
        this.img = Toolkit.getDefaultToolkit().getImage("imgs/gold2.gif");
    }
}

        介绍岩石对象

import java.awt.*;

public class Rock extends Object {
    Rock() {
        this.x = (int) (Math.random() * 700);
        this.y = (int) (Math.random() * 560 + 365);
        this.width = 71;
        this.height = 71;
        this.flag = false;
        this.m = 50;
        this.count = 1;
        this.type = 2;
        this.img = Toolkit.getDefaultToolkit().getImage("imgs/rock1.png");
    }
}

        介绍线对象

import java.awt.*;

public class Line {
    int x = 380;
    int y = 180;
    int endx = 500;
    int endy = 500;
    double length = 100;
    double MIN_length = 100;
    double MAX_length = 750;
    double n = 0;
    int dir = 1;
    int state;
    Image hook = Toolkit.getDefaultToolkit().getImage("imgs/hook.png");
    GameWin frame;

    Line(GameWin frame) {
        this.frame = frame;
    }
    Explosion currentExplosion;
    void logic() {
        for (Object obj : this.frame.objectList) {
            if (endx > obj.x && endx < obj.x + obj.width && endy > obj.y && endy < obj.y + obj.height) {
                state = 3;
                obj.flag = true;
                if (obj.isBomb) {
                    explode(obj);
                    new Thread(() -> {
                        MusicPlayer player = new MusicPlayer();
                        try {
                            player.playMusic("sounds/boom.mp3");
                        } catch (InterruptedException a) {
                            throw new RuntimeException(a);
                        }
                    }).start();
                }
            }
        }
    }
    void explode(Object bomb) {
        int totalFrames = 30; // 假设爆炸动画总帧数为30
        Image explosionImg = Toolkit.getDefaultToolkit().getImage("imgs/boom.gif");
        currentExplosion = new Explosion(explosionImg, bomb.x, bomb.y, bomb.bombRadius, totalFrames);
        bomb.img =null; // 更换图片为爆炸效果
        for (Object obj : this.frame.objectList) {
            if (obj != bomb && obj.getRec().intersects(new Rectangle(bomb.x - bomb.bombRadius, bomb.y - bomb.bombRadius,
                    bomb.width + 2 * bomb.bombRadius, bomb.height + 2 * bomb.bombRadius))) {
                obj.x = -150; // 将物体移出屏幕
                obj.y = -150;
                obj.flag = false;
            }
        }
    }
    void lines(Graphics g) {
        endx = (int) (x + length * Math.cos(n * Math.PI));
        endy = (int) (y + length * Math.sin(n * Math.PI));
        g.setColor(Color.black);
        g.drawLine(x - 1, y, endx - 1, endy);
        g.drawLine(x, y, endx, endy);
        g.drawLine(x + 1, y, endx + 1, endy);
        g.drawImage(hook, endx - 23, endy - 2, null);
    }

    void paintSelf(Graphics g) {
        logic();
        switch (state) {
            case 0:
                if (n < 0.1) {
                    dir = 1;
                } else if (n > 0.9) {
                    dir = -1;
                }
                n = n + 0.005 * dir;
                lines(g);
                break;
            case 1:
                if (length <= MAX_length) {
                    length = length + 5;
                    lines(g);
                } else {
                    state = 2;
                }
                break;
            case 2:
                if (length >= MIN_length) {
                    length = length - 5;
                    lines(g);
                } else {
                    state = 0;
                }
                break;
            case 3:
                int m = 1;
                if (length >= MIN_length) {
                    length = length - 5;
                    lines(g);
                    for (Object obj : this.frame.objectList) {
                        if (obj.flag) {
                            m = obj.m;
                            obj.x = endx - obj.getWidth() / 2;
                            obj.y = endy;
                            if (length <= MIN_length) {
                                obj.x = -150;
                                obj.y = -150;
                                obj.flag = false;
                                Bg.count += obj.count;
                                new Thread(() -> {
                                    MusicPlayer player = new MusicPlayer();
                                    try {
                                        player.playMusic("sounds/grab.mp3");
                                    } catch (InterruptedException e) {
                                        throw new RuntimeException(e);
                                    }
                                }).start();
                                Bg.waterFlag = false;
                                state = 0;
                            }
                            if (Bg.waterFlag) {
                                if (obj.type == 1) {
                                    m = 1;
                                } else if (obj.type == 2) {
                                    obj.x = -150;
                                    obj.y = -150;
                                    obj.flag = false;
                                    Bg.waterFlag = false;
                                    state = 2;
                                }
                            }
                        }
                    }
                }
                try {
                    Thread.sleep(m);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                break;
        }
        // 绘制爆炸效果(如果存在且处于活动状态)
        if (currentExplosion!= null && currentExplosion.isActive()) {
            currentExplosion.draw(g);
        }
    }

    void reGame() {
        n = 0;
        length = 100;
    }
}

3.动画和视觉效果

        讨论游戏中的动画效果,如爆炸效果的实现。

import java.awt.Graphics;
import java.awt.Image;
public class Explosion {
    private Image explosionImg;
    private int x;
    private int y;
    private int radius;// 爆炸半径
    private boolean active;  // 用于标记爆炸是否处于活动显示状态
    private int totalFrames;  // 爆炸动画总帧数,用于控制动画持续时间
    private int currentFrame;  // 当前播放到的帧数

    public Explosion(Image img, int x, int y, int radius, int totalFrames) {
        this.explosionImg = img;
        this.x = x;
        this.y = y;
        this.radius = radius;
        this.active = true;
        this.totalFrames = totalFrames;
        this.currentFrame = 0;
    }

    public void update() {
        if (active) {
            currentFrame++;
            if (currentFrame >= totalFrames) {
                setInactive();
            }
        }
    }

    public void draw(Graphics g) {
        if (active) {
            g.drawImage(explosionImg, x, y, null);
        }
    }

    public boolean isActive() {
        return active;
    }

    public void setInactive() {
        active = false;
    }
}

四、音乐播放器实现

        介绍如何使用javazoom.jl.player.Player来播放背景音乐说明游戏中如何根据不同事件(如抓取金块、爆炸)播放相应的音效。

import javazoom.jl.player.Player;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class MusicPlayer {
    public void playBgMusic(String audioFilePath) throws InterruptedException {
        Thread playThread = new Thread(() -> {
            while (true) {
                try {
                    FileInputStream fis = new FileInputStream(audioFilePath);
                    Player player = new Player(fis);
                    player.play();
                } catch (FileNotFoundException e) {
                    System.out.println("音频文件未找到:" + e.getMessage());
                } catch (Exception e) {
                    System.out.println("播放音频时发生错误:" + e.getMessage());
                }
            }
        });
        playThread.start();
    }

    public void playMusic(String audioFilePath) throws InterruptedException {
        Thread playThread = new Thread(() -> {
            try {
                FileInputStream fis = new FileInputStream(audioFilePath);
                Player player = new Player(fis);
                player.play();
            } catch (FileNotFoundException e) {
                System.out.println("音频文件未找到:" + e.getMessage());
            } catch (Exception e) {
                System.out.println("播放音频时发生错误:" + e.getMessage());
            } finally {
                System.out.println("音乐播放结束,资源已释放。");
            }
        });
        playThread.start();
        Thread.sleep(2000);
        playThread.interrupt();
    }
}

五、效果展示

        通过上述完美的代码体现,我们可以玩一把简单的黄金矿工小游戏,效果图如下:

        图片和声音记得更改为自己的图片和音乐,喜欢博主的点点赞,加加关注,有什么疑问可以在评论区提问,祝各位取得自己想要的结果

标签:Bg,Java,int,Color,小游戏,obj,new,黄金矿工,public
From: https://blog.csdn.net/makeke123456/article/details/145225326

相关文章

  • Java—常用的API
    API:API不需要背,用的时候会查就行。Math:是一个帮助我们用于进行数学计算的工具类私有化构造方法,所有的方法都是静态的math类的常用方法:调用方式:Math.方法名()调用Math中的abs:Math.abs(-88)将去绝对值打印为88注意:以int类型为例,取值范围:-2147483648~2147483647如果没有......
  • JavaScript的那些不可不知的知识
    目录JavaScript基础JavaScript高级JavaScript基础数据类型:JavaScript的数据类型分为基本数据类型和引用数据类型。基本数据类型包含number(数字)、string(字符串)、boolean(布尔值)、null(空值)、undefined(未定义)。而像array(数组)、function(函数)等则属于引用数据类型。在内......
  • JavaScript详解十二 ——事件概述、操作元素
    1、事件概述JS使我们有能力创建动态页面,而事件是可以被JS侦测的行为简单理解:触发----响应机制网页中每个元素都可以产生某些可以触发JS的事件,例如点击事件事件是由三部分组成事件源事件类型事件处理程序称为事件三要素事件源:事件被触发的对象谁被触发事件类型:如何触......
  • InfluxDB:单节点与集群部署实操及 java.lang.RuntimeException 报错的高效解决方案
    前言:在当今数据驱动的时代,时序数据的管理和分析变得愈发重要。InfluxDB作为一款高性能、开源的时序数据库,凭借其强大的写入性能、灵活的查询功能以及对大规模数据的高效处理能力,成为了众多开发者的首选工具。无论是用于监控系统、物联网设备数据存储,还是日志分析,InfluxDB......
  • JavaScript详解十三 ——节点操作
    节点操作1、创建节点docment.createElement('节点')参数:标签名字符串这些元素原先不存在,是根据需求动态生成的,所以也成为动态创建元素节点,会将创建好的对象作为返回值返回2、创建文本document.createTextNode()可以用来创建一个文本节点对象参数:文本内容字符串,并将新的......
  • Java类加载机制与JVM运行时数据区各逻辑内存区域与JDK的版本相关差异浅谈
    Java类加载机制与JVM运行时数据区各逻辑内存区域与JDK的版本相关差异浅谈 【摘要】JVM(JavaVirtualMachine)作为Java研发人员工作的每天都会接触到的虚拟机,其运行机制与底层原理想必大家都略知一二,今天我将从初学者的角度出发,结合甲骨文官方的技术文档,对部分Java虚拟机的相关......
  • Java项目部署后无法访问的原因及解决方法
    当您部署了一个Java项目但无法访问时,可能是由多个因素引起的。为了快速定位并解决问题,您可以按照以下步骤进行排查和修复:检查应用服务器配置:确保应用服务器(如Tomcat、Jetty、WildFly等)已正确安装并配置。检查服务器的启动日志,确保没有启动错误或异常信息。确认应用服务器监......
  • 【转】[JavaScript] 为什么需要 ===
    转自:kimi.ai在JavaScript中,===是严格等于运算符(StrictEqualityOperator),它与==(等于运算符)一起用于比较两个值是否相等。然而,===和==的行为和用途有所不同,这主要是由于JavaScript的类型系统和历史设计导致的。以下是一些关键原因,解释为什么JavaScript中需要===:1.......
  • JavaScript笔记APIs篇02——DOM事件
     黑马程序员视频地址:黑马程序员前端JavaScript入门到精通全套视频教程https://www.bilibili.com/video/BV1Y84y1L7Nn?vd_source=0a2d366696f87e241adc64419bf12cab&spm_id_from=333.788.videopod.episodes&p=78 目录事件监听(绑定)事件监听其他版本(了解)事件类型事件对象......
  • 【转】[JavaScript] JS 对象和 JSON 的区别与转换
    转自:kimi.ai在JavaScript中,JS对象和JSON是两个密切相关但又有所区别的概念。以下是它们的主要区别:1. 定义和用途JS对象JS对象是JavaScript中的一种数据结构,用于存储键值对(key-valuepairs)。它是JavaScript中的基本数据类型之一,可以用来表示复杂的数据结构,例如用......