iT邦幫忙

2025 iThome 鐵人賽

DAY 27
0
Software Development

30天從基礎學起Java,直到做出我的第一個遊戲系列 第 27

Day 27:Java Snake Game 設定功能(二)

  • 分享至 

  • xImage
  •  

今日內容:音量大小設定、顏色設定

音量大小設定

為了能夠調整音量大小,我們需要先學習如何使用JSlider

JSlider soundSlider;

soundSlider = new JSlider(0, 100, 100);
// 設定值(最小,最大,預設)
soundSlider.setBounds(300, 200, 400, 50);
// 設置slider顯示範圍
soundSlider.setForeground(Color.WHITE);
// 將文字設為白色
soundSlider.setBackground(Color.darkGray);
// 將背景設成與遊戲同色

soundSlider.setPaintTicks(true);
// 顯示刻度
soundSlider.setMajorTickSpacing(25);
// 設置大刻度距離
soundSlider.setPaintLabels(true);
// 顯示刻度數值

接著,我們需要到調整音效的地方(GamePanel)新增一個控制系統

FloatControl eatControl;
FloatControl gameOverControl;
FloatControl levelUpControl;
// 接收float數值,用於修改Clip物件的音量大小

// 在loadSound()中,當物件(Clip)被打開(Open)後,我們存取該物件的Control
private void loadSound(){
    try{
        // ... (載入 eatSound)
        eatSound = AudioSystem.getClip();
        eatSound.open(audioInputStream1);
        eatControl = (FloatControl) eatSound.getControl(FloatControl.Type.MASTER_GAIN);

        // ... (載入 gameOverSound)
        gameOverSound = AudioSystem.getClip();
        gameOverSound.open(audioInputStream2);
        gameOverControl = (FloatControl) gameOverSound.getControl(FloatControl.Type.MASTER_GAIN);

        // ... (載入 levelUpSound)
        levelUpSound = AudioSystem.getClip();
        levelUpSound.open(audioInputStream3);
        levelUpControl = (FloatControl) levelUpSound.getControl(FloatControl.Type.MASTER_GAIN);
    }
    catch(Exception e){
        System.out.println("Error: " + e);
    }
}

接著我們需要透過GameFrame來傳遞參數

float currentVolume = 0.0f; // 新增音量變數,預設為 0dB (最大音量)

// 設定音量
public void setVolume(float volume) {
    this.currentVolume = volume;
}

// 取得音量
public float getVolume() {
    return currentVolume;
}

最後是為JSlider物件新增ChangeListener方法 (不是ActionListener哦,這裡是當Slider被修改後(change)會呼叫ChangeListener)

soundSlider.addChangeListener(e ->{
    int soundVolume = soundSlider.getValue();
    float volume;
    // 如果音效設定被拉到0,就設置成靜音
    if(soundVolume == 0) volume = -80.0f;
    // 否則使用分貝公式計算(聲音除100後log10再乘20)
    else volume = (float)(Math.log10(soundVolume / 100.0) * 20.0);

    // 呼叫gameFrame的聲音數值,並更新gamePanel的音量
    gameFrame.setVolume(volume);
    gameFrame.gamePanel.updateSoundVolume();
});

補上gamePanel中更新音量的方法

public void updateSoundVolume() {
    float volume = gameFrame.getVolume();
    eatControl.setValue(volume);
    gameOverControl.setValue(volume);
    levelUpControl.setValue(volume);
}

有一點要注意的是,FloatControl接收的數值必須是float,不能使用double,否則會有精度的問題(不會進行Narrow Convertion)!

image
這樣就完成設定音量的部分了

顏色設定

接下來要做的是選擇蛇的顏色
我的想法是使用JComboBox,這樣在確保使用者只能選擇一個顏色的情況下,我們可以制定使用者選擇的內容
我們首先學習如何使用JComboBox

JComboBox<String> colorChooser;
String[] colors = {"綠色 Green", "藍色 Blue", "粉色 Pink"};

colorChooser = new JComboBox<>(colors);
// 新增JComboBox物件,使用String,傳入colors的String array
colorChooser.setSelectedIndex(0);
// 預設預選選項為第一格(index 0)
colorChooser.setBounds(300, 300, 400, 50);
// 設定位置
colorChooser.setBackground(Color.lightGray);
// 將背景設為淺灰色,增加對比讓使用者更好選擇
colorChooser.setForeground(Color.BLACK);
// 文字設為黑色
colorChooser.setFont(new Font("宋体", Font.PLAIN, 30));
// 設定文字型式
});

接著,回想一下我們繪製蛇的顏色,我們是在drawSnake()裡面決定畫筆顏色的
所以首先我們先在GameFrame中傳遞color的參數

private String color = "綠色 Green";

public void setColor(String color){
    this.color = color;
}

public String getColor(){
    return color;
}

然後在GamePanel中

// 我們原本設置的snakeC
snakeC = Color.GREEN;

// 改成當遊戲開始時,我們去抓使用者選擇的數值
public void startGame(){
    checkSnakeColor();
}

private void checkSnakeColor(){
    String color = gameFrame.getColor();
    if(color.equals("綠色 Green")) snakeC = Color.GREEN;
    else if(color.equals("藍色 Blue")) snakeC = Color.CYAN;
    else if(color.equals("粉色 Pink")) snakeC = Color.PINK;
    else{
        snakeC = Color.GREEN;
        System.out.println("Error Occurred at checkSnakeColor");
    }
}

最後我們補上在Setting中,JComboBox的ActionListener

colorChooser.addActionListener(e -> {
    String colorChose = Objects.requireNonNull(colorChooser.getSelectedItem()).toString();
    // 使用requireNonNull避免傳遞Null參數,getSelectedItem().toString()取得字串
    gameFrame.setColor(colorChose);
    // 呼叫gameFrame,修改顏色選項
});

image
最後也完成顏色設定的部分了


上一篇
Day 26:Java Snake Game 設定功能(一)
系列文
30天從基礎學起Java,直到做出我的第一個遊戲27
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言