iT邦幫忙

0

Day26 | 遊戲開發(五)

  • 分享至 

  • xImage
  •  

在前面的單元中,我們完成了遊戲視窗與 3x3 棋盤按鈕的靜態外觀。今天我們要迎來最關鍵的互動邏輯——ActionListener讓玩家能夠點擊格子,並實現 X 與 O 的輪流下棋機制!


  • 核心實作:為每個按鈕綁定 ActionListener
    在雙層 for 迴圈建立按鈕的同時,我們替每一個按鈕(tile)加上了事件監聽器:
tile.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e){
        // 1. 取得被點擊的按鈕來源
        JButton tile = (JButton)e.getSource();
        
        // 2. 防呆機制:確保格子是空的(還沒被下過)才能填入
        if (tile.getText() == ""){
            // 將按鈕文字設為當前玩家(X 或 O)
            tile.setText(currentPlayer);

            // 3. 切換玩家回合(三元運算子:如果是 X 就換 O,反之換 X)
            currentPlayer = currentPlayer == playerX ? playerO : playerX;
            
            // 4. 更新頂部標題文字,提示下一個玩家的回合
            textLabel.setText(currentPlayer + "'s turn.");
        }
    }
});

說明:

* e.getSource() 與強制轉型:當任何一個按鈕被點擊時,ActionEvent 會捕捉到這個事件。我們透過 e.getSource() 拿到觸發事件的元件,並將它強制轉型為 JButton,以便對它進行文字修改。
* 防呆檢查 if (tile.getText() == ""):確保玩家不能重複點擊已經有棋子的格子,避免已經下過的 X 或 O 被蓋掉。
* 三元運算子切換回合:currentPlayer = currentPlayer == playerX ? playerO : playerX; 簡潔地實現了每次點擊後在兩位玩家之間交替。
* 即時更新頂部標題:透過 textLabel.setText(...),讓頂部文字從一開始的遊戲名稱變成動態的 O's turn. 或 X's turn.,大幅提升遊戲體驗。
  • 目前完整程式碼:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class TicTacToe {
    int boardWidth = 600;
    int boardHeight = 650; //50px for the text panel on top

    JFrame frame = new JFrame("Tic-Tac-Toe");
    JLabel textLabel = new JLabel();
    JPanel textPanel = new JPanel();
    JPanel boardPanel = new JPanel();

    JButton[][] board = new JButton[3][3];
    String playerX = "X";
    String playerO = "O";
    String currentPlayer = playerX;

    TicTacToe(){
        frame.setVisible(true);
        frame.setSize(boardWidth, boardHeight);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());

        textLabel.setBackground(Color.darkGray);
        textLabel.setForeground(Color.white);
        textLabel.setFont(new Font("Arial", Font.BOLD, 50));
        textLabel.setHorizontalAlignment(JLabel.CENTER);
        textLabel.setText("Tic-Tac-Toe");
        textLabel.setOpaque(true);

        textPanel.setLayout(new BorderLayout());
        textPanel.add(textLabel);
        frame.add(textPanel, BorderLayout.NORTH);

        boardPanel.setLayout(new GridLayout(3, 3));
        boardPanel.setBackground(Color.darkGray);
        frame.add(boardPanel);

        for (int r = 0; r < 3; r++){
            for (int c = 0; c < 3; c++){
                JButton tile = new JButton();
                board[r][c] = tile;
                boardPanel.add(tile);

                tile.setBackground(Color.darkGray);
                tile.setForeground(Color.white);
                tile.setFont(new Font("Arial", Font.BOLD, 120));
                tile.setFocusable(false);

                tile.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e){
                        JButton tile = (JButton)e.getSource();
                        if (tile.getText() == ""){
                            tile.setText(currentPlayer);

                            currentPlayer = currentPlayer == playerX ? playerO : playerX;
                            textLabel.setText(currentPlayer + "'s turn.");
                        }
                        
                    }
                });
                
            }
        }
    }
}
  • 跑出來長這樣:
    https://ithelp.ithome.com.tw/upload/images/20261018/20184397iEfwsJXtTV.png

  • 參考教學影片:https://youtu.be/Nc77ymnm8Ss?si=PC8nENyFWeLg1lDg


*提醒邦友,使用第三方服務/API 時,請務必評估資安風險與隱私保護
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言