第二章:安裝與設置 Blockly

在開始使用 Blockly 建立視覺化程式設計環境之前,我們需要先完成安裝與基本設置。Blockly 是一個客戶端的 JavaScript 庫,可以通過多種方式引入到您的網頁專案中。本章將詳細介紹不同的安裝方法,以及如何進行基本設置。

安裝 Blockly

Blockly 提供了多種安裝方式,您可以根據自己的專案需求選擇最適合的方法。以下是三種常見的安裝方式:

方法一:使用 npm 安裝

如果您的專案使用 Node.js 和 npm 進行管理,這是推薦的安裝方式。通過 npm 安裝 Blockly 可以讓您更容易地管理依賴關係和版本更新。

首先,在您的專案目錄中打開終端機,執行以下命令:

npm install blockly

安裝完成後,您可以在 JavaScript 檔案中引入 Blockly:

// ES6 模組語法
import * as Blockly from 'blockly';

// 如果需要特定語言的生成器,可以單獨引入
import 'blockly/javascript';
import 'blockly/python';

方法二:使用 CDN 引用

如果您想快速開始使用 Blockly,或者不想設置 npm 環境,可以通過 CDN 直接在 HTML 中引入 Blockly。

在您的 HTML 檔案的 `<head>` 或 `<body>` 底部添加以下代碼:

<script src="https://unpkg.com/blockly/blockly.min.js"></script>

<!-- 如果需要特定語言的生成器,可以單獨引入 -->
<script src="https://unpkg.com/blockly/javascript_compressed.js"></script>
<script src="https://unpkg.com/blockly/python_compressed.js"></script>

方法三:下載源碼

您也可以直接從 GitHub 下載 Blockly 的源碼,然後手動引入到您的專案中。

1. 前往 Blockly GitHub 倉庫
2. 下載最新版本的源碼(通常是 .zip 或 .tar.gz 檔案)
3. 解壓縮檔案,將需要的 JavaScript 檔案複製到您的專案中
4. 在 HTML 中引入這些檔案:

<script src="path/to/blockly_compressed.js"></script>
<script src="path/to/blocks_compressed.js"></script>

<!-- 如果需要特定語言的生成器,可以單獨引入 -->
<script src="path/to/javascript_compressed.js"></script>
<script src="path/to/python_compressed.js"></script>

<!-- 如果需要多語言支援,引入對應的語言檔案 -->
<script src="path/to/msg/zh-hant.js"></script>

專案結構說明

一個典型的 Blockly 專案結構如下:

my-blockly-project/
├── index.html          # 主 HTML 檔案
├── style.css           # 樣式表
├── script.js           # 主 JavaScript 檔案
├── node_modules/       # npm 安裝的依賴(如果使用 npm)
│   └── blockly/        # Blockly 庫
└── custom/             # 自定義積木和生成器
    ├── custom_blocks.js    # 自定義積木定義
    └── custom_generators.js # 自定義生成器

基本設置

安裝完 Blockly 後,我們需要進行一些基本設置才能開始使用。以下是設置 Blockly 工作區的基本步驟:

步驟一:準備 HTML 容器

首先,在 HTML 中創建一個容器元素,用於放置 Blockly 工作區:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Blockly 示例</title>
    <style>
        #blocklyDiv {
            height: 480px;
            width: 100%;
        }
    </style>
</head>
<body>
    <div id="blocklyDiv"></div>
    
    <!-- 引入 Blockly 庫 -->
    <script src="https://unpkg.com/blockly/blockly.min.js"></script>
    <script src="https://unpkg.com/blockly/javascript_compressed.js"></script>
    <script src="https://unpkg.com/blockly/python_compressed.js"></script>
    
    <!-- 自定義腳本 -->
    <script src="script.js"></script>
</body>
</html>

步驟二:初始化 Blockly 工作區

接下來,在 JavaScript 檔案中初始化 Blockly 工作區:

// script.js
document.addEventListener('DOMContentLoaded', function() {
    // 定義工具箱
    const toolbox = {
        kind: 'categoryToolbox',
        contents: [
            {
                kind: 'category',
                name: '邏輯',
                colour: '%{BKY_LOGIC_HUE}',
                contents: [
                    {
                        kind: 'block',
                        type: 'controls_if'
                    },
                    {
                        kind: 'block',
                        type: 'logic_compare'
                    },
                    {
                        kind: 'block',
                        type: 'logic_operation'
                    },
                    {
                        kind: 'block',
                        type: 'logic_negate'
                    },
                    {
                        kind: 'block',
                        type: 'logic_boolean'
                    }
                ]
            },
            {
                kind: 'category',
                name: '迴圈',
                colour: '%{BKY_LOOPS_HUE}',
                contents: [
                    {
                        kind: 'block',
                        type: 'controls_repeat_ext'
                    },
                    {
                        kind: 'block',
                        type: 'controls_whileUntil'
                    },
                    {
                        kind: 'block',
                        type: 'controls_for'
                    },
                    {
                        kind: 'block',
                        type: 'controls_forEach'
                    }
                ]
            },
            {
                kind: 'category',
                name: '數學',
                colour: '%{BKY_MATH_HUE}',
                contents: [
                    {
                        kind: 'block',
                        type: 'math_number'
                    },
                    {
                        kind: 'block',
                        type: 'math_arithmetic'
                    },
                    {
                        kind: 'block',
                        type: 'math_single'
                    }
                ]
            },
            {
                kind: 'category',
                name: '文字',
                colour: '%{BKY_TEXTS_HUE}',
                contents: [
                    {
                        kind: 'block',
                        type: 'text'
                    },
                    {
                        kind: 'block',
                        type: 'text_join'
                    },
                    {
                        kind: 'block',
                        type: 'text_append'
                    }
                ]
            },
            {
                kind: 'category',
                name: '變數',
                colour: '%{BKY_VARIABLES_HUE}',
                custom: 'VARIABLE'
            },
            {
                kind: 'category',
                name: '函數',
                colour: '%{BKY_PROCEDURES_HUE}',
                custom: 'PROCEDURE'
            }
        ]
    };

    // 初始化 Blockly 工作區
    const workspace = Blockly.inject('blocklyDiv', {
        toolbox: toolbox,
        grid: {
            spacing: 20,
            length: 3,
            colour: '#ccc',
            snap: true
        },
        zoom: {
            controls: true,
            wheel: true,
            startScale: 1.0,
            maxScale: 3,
            minScale: 0.3,
            scaleSpeed: 1.2
        },
        trashcan: true
    });

    // 監聽工作區變化事件
    workspace.addChangeListener(function(event) {
        if (event.type === Blockly.Events.BLOCK_CHANGE || 
            event.type === Blockly.Events.BLOCK_CREATE || 
            event.type === Blockly.Events.BLOCK_DELETE || 
            event.type === Blockly.Events.BLOCK_MOVE) {
            
            // 生成 JavaScript 程式碼
            const jsCode = Blockly.JavaScript.workspaceToCode(workspace);
            console.log('JavaScript 程式碼:', jsCode);
            
            // 生成 Python 程式碼
            const pythonCode = Blockly.Python.workspaceToCode(workspace);
            console.log('Python 程式碼:', pythonCode);
        }
    });
});

步驟三:配置選項說明

在上面的例子中,我們使用了一些配置選項來初始化 Blockly 工作區。以下是這些選項的詳細說明:

toolbox:定義工具箱的內容,包括可用的積木類別和積木類型。

grid:配置工作區的網格,包括網格間距、線長、顏色和是否自動對齊。

zoom:配置縮放功能,包括是否顯示縮放控制按鈕、是否啟用滾輪縮放、初始縮放比例、最大和最小縮放比例以及縮放速度。

trashcan:是否顯示垃圾桶圖標,用於刪除積木。

驗證安裝

完成上述步驟後,打開您的 HTML 檔案,您應該能夠看到一個功能完整的 Blockly 工作區,包括工具箱、積木拖曳區域和垃圾桶。

您可以嘗試從工具箱中拖出一些積木,連接它們,然後查看控制台中生成的 JavaScript 和 Python 程式碼。

常見問題與解決方案

問題:Blockly 工作區沒有顯示或顯示不完整

解決方案:確保容器元素(例如 `#blocklyDiv`)有明確的高度和寬度設置。Blockly 工作區的大小取決於其容器元素的大小。

問題:無法拖曳積木或工作區操作不正常

解決方案:檢查瀏覽器控制台是否有錯誤訊息。確保所有必要的 Blockly 檔案都已正確引入,並且沒有 JavaScript 錯誤。

問題:自定義積木不顯示在工具箱中

解決方案:確保您已正確定義自定義積木,並將其添加到工具箱配置中。自定義積木的定義應該在初始化工作區之前完成。

在下一章中,我們將深入探討如何使用 Blockly 的基本功能,包括積木拖曳、連接、刪除以及程式碼生成等操作。