贪吃蛇游戏音效优化:使吃到食物的音效只播放一次

本教程将演示如何修改贪吃蛇游戏代码,使吃到食物的音效只播放一次。

问题描述

在原始代码中,每次贪吃蛇吃到食物时,都会播放音效。然而,我们希望音效只播放一次,直到下次吃到食物为止。

解决方案

为了实现这一目标,我们可以通过引入一个布尔变量来记录音效是否已经播放过。

  1. 添加布尔变量

    SnakeGame 类中添加一个名为 hasPlayed 的布尔变量,用来记录音效是否已经播放过。

    private boolean hasPlayed = false;
    
  2. 更新 moveSnake() 方法

    moveSnake() 方法中,判断是否吃到食物。如果吃到食物,且 hasPlayedfalse,则播放音效,并将 hasPlayed 设置为 true。否则,将 hasPlayed 设置为 false

    // 判断是否吃到食物
    if (head.equals(food)) {
        // 如果音效未播放过,则播放音效
        if (!hasPlayed) {
            Random random = new Random();
            int index = random.nextInt(8);
            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;
            }
            playMusic(filePath);
            hasPlayed = true;
        }
        // 更新贪吃蛇和食物
        snake.add(0, head);
        initFood();
        // 如果吃到食物,则将 score 的值加上 10
        score += 10;
        // 将 hasPlayed 设置为 true,表示音效已经播放过
        hasPlayed = true;
    } else {
        // 将 hasPlayed 设置为 false,表示音效未播放过
        hasPlayed = false;
        snake.add(0, head);
        snake.remove(snake.size() - 1);
    }
    
    // 刷新游戏界面
    repaint();
    

代码示例

以下是修改后的完整代码:

package game;

import javax.sound.sampled.*;
import javax.swing.*;
import java.awt.*;
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.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<Point> 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('C:\Users\彭 杨\IdeaProjects\untitled\src\game\resizedImage.jpg');
    JLabel j=new JLabel(icon);
    public SnakeGame() {
        // 设置窗口大小和标题
        setSize(WIDTH, HEIGHT);
        setTitle('贪吃蛇小游戏');
        // 设置窗口居中
        setLocationRelativeTo(null);
        // 添加键盘监听器
        addKeyListener(this);
        // 初始化贪吃蛇和食物

        initSnake();
        initFood();
        this.add(j);

        // 播放背景音乐
        playMusic('C:\Users\彭 杨\IdeaProjects\untitled\src\G0tch_ - 托马斯臭火车_1_1.WAV');

        // 显示窗口
        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) {
            JOptionPane.showMessageDialog(this, '你是真的菜,才' + score + '分');
            System.exit(0);
        }
        // 判断蛇头是否与蛇身相撞
        for (int i = 1; i < snake.size(); i++) {
            if (head.equals(snake.get(i))) {
                JOptionPane.showMessageDialog(this, '你是真的菜,才' + score + '分');
                System.exit(0);
            }
        }
        // 判断是否吃到食物
        if (head.equals(food)) {
            // 如果音效未播放过,则播放音效
            if (!hasPlayed) {
                Random random = new Random();
                int index = random.nextInt(8);
                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;
                }
                playMusic(filePath);
                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();
        }
    }

    public static void main(String[] args) {

        SnakeGame game = new SnakeGame();
        // 游戏循环
        while (true) {
            game.moveSnake();
            try {
                Thread.sleep(8000 / SNAKE_SPEED);
            } catch (InterruptedException i) {
                i.printStackTrace();
            }
        }
        // 关闭旧的界面

    }
}

说明

  1. 代码中的路径请根据您的实际情况进行修改。
  2. hasPlayed 变量可以放在 SnakeGame 类的其他位置,但必须是可被 moveSnake() 方法访问的。
  3. 此代码仅供参考,您可能需要根据您的具体情况进行调整。

总结

通过引入布尔变量 hasPlayed,我们可以轻松地实现贪吃蛇吃到食物的音效只播放一次的功能,提高游戏体验。

贪吃蛇游戏音效优化:使吃到食物的音效只播放一次

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

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