C .
ODE
G
AMELET
# CookPixiUI 這是一個主要用於 Code.Gamelet Pixi v5 的 UI 模組。 # 元件介紹 ## ScrollView(滑動容器元件) **ScrollView** 是一個可捲動的容器元件,適用於清單、選單、物品欄等場景。 支援以下功能: - 指定顯示區域的寬度與高度 - 垂直或水平滑動方向(可選) - 拖曳滑動內容(支援滑鼠與觸控) - 慣性滾動(速度遞減) - 自動遮罩超出區域的內容 - 可動態加入或清除內容項目 ### `ScrollView.addContent(...child: PIXI.DisplayObject[]): void;` 添加內容到滑動容器中。 - `child` — 要加入的顯示物件(例如卡片、格子、圖片等) ### `ScrollView.clearContent(): void;` 清除內容容器內的所有子物件。 ### 使用範例 ```ts // 請先確保該檔案頂層有 import(引入)ScrollView class(類別) import ScrollView = CG.CookPixiUI.Components.ScrollView; ``` #### 建立垂直滑動區域 ```ts // 建立一個 300 x (畫面高度 - 100) 的垂直滑動區域 const scrollView_V = new ScrollView(300, CG.Base.pixi.stageHeight - 100, 'vertical'); scrollView_V.position.set(50, 50); CG.Base.pixi.root.addChild(scrollView_V); // 單元格尺寸設定(寬 300、高 50) const rowCellSize = { width: 300, height: 50 }; // 加入 20 個垂直排列的矩形內容 for (let i = 0; i < 20; i++) { const item = getRowItemCell(i); scrollView_V.addContent(item); } /** * 建立一個垂直列表用的彩色矩形區塊(含文字) * @param index 第幾個項目(用來標示文字與計算 Y 座標) */ function getRowItemCell(index: number): PIXI.Graphics { const item = new PIXI.Graphics() .beginFill(0xFFFFFF * Math.random()) // 隨機顏色 .drawRect(0, 0, rowCellSize.width, rowCellSize.height) .endFill(); // 設定位置(x 固定,y 根據索引排列) item.position.set(10, index * (rowCellSize.height + 10)); // 建立文字物件並加入 item 內 const label = new PIXI.Text(`Item ${index + 1}`, { fontSize: 20, fill: 0xFFFFFF, stroke: 0, strokeThickness: 4, lineJoin: 'round', } as PIXI.TextStyle); label.anchor.set(0, 0.5); label.position.set(10, 25); item.addChild(label); return item; } ``` #### 建立水平滑動區域 ```ts // 建立一個 (畫面寬度 - 450) x 150 的水平滑動區域 const scrollView_H = new ScrollView(CG.Base.pixi.stageWidth - 450, 150, 'horizontal'); scrollView_H.position.set(400, CG.Base.pixi.stageHeight * 0.5 - 75); CG.Base.pixi.root.addChild(scrollView_H); // 單元格尺寸設定(寬 80、高 100) const colCellSize = { width: 80, height: 100 }; // 加入 15 個水平排列的彩色方塊 for (let i = 0; i < 15; i++) { const item = getColItemCell(i); scrollView_H.addContent(item); } /** * 建立一個水平列表用的彩色方塊(含文字) * @param index 第幾個項目(用來標示文字與計算 X 座標) */ function getColItemCell(index: number): PIXI.Graphics { const item = new PIXI.Graphics() .beginFill(0x66ccff + (index * 0x111111)) // 每個項目不同顏色 .drawRoundedRect(0, 0, colCellSize.width, colCellSize.height, 12) .endFill(); // 設定位置(y 固定,x 根據索引排列) item.position.set(index * (colCellSize.width + 20), 25); // 建立文字物件並加入 item 內 const label = new PIXI.Text(`${index + 1}`, { fontSize: 25, fill: 0xFFFFFF, stroke: 0, strokeThickness: 5, lineJoin: 'round', } as PIXI.TextStyle); label.anchor.set(0.5); label.position.set(40, 50); item.addChild(label); return item; } ``` ## ListViewCell(清單項目元件) **ListViewCell** 是 `ListView` 所使用的 Cell 元件基底類別。 每個 Cell 對應一筆資料,並由 `ListView` 控制其建立、重用與位置配置。 主要功能: - 儲存並暴露該筆資料與索引(`data` 與 `index`) - 提供 `setItem(index, data)` 方法,用於資料更新 - 可透過 `this.view` 取得所屬 `ListView` 實例,取得 cell 尺寸或其他設定 使用方式: - 請繼承此類別並實作 UI 邏輯 - 必須實作 `setItem()`,並在內部呼叫 `super.setItem(index, data)` - 不需手動設定尺寸,請使用 `view.cellWidth` / `view.cellHeight` 注意事項: - 每個 Cell 僅代表一筆資料,不持有整份列表 - 請勿在 Cell 內進行與其他 Cell 相關的操作 ### `ListViewCell.view: ListView<ListViewCell<T>, T>;` `ListView` 實例,可經由此取得 `cellWidth`, `cellHeight` ### 使用範例 ```ts // 請先確保該檔案頂層有 import(引入)下列 class(類別) import ListViewCell = CG.CookPixiUI.Components.ListViewCell; import ListView = CG.CookPixiUI.Components.ListView; ``` #### 建立用於垂直清單的項目 ```ts /** 一個簡單的 Cell 實作,顯示數字(垂直版)。 */ export class NumberCell_V extends ListViewCell<number> { // <number> 是指這個 Cell 使用的資料格式 private _background: PIXI.Graphics; private _label: PIXI.Text; constructor(view: ListView<NumberCell_V>) { super(view); this._background = new PIXI.Graphics(); this.addChild(this._background); this._label = new PIXI.Text('', { fontSize: 20, fill: 0x333333, }); this._label.anchor.set(0.5); this._label.position.set(view.cellWidth / 2, view.cellHeight / 2); this.addChild(this._label); } /** * 設定 Cell 資料並更新顯示內容。 * @param index - 資料在列表中的位置 * @param data - 對應的資料內容,等同於上方 ListViewCell 後 <> 內的型別。 */ setItem(index: number, data: number): void { super.setItem(index, data); // 一定要呼叫,讓父類別記住 index 和 data,ListView 才能正確管理 Cell // 從 this.view 裡面取出 cell 的寬高屬性。 const { cellWidth, cellHeight } = this.view; // 重新繪製底色 this._background.clear() .beginFill(index % 2 === 0 ? 0xeeeeee : 0xdddddd) // 依據 index 決定底色,用於交錯顯示兩種顏色 .drawRoundedRect(0.5, 0.5, cellWidth - 1, cellHeight - 1, 5) .endFill(); this._label.text = `#${index} → ${data}`; } } ``` #### 建立用於水平清單的項目 ```ts /** 一個簡單的 Cell 實作,顯示數字(水平版)。 */ export class NumberCell_H extends ListViewCell<number> { // <number> 是指這個 Cell 使用的資料格式 private _background: PIXI.Graphics; private _label: PIXI.Text; constructor(view: ListView<NumberCell_H>) { super(view); this._background = new PIXI.Graphics(); this.addChild(this._background); this._label = new PIXI.Text('', { fontSize: 18, fill: 0x224466 }); this._label.anchor.set(0.5); this._label.position.set(view.cellWidth / 2, view.cellHeight / 2); this.addChild(this._label); } /** * 設定 Cell 資料並更新顯示內容。 * @param index - 資料在列表中的位置 * @param data - 對應的資料內容,等同於上方 ListViewCell 後 <> 內的型別。 */ setItem(index: number, data: number): void { super.setItem(index, data); // 一定要呼叫,讓父類別記住 index 和 data,ListView 才能正確管理 Cell // 從 this.view 裡面取出 cell 的寬高屬性。 const { cellWidth, cellHeight } = this.view; // 重新繪製底色 this._background.clear() .beginFill(index % 2 === 0 ? 0xddeeff : 0xaabbcc) // 依據 index 決定底色,用於交錯顯示兩種顏色 .drawRoundedRect(0.5, 0.5, cellWidth - 1, cellHeight - 1, 6) .endFill(); this._label.text = `${data}`; } } ``` ## ListView(清單元件) **ListView** 是一個高效能、可重用的清單元件,基於 `ScrollView` 擴充設計。 適用場景: - 大量資料需要滾動顯示的 UI(如:排行榜、物品欄、列表選單等) 主要特性: - 支援垂直與水平滾動 - 根據可視區動態建立與回收 Cell,節省效能 - Cell 實例由 `ListView` 自動管理與重用 - 每個 Cell 類別需繼承 `ListViewCell`,並實作 `setItem()` - Cell 尺寸由建構時指定(`cellWidth`, `cellHeight`),支援動態設計 注意事項: - 請勿手動新增或刪除 Cell 實例 - 若需支援自動調整 Cell 尺寸,可繼承此類別進一步擴充 ### `ListView.addData(...data: U[]): void;` 加入一筆或多筆資料,並立即更新畫面。 - `data` — 欲加入的資料內容 ### `ListView.refreshVisibleCells(): void;` 根據目前滾動位置更新可見 Cell。 - 回收不在顯示範圍內的 Cell - 產生新的 Cell,設定資料與位置 ### `ListView.jumpToIndex(index: number): void;` 瞬間跳轉到指定資料索引位置,讓該項目顯示在可視區起始處(上方或左方)。 - `index` — 欲顯示的資料索引 ### 使用範例 ```ts // 請先確保該檔案頂層有 import(引入)ListView class(類別) import ListView = CG.CookPixiUI.Components.ListView; ``` #### 建立垂直滑動區域 ```ts // 建立垂直 ListView 實例 const listView_V = new ListView<NumberCell_V, number>( 300, // 可視寬度 CG.Base.pixi.stageHeight - 100, // 可視高度 NumberCell_V, // Cell(項目條)的 Class(類別) 300, // Cell 的寬度 40, // Cell 的高度 ListView.DIRECTION.VERTICAL // ListView 的方向(垂直) ); listView_V.position.set(50, 50); CG.Base.pixi.root.addChild(listView_V); // 填入資料,生成一個 [0, 1, 2, ... , 99] 的數字陣列 const numbers = Array.from({ length: 100 }, (item, i) => i + 1); listView_V.addData(...numbers); // 跳到第 26 筆 listView_V.jumpToIndex(26); ``` #### 建立水平滑動區域 ```ts // 建立水平 ListView 實例 const listView_H = new ListView<NumberCell_H, number>( CG.Base.pixi.stageWidth - 400, // 可視寬度 100, // 可視高度 NumberCell_H, // Cell(項目條)的 Class(類別) 80, // Cell 的寬度 100, // Cell 的高度 ListView.DIRECTION.HORIZONTAL // ListView 的方向(水平) ); listView_H.position.set(350, CG.Base.pixi.stageHeight * 0.5 - NumberCell_H.height * 0.5); CG.Base.pixi.root.addChild(listView_H); // 填入資料,生成一個 [0, 1, 2, ... , 99] 的數字陣列 const numbers = Array.from({ length: 100 }, (item, i) => i + 1); listView_H.addData(...numbers); // 跳到第 50 筆 listView_H.jumpToIndex(50); ``` --- ## Authors **[cook1470](/profile/cook1470)**
# EnhServer 為了解決一些CG功能上的缺失,故實作此Lib。 包含變數無法跨專案使用,以及無法跨專案實作大聊天室。 (可能只是不知道方法) 未來將會逐步補上缺失的功能,範例後端請參照[此Github repo](https://github.com/setsuk1/EnhServer-monorepo),歡迎發起PR。 以及可以加入[Discord群組](https://discord.gg/seJwuzCbWq)一起討論,並共同討論功能方向。 初期可能不穩定,建議自建Server。 **且安全性並非此Lib的第一考量,此Lib主要是作為補充功能使用。** ## 如何使用 主要是透過下列方法進行初始化: ```typescript server.initialize(options) ``` options部分為可選選項,若參數為空則預設連線至Enh之後端伺服器。 預設狀態本模組會export一個server物件提供操作,若是希望使用多個instance,僅須透過下列方法: ```typescript const customServer = new EnhServer(); customServer.initialize(options); ``` 之後透過下列方式取得一對一傳訊的資料: ```typescript let context = { handler(data: any, senderCode: string) { console.log(data); } } server.msgManager.on(UserEventList.MSG.UNICAST, context.handler, context); ``` --- ## 呼叫功能 作為範例,下面舉出廣播至全體的功能如何使用: ```typescript let cmd = new Command(SocketEventList.USER, new BroadcastToAllEvent({ data: "Hi there." })); server.sendCommand(cmd); ``` 由此便可送出"Hi there."訊息到Server上的所有使用者。 至於其餘功能目前尚未確定如何說明,待補。 ## Authors **[EnhProject](/profile/EnhProject)** - **[不會取名字](/profile/buhuechuminzu)** - **[雪姬](/profile/setsuki)**
# three.js three.js 是一個基於 JavaScript 的瀏覽器 3D 繪圖引擎,允許開發者在網頁上輕鬆創建和顯示 3D 場景。 ## 使用方法 以下是一個簡單的範例,展示如何使用 `three.js` 創建一個基本的 3D 場景: ```ts import three = CG.ThreeJs.three; import OrbitControls = CG.ThreeJs.examples.jsm.controls.OrbitControls; function start(): void { // 初始化 three,用於自動建立場景、攝影機、渲染循環。 three.initialize(800, 600); // 建立一個軸心輔助物件,用於查看 x, y, z 的方向 const axesHelper = new THREE.AxesHelper(2); three.scene.add(axesHelper); // 添加至場景中 // 創建一個平面作為地板 const planeGeometry = new THREE.PlaneGeometry(10, 10); // 表示平面的幾何形狀 const planeMaterial = new THREE.MeshBasicMaterial({ color: 0xAAAAAA, side: THREE.DoubleSide }); // 基本紋理 const plane = new THREE.Mesh(planeGeometry, planeMaterial); plane.rotation.x = Math.PI / 2; // 平面一開始為垂直,調整 X 軸旋轉角度使其水平 three.scene.add(plane); // 將平面添加至場景中 // 創建方塊 const boxGeometry = new THREE.BoxGeometry(0.5, 0.5, 0.5); // 表示立方體的幾何形狀 const noxMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); // 基本紋理 const box = new THREE.Mesh(boxGeometry, noxMaterial); box.position.y = 0.25; // 將方塊抬高 0.25,使其貼地 three.scene.add(box); // 將方塊添加至場景中 three.camera.position.set(0, 2, 5); // 調整攝影機位置 three.camera.lookAt(0, 0, 0); // 讓攝影機看向 (0, 0, 0) // 本模組初始化時會自動建立攝影機,一般需自行建立 // 新增一個控制器,可以用滑鼠來控制攝影機的視角,像是自由旋轉、平移和縮放效果。 const controls = new OrbitControls(three.camera, three.renderer.domElement); let lastFrame = Date.now(); three.beforeRender = () => { // 你可以複寫這個函數,在渲染畫面前做點事 const currentFrame = Date.now(); // 為當前幀時間 const deltaTime = currentFrame - lastFrame; // 計算自上幀以來的時間差 lastFrame = currentFrame; // 更新 lastFrame 為當前幀時間 // 如果 controls.enableDamping 或 controls.autoRotate 設為 true 則必須每次渲染畫面前更新。 controls.update(deltaTime); // 更新 OrbitControls }; } start(); ``` ## Resources - [three.js](https://threejs.org/) - 基於 JavaScript 的瀏覽器 3D 繪圖引擎。 ## Authors **[cook1470](/profile/cook1470)**
ⒸCode.Gamelet.com | Privacy Policy | Terms of Service