import javax.sound.sampled.; import javax.swing.; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Random;

public class SnakeGame extends JFrame implements KeyListener { // 游戏界面大小 private final int WIDTH = 800; private final int HEIGHT = 840; // 网格大小 private static final int GRID_SIZE = 40; // 贪吃蛇移动速度 private static final int SNAKE_SPEED = GRID_SIZE; // 贪吃蛇的区块 private final ArrayList snake = new ArrayList<>(); private Point direction = new Point(1, 0); // 贪吃蛇移动方向 private Point food; // 食物 // 记录玩家得分 private int score = 0; // 判断是否正在播放音乐 private boolean hasPlayed = false; // 蛇头图片 ImageIcon icon = new ImageIcon('resizedImage.jpg'); ImageIcon deadicon = new ImageIcon('微信图片_20230603143822.jpg'); ImageIcon eaticon = new ImageIcon('resizedImage.jpg');

// 把图片jlabel一下
JLabel j = new JLabel(icon);
JLabel jdead = new JLabel(deadicon);
JLabel jeat = new JLabel(eaticon);

// 排行榜
private final ArrayList<Integer> scoreList = new ArrayList<>();

// 开始游戏按钮
private JButton startButton;
// 排行榜按钮
private JButton leaderboardButton;

// 游戏是否开始
private boolean gameStarted = false;

public SnakeGame() {
    // 设置窗口大小和标题
    setSize(WIDTH, HEIGHT);
    setTitle('贪吃蛇小游戏');
    // 设置窗口居中
    setLocationRelativeTo(null);
    // 添加键盘监听器
    addKeyListener(this);
    // 初始化贪吃蛇和食物
    initSnake();
    initFood();
    // 打印蛇头
    this.add(j);

    // 创建开始游戏按钮
    startButton = new JButton('开始游戏');
    startButton.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            gameStarted = true;
            startButton.setVisible(false);
            leaderboardButton.setVisible(false);
        }
    });
    add(startButton);

    // 创建排行榜按钮
    leaderboardButton = new JButton('排行榜');
    leaderboardButton.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            // 显示排行榜
            showLeaderboard();
        }
    });
    add(leaderboardButton);

    // 显示窗口
    setVisible(true);
}

// 初始化贪吃蛇
private void initSnake() {
    // 初始长度为3
    snake.add(new Point(4, 2));
    snake.add(new Point(3, 2));
    snake.add(new Point(2, 2));
}

// 初始化食物
private void initFood() {
    Random random = new Random();
    int x = random.nextInt((WIDTH - 2 * GRID_SIZE) / GRID_SIZE);
    int y = random.nextInt((HEIGHT - 2 * GRID_SIZE) / GRID_SIZE);
    food = new Point(x + 1, y + 1);
}

// 绘制游戏界面
@Override
public void paint(Graphics g) {
    // 清空画布
    g.clearRect(0, 0, WIDTH, HEIGHT);

    // 绘制贪吃蛇
    g.setColor(Color.red);
    for (Point p : snake) {
        g.fillOval(p.x * GRID_SIZE, p.y * GRID_SIZE, GRID_SIZE, GRID_SIZE);
    }
    // 绘制蛇头
    j.setBounds(snake.get(0).x * GRID_SIZE - 7, snake.get(0).y * GRID_SIZE - 30, 40, 40);
    // 绘制网格
    g.setColor(Color.blue);
    for (int i = 0; i < WIDTH / GRID_SIZE; i++) {
        g.drawLine(i * GRID_SIZE, 0, i * GRID_SIZE, HEIGHT);
    }
    for (int i = 0; i < HEIGHT / GRID_SIZE; i++) {
        g.drawLine(0, i * GRID_SIZE, WIDTH, i * GRID_SIZE);
    }
    // 绘制食物
    g.setColor(Color.PINK);
    g.fillOval(food.x * GRID_SIZE, food.y * GRID_SIZE, GRID_SIZE, GRID_SIZE);
    // 显示得分
    g.setColor(Color.darkGray);
    g.setFont(new Font('微软雅黑', Font.PLAIN, 20));
    g.drawString('得分:' + score, 650, 100);
    // 绘制黑色方格边框
    g.setColor(Color.black);
    for (int i = 0; i < WIDTH / GRID_SIZE; i++) {
        g.fillRect(i * GRID_SIZE, 0, 40, 40);
        g.fillRect(i * GRID_SIZE, 800, 40, 40);
        g.fillRect(0, i * GRID_SIZE, 40, 40);
        g.fillRect(760, i * GRID_SIZE, 40, 40);
    }
}

// 重写 update() 方法,调用 paint() 方法
@Override
public void update(Graphics g) {
    paint(g);
}

// 贪吃蛇移动
private void moveSnake() {
    // 计算新的蛇头位置
    Point head = new Point(snake.get(0).x + direction.x, snake.get(0).y + direction.y);
    // 判断是否撞墙
    if (head.x < 1 || head.x >= (WIDTH / GRID_SIZE) - 1 || head.y < 1 || head.y >= (HEIGHT / GRID_SIZE) - 1) {
        String filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\FQ!(魔男)_1.WAV';
        playSnakeMusic(filePath, 2F);
        JOptionPane.showMessageDialog(this, '你是真的菜,才' + score + '分');
        System.exit(0);
    }
    // 判断蛇头是否与蛇身相撞
    for (int i = 1; i < snake.size(); i++) {
        if (head.equals(snake.get(i))) {
            String filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\你干嘛哎哟_1.WAV';
            playSnakeMusic(filePath, 2F);
            JOptionPane.showMessageDialog(this, '你是真的菜,才' + score + '分');
            System.exit(0);
        }
    }
    // 判断是否吃到食物
    if (head.equals(food)) {
        // 如果音效未正在播放,则播放音效
        if (!hasPlayed) {
            // 13个音效随机播放
            Random random = new Random();
            int index = random.nextInt(18);
            String filePath = '';
            switch (index) {
                case 0:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\emmmm__(van)_1.WAV';
                    break;
                case 1:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\I love that_ (van)_1.WAV';
                    break;
                case 2:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\oh!夜色!_1.WAV';
                    break;
                case 3:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\务必让螳螂乱摸_(van)_1.WAV';
                    break;
                case 4:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\啊_this good_(van)_1.WAV';
                    break;
                case 5:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\啊?快哉!(王)_1.WAV';
                    break;
                case 6:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\来!_1.WAV';
                    break;
                case 7:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\洞子大(van)_1.WAV';
                    break;
                case 8:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\van的销魂叫声__1.WAV';
                    break;
                case 9:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\Is so F K D(van)_1.WAV';
                    break;
                case 10:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\That turns me on(van)_1.WAV';
                    break;
                case 11:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\Do you like van 游戏?_1.WAV';
                    break;
                case 12:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\偷袭_1.WAV';
                    break;
                case 13:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\Yeees(van)_1.WAV';
                    break;
                case 14:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\厉不厉害 你坤哥_1.WAV';
                    break;
                case 15:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\及你太美_1.WAV';
                    break;
                case 16:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\其实我平时很厉害的   你知道吗_1.WAV';
                    break;
                case 17:
                    filePath = 'C:\Users\彭 杨\IdeaProjects\untitled\src\snake\个人练习生_1.WAV';
                    break;
            }
            playSnakeMusic(filePath, 2F);
            hasPlayed = true;
        }
        // 更新贪吃蛇和食物
        snake.add(0, head);
        initFood();
        // 如果吃到食物,则将 score 的值加上 10
        score += 10;
    } else {
        hasPlayed = false; // 如果未吃到食物,则重置 hasPlayed 为 false
        snake.add(0, head);
        snake.remove(snake.size() - 1);
    }
    // 刷新游戏界面
    repaint();
}

// 按键处理
@Override
public void keyPressed(KeyEvent e) {
    switch (e.getKeyCode()) {
        case KeyEvent.VK_UP:
            if (direction.y != 1) {
                direction.x = 0;
                direction.y = -1;
            }
            break;
        case KeyEvent.VK_DOWN:
            if (direction.y != -1) {
                direction.x = 0;
                direction.y = 1;
            }
            break;
        case KeyEvent.VK_LEFT:
            if (direction.x != 1) {
                direction.x = -1;
                direction.y = 0;
            }
            break;
        case KeyEvent.VK_RIGHT:
            if (direction.x != -1) {
                direction.x = 1;
                direction.y = 0;
            }
            break;
    }
}

// 必须实现的方法
@Override
public void keyTyped(KeyEvent e) {
}

// 必须实现的方法
@Override
public void keyReleased(KeyEvent e) {
}

// 播放音乐
private void playMusic(String filePath) {
    File musicFile = new File(filePath);
    try {
        AudioInputStream audioStream = AudioSystem.getAudioInputStream(musicFile);
        Clip clip = AudioSystem.getClip();
        clip.open(audioStream);
        clip.loop(Clip.LOOP_CONTINUOUSLY);
    } catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
        e.printStackTrace();
    }
}

// 播放音效,音效只播放一次(这里因为我找的音效声音太小了便传进一个volume增大音量)
private void playSnakeMusic(String filePath, float volume) {
    File musicFile = new File(filePath);
    try {
        AudioInputStream audioStream = AudioSystem.getAudioInputStream(musicFile);
        Clip clip = AudioSystem.getClip();
        clip.open(audioStream);
        // 获取FloatControl控制类型
        FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
        // 设置音量大小
        float dB = (float) (Math.log(volume) / Math.log(10.0) * 20.0);
        gainControl.setValue(dB);
        // 添加LineListener
        clip.addLineListener(new LineListener() {
            @Override
            public void update(LineEvent event) {
                if (event.getType() == LineEvent.Type.STOP) {
                    clip.close(); // 关闭Clip
                    try {
                        audioStream.close(); // 关闭音频输入流
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        clip.start(); // 播放音乐
    } catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
        e.printStackTrace();
    }
}

// 游戏循环
private void gameLoop() {
    while (gameStarted) {
        moveSnake();
        try {
            Thread.sleep(8000 / SNAKE_SPEED);
        } catch (InterruptedException i) {
            i.printStackTrace();
        }
    }
}

// 显示排行榜
private void showLeaderboard() {
    // 1. 获取当前得分
    scoreList.add(score);
    // 2. 对得分列表进行排序
    Collections.sort(scoreList, Collections.reverseOrder());
    // 3. 创建一个新的窗口来显示排行榜
    JFrame leaderboardFrame = new JFrame('排行榜');
    leaderboardFrame.setSize(300, 200);
    leaderboardFrame.setLocationRelativeTo(null);
    // 4. 创建一个文本区域来显示排行榜内容
    JTextArea leaderboardTextArea = new JTextArea();
    leaderboardTextArea.setEditable(false);
    // 5. 将得分列表添加到文本区域
    for (int i = 0; i < scoreList.size(); i++) {
        leaderboardTextArea.append('第' + (i + 1) + '名: ' + scoreList.get(i) + '\n');
    }
    // 6. 将文本区域添加到窗口
    leaderboardFrame.add(leaderboardTextArea);
    // 7. 显示窗口
    leaderboardFrame.setVisible(true);
}

public static void main(String[] args) {
    SnakeGame game = new SnakeGame();
    // 启动游戏循环
    game.gameLoop();
}

}

贪吃蛇小游戏 - 在线玩经典蛇形游戏

原文地址: https://www.cveoy.top/t/topic/oC36 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录