今日內容:音量大小設定、顏色設定
為了能夠調整音量大小,我們需要先學習如何使用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)!
這樣就完成設定音量的部分了
接下來要做的是選擇蛇的顏色
我的想法是使用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,修改顏色選項
});
最後也完成顏色設定的部分了