今天要繼續昨天的任務,完成其他的panel
不過首先我們要先處理一些小問題,就是目前主畫面的選單框框如果被選中了會有透明的邊線,很醜!
所以我回顧了一下我的程式碼,發現我並沒有加入這行:
startButton.setFoucsPainted(false);
// 其他按鈕一樣加上
後來我覺得按鈕不應該要有邊界顯示,所以我將按鈕的背景設置成與遊戲背景相同,然後將
startButton.setBackground(backgroundC);
startButton.setBorderPainted(false);
// 其他按鈕一樣加上
這樣就不會有按鈕突兀的問題了,選項變成很直覺美觀地顯示在畫面上
然後就是如同GamePanel中,我將設置文字與按鈕的程式碼獨立寫method,再於constructor中呼叫這些method,提高程式碼可讀性
開始今天的工作!
首先,settingPanel的工作打算明天再做,預計會有調整音量,遊戲難度(速度)設置,顏色設定等
今天先完善helpPanel與GameOverPanel
而我們先從helpPanel開始
我想法中helpPanel大概就只是介紹遊戲怎麼玩,然後像之前提醒使用者要切換成英文輸入法而已,比較簡單
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JLabel;
import java.awt.*;
public class HelpPanel extends JPanel{
static final int PANEL_WIDTH = 800;
static final int PANEL_HEIGHT = 500;
GameFrame gameFrame;
JLabel label;
JButton homeButton;
HelpPanel(GameFrame frame){
this.gameFrame = frame;
this.setBackground(Color.darkGray);
this.setLayout(null);
this.setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
setButton();
setLabel();
}
private void setButton(){
homeButton = new JButton("← Home"); // 給一個回到主畫面的按鈕
homeButton.setFont(new Font("Times New Roman", Font.ITALIC, 30));
homeButton.setForeground(Color.WHITE);
homeButton.setBackground(Color.darkGray);
homeButton.setBorderPainted(false);
homeButton.setBounds(25, 400, 200, 50);
homeButton.addActionListener(e->gameFrame.showPanel("Menu"));
this.add(homeButton);
}
private void setLabel(){
label = new JLabel();
label.setFont(new Font("MV Boli", Font.BOLD, 50));
label.setText("<html>HOW TO PLAY:<br>用WASD控制上下左右
<br>記得要切成英文輸入法!</html>");
label.setForeground(Color.WHITE);
label.setBounds(150, 50, 600, 300);
label.setVisible(true);
this.add(label);
}
}
然後記得要在GameFrame中加入對應的變數與名稱
public class GameFrame extends JFrame{
HelpPanel helpPanel;
private void setPanel(){
helpPanel = new HelpPanel(this);
mainPanel.add(helpPanel, "Help");
}
}
接下來是遊戲結束的畫面,由於我們會在遊戲結束時展示成績分數,所以我們需要想辦法傳遞這個變數
我的想法是在GameFrame, GamePanel, GameOverPanel中各宣告score變數用於儲存與傳遞這個數值
我們首先要在GameFrame中宣告setScore和getScore,讓另外兩個Panel可以對其做操作
public class GameFrame extends JFrame{
private int score = 0;
public void setScore(int score){
if(score >= 0) this.score = score;
}
public void getScore(){return this.score;}
}
思考完傳遞數值的方式後,我們可以來建置GameOverPanel了,我打算在這個畫面除了展示結束、成績以外,可以提供兩個選擇:回主畫面或開始下一把遊戲
import javax.swing.*;
import java.awt.*;
public class GameOverPanel extends JPanel{
static final int PANEL_WIDTH = 800;
static final int PANEL_HEIGHT = 500;
// 用於存放更新的score數值
int score = 0;
GameFrame gameFrame;
JButton homeButton; // 回到主畫面
JButton newGameButton; // 開始下一把遊戲
JLabel gameOverLabel;
JLabel gameOverLabel2;
GameOverPanel(GameFrame frame){
this.gameFrame = frame;
this.setBackground(Color.darkGray);
this.setLayout(null);
this.setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
setButton();
}
public void setScore(){
// 這個setScore設為public,用意是當GameFrame在showPanel需要呼叫GameOverPanel時
// 會先呼叫setScore()修改其分數,然後再呼叫GameOverPanel顯示結束畫面
// 否則會因為修改時間與展示時間不對,導致例如score永遠為0的情況
this.score = gameFrame.getScore();
gameOverLabel2.setText("<html>Your Final Score Is: " + score + "</html>");
// 得到新的score後再將其加入label的text內
}
private void setButton(){
gameOverLabel = new JLabel();
gameOverLabel.setFont(new Font("MV Boli", Font.BOLD, 100));
gameOverLabel.setText("GAME OVER!");
gameOverLabel.setForeground(Color.WHITE);
gameOverLabel.setBounds(50, 50, 700, 100);
gameOverLabel.setVisible(true);
gameOverLabel2 = new JLabel();
gameOverLabel2.setFont(new Font("MV Boli", Font.BOLD, 50));
gameOverLabel2.setForeground(Color.WHITE);
gameOverLabel2.setBounds(100, 150, 600, 100);
gameOverLabel2.setVisible(true);
homeButton = new JButton("回主畫面 Menu");
homeButton.setFont(new Font("宋体", Font.PLAIN, 30));
homeButton.setForeground(Color.WHITE);
homeButton.setBackground(Color.darkGray);
homeButton.setBorderPainted(false);
homeButton.setFocusPainted(false);
homeButton.setBounds(200, 350, 400, 50);
homeButton.addActionListener(e->gameFrame.showPanel("Menu"));
// 這邊使用e,是Lambda Expression的用法
// 對於ActionListener這樣的Anonymous Inner Class可以省去很多程式碼
// 前面的Anonymous Inner Class也會大部分改成e,用於簡短程式碼
newGameButton = new JButton("新遊戲 New Game");
newGameButton.setFont(new Font("宋体", Font.PLAIN, 30));
newGameButton.setForeground(Color.WHITE);
newGameButton.setBackground(Color.darkGray);
newGameButton.setBorderPainted(false);
newGameButton.setBounds(200, 280, 400, 50);
newGameButton.addActionListener(e->gameFrame.showPanel("Game"));
this.add(gameOverLabel);
this.add(gameOverLabel2);
this.add(newGameButton);
this.add(homeButton);
}
}
接著是回到GameFrame做設定
public class GameFrame extends JFrame{
GameOverPanel gameOverPanel;
private void setPanel(){
gameOverPanel = new GameOverPanel(this);
mainPanel.add(gameOverPanel, "GameOver");
}
// 重要的是我們要在這裡修改GameOverPanel的分數
public void showPanel(String panelName){
cardLayout.show(mainPanel, panelName);
if("Game".equals(panelName)){gamePanel.startGame();}
else if("GameOver".equals(panelName)){gameOverPanel.setScore();} // 增加這行
}
}
這樣就完成HelpPanel的幫助頁面與GameOverPanel的結束頁面以及分數顯示了