C .
ODE
G
AMELET
# 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)**
# 我的視覺小說(My Visual Novel) 視覺小說遊戲的範本專案,編輯事件表就可以做出自己的視覺小說遊戲了。 - [視覺小說製作教學影片](https://www.youtube.com/live/s19SacUQ0V4?si=4j4W3RXfyPj9bNrz&t=2562) <a href="https://code.gamelet.com/edit/VisualNovelGame?source=CG.VisualNovelGame/game.events" class="mat-raised-button mat-primary">點此參考範本專案</a> ### 開始設計 <a href="cg://source/CG.VisualNovelGameTemplate/game.events" class="mat-raised-button mat-primary">點此開始創造視覺小說遊戲</a> ## 如何複製這個專案? 1. 開啟本專案。 ![開專案](https://i.imgur.com/6gkMRao.png) 2. 點擊專案代碼右側的 🍴(刀叉圖示)來複製成新的專案。 ![複製專案](https://i.imgur.com/aTfNmMJ.png) 3. 輸入你自己的專案代碼後,點摳成新專案。 ![輸入專案代碼](https://i.imgur.com/pFqUnQH.png) # 專案介紹 ![](https://i.imgur.com/dhi0NxE.png) 本專案檔案總管如上圖所示,**視覺小說遊戲的主要流程在 `game.events` 檔案內**。 另外一個 **`menu.events` 為遊戲主選單**,為有需要遊戲選單的人所新增的,若你不需要遊戲主畫面,可以參考下方修改方式。 **點進 `app.ts` 檔案**,找到如下方的程式碼,根據註解說明,**將字串後方的 `menu` 改成 `game` 即可**。 ```ts /** * 修改下方 source 的路徑字串,可以改變專案運行後初次執行的事件表 * 例如改為 'CG.VisualNovelGameTemplate/game.events' 可以直接執行遊戲 */ let source = 'CG.VisualNovelGameTemplate/menu.events'; // 請嘗試將這裡的 menu 改為 game ``` 至於該如何編輯 `menu.events` 來設計自己的遊戲主畫面,可以進入該檔案的「初始化」事件,找到「建立圖層佈局」的動作查看當前畫面佈局。 而對「建立圖層佈局」這個動作不熟悉的人,可以參考 **[【系統設計】CG 事件表的 UI 系統設計](https://www.youtube.com/live/BKRxSFObMlY?t=1000s)** 這個影片,簡單的介紹了如何使用該動作來建立自己的 UI 介面。 ## 教學資源 - 文章 - **[巴哈姆特 - 【教學】在網頁上做一個視覺小說遊戲](https://home.gamer.com.tw/artwork.php?sn=5866046)** - **[IT邦幫忙 - [Day 03] CG 同人陣的運作原理](https://ithelp.ithome.com.tw/articles/10321203)** - **[IT邦幫忙 - [Day 11] 在 CG 上公開自己的作品](https://ithelp.ithome.com.tw/articles/10328457)** - **[IT邦幫忙 - [Day 12] 設定專案封面、將成品發布到 Gamelet.online](https://ithelp.ithome.com.tw/articles/10328935)** - **[IT邦幫忙 - 什麼!在網頁上也可以寫視覺小說?](https://ithelp.ithome.com.tw/articles/10337454)** - 影片 - **[【遊戲設計】介紹在網頁上製作視覺小說遊戲](https://www.youtube.com/live/5AUGRityOec?t=189s)** - **[【系統設計】CG 事件表的 UI 系統設計](https://www.youtube.com/live/BKRxSFObMlY?t=1000s)** - **[【遊戲設計】視覺小說引擎更新報告!](https://www.youtube.com/live/s19SacUQ0V4?t=1092s)** - **[【教學】視覺小說引擎-迷霧特效【CC 字幕】](https://www.youtube.com/watch?v=MyXBfAL2BJQ)** - 本站討論串 - **[變數決定結局](https://code.gamelet.com/discuss/p/liaw1/issue/3698/0)** - **[分支選項設置](https://code.gamelet.com/discuss/coding/topic/3706)** ## 作者 **[cook1470](/profile/114899766849308759711@google)**
# TestTube TestTubes is a simple library for the CG platform. ## Usage ### Basic Usage First, import the required functions from the library: ```typescript const {test, expect, runTests} = CG.TestTube; ``` ### Writing Tests You can write tests using the `test` function. Each test is defined with a description, a test function, and optional tags for categorization: ```typescript test("adds numbers correctly", () => { expect(1 + 2).toBe(3); }, ["math"]); ``` ### Running Tests To run all registered tests, use the `runTests` function: ```typescript runTests(); ``` You can also run tests with a specific tag: ```typescript runTests("math"); ``` ### Assertions TestTubes provides a simple `expect` function to make assertions, including: - `toBe(expected)`: Asserts that the actual value is strictly equal to the expected value. - `toEqual(expected)`: Asserts that the actual value is deeply equal to the expected value. - `toBeTruthy()`: Asserts that the actual value is truthy. - `toBeFalsy()`: Asserts that the actual value is falsy. - `toThrow(expectedMessage?)`: Asserts that the actual function throws an error, optionally matching the expected message. ### Example Here's a very simple example demonstrating the usage of TestTubes for a simple math library and a DOM manipulation library: ```typescript const {test, expect, runTests} = CG.TestTube; // Math library export const MathLib = { add(a: number, b: number): number { return a + b; }, subtract(a: number, b: number): number { // Typing error return a + b; }, multiply(a: number, b: number): number { return a * b; }, divide(a: number, b: number): number { if (b === 0) throw new Error("Cannot divide by zero"); return a / b; } }; // DOM manipulation library export const DomLib = { createElement(tag: string, content: string): HTMLElement { const element = document.createElement(tag); element.textContent = content; return element; }, appendToBody(element: HTMLElement): void { document.body.appendChild(element); } }; // Math library tests test("adds numbers correctly", () => { expect(MathLib.add(1, 2)).toBe(3); }, ["math"]); test("subtracts numbers correctly", () => { expect(MathLib.subtract(2, 1)).toBe(1); }, ["math"]); test("multiplies numbers correctly", () => { expect(MathLib.multiply(2, 2)).toBe(4); }, ["math"]); test("divides numbers correctly", () => { expect(MathLib.divide(4, 2)).toBe(2); }, ["math", "division"]); test("throws error when dividing by zero", () => { expect(() => MathLib.divide(4, 0)).toThrow("Cannot divide by zero"); }, ["math", "division"]); // DOM manipulation tests test("creates an element with correct tag and content", () => { const element = DomLib.createElement("div", "Hello, World!"); expect(element.tagName.toLowerCase()).toBe("div"); expect(element.textContent).toBe("Hello, World!"); }, ["dom"]); test("appends an element to the body", () => { const element = DomLib.createElement("div", "Appended Element"); DomLib.appendToBody(element); expect(document.body.contains(element)).toBeTruthy(); }, ["dom"]); // Run all tests runTests(); // Optionally run only tests with a specific tag // runTests("math"); ``` The output looks like this: ```text Running 7 tests... ✅ adds numbers correctly ❌ subtracts numbers correctly Expected 3 to be 1 ✅ multiplies numbers correctly ✅ divides numbers correctly ✅ throws error when dividing by zero ✅ creates an element with correct tag and content ✅ appends an element to the body ``` ## API ### `test(description: string, fn: TestFunction, tags: string[] = [])` Registers a new test. - `description`: A description of the test. - `fn`: The test function to execute. - `tags`: Optional tags to categorize the test. ### `runTests(tag?: string)` Runs all registered tests, or only tests with the specified tag. - `tag`: Optional tag to filter tests to run. ### `expect(actual: unknown)` Creates an expectation for a value. Returns an object with assertion methods. ## Authors **[FOBShippingPoint](/profile/FOBShippingPoint)**
ⒸCode.Gamelet.com | Privacy Policy | Terms of Service