C .
ODE
G
AMELET
# TwilightWarsEventsExp 本專案為光暈戰記的擴充模組,主要是建立在 **[TwilightWarsLib](/edit/TwilightWarsLib)** 的基礎之上,添加一些小東西。本專案並不包含 **[TwilightWarsEvents](/edit/TwilightWarsEvents)** 模組。 本模組並不會覆蓋原有的動作、檢查,所有本模組新增的檢查、動作等,都會被整合在**光暈戰記 / 擴充包**內,且不會新增任何跟光暈無關的檢查或動作,希望是一個純淨的光暈模組,跟光暈無關的相關事件,有需要的話會在 **[CgEventsExp](/edit/CgEventsExp)** 做更新。 本專案開放查詢原始碼,所有的檢查、動作,皆有在本專案的 **Test** 資料夾內做實際範例,歡迎自行查看使用方法,也歡迎自行進入程式區內,看各個檢查、動作是如何完成。 本人希望弄一個可以讓大家互相交流、維護,甚至更新的這麼一個光暈同人模組,我覺得這樣共同成長,才會讓嘎母變得更成熟,所以如果你有什麼好想法,也都歡迎提供給我。 另外個人創了一個第三方的 **[嘎母討論區(Discord)](https://discord.gg/hZKQzRfPJM)** ,主要是希望大家有一個好的交流平台,可以一起討論一些設計,除了光暈,還有其他非光暈的專案等等,甚至是能夠一起合作,讓作者們有機會推出更多優質的作品。 有任何 BUG 的話都歡迎回報,會盡量在最短的時間內處裡掉。 **[Google 試算表 - 光暈戰記](https://docs.google.com/spreadsheets/d/1kRPdI6caisjZuHJGmCjB3kHBveR2RVAeTJoyCmqOZVs/edit?usp=sharing)** 本專案有些需要查詢的地方,例如武器道具的索引值等等,可以由此試算表查詢。 ## 其他工具 - [ImageIndex 查詢器](https://paint.gamelet.online/?version=0.0.27) ## 作者 **[cook1470](/profile/cook1470)**
# 花靈宮模組 - 作者 **[妮娜](/profile/LoliPrincessNina)** - 使用此模組為你的專案增加新的陣營和技能 - 注意電腦AI使用技能時有機會比較蠢 - 過快使用技能將會有概率出BUG - 此為測試版本,有BUG很正常 - 查詢及回報請到<b><a href="https://gamelet.online/user/nina/board">我的留言板</a></b> # 說明 - 為了方便各位照搬/測試花靈宮的任務,此處將填上花靈宮裡所有用到的觸發/檢查/動作 - 有相當一部分代碼是來自TwilightWarsEventsExp和CgEventsExp(下方不列出;部分存在變更,與原版有差異) - 若希望使用以上觸發/檢查/動作,請用原版,此處不會有更新 ## 目前提供支援的有: ## 陣營 - 花靈宮 - 盜賊幫 - 無魂軍 - 智械兵團(缺失: 小刀LV2、大刀LV2、冰劍LV1) <!-- --> ## 觸發 #### 角色 - 角色說話 - 人物受傷(內建排除傷害類型/傷害數值比對) #### 武器道具 - 使用消耗型道具(可儲存道具變數) <!-- --> ## 檢查 #### 技能 - 角色技能狀態 - 手持武器技能 #### 角色 - 角色狀態附加 - 角色面向某物 - 角色燃燒狀態 - 角色B是否角色A的敵人 #### 地圖 - 可行走座標 - 兩點之間的距離 #### 存讀 - 儲存變數 - 在陣列中找到字串 - 以符號分離字串 #### 地圖機關 - 燭火機關狀態 - 找出所有地圖機關(迴圈) <!-- --> ## 動作 - 筆記 #### 角色 - 新增角色 - 角色漂浮能力 - 設定角色演員 - 移動角色位置 - 設定角色大小 - 角色可否攻擊 - 角色死亡訊息 - 人物停止說話 - 角色特殊屬性 - 取得玩家陣營演員角色 - 角色醉酒管理 - 角色反彈子彈 - 放下旗幟 - 鎖定面向方向 - 傳送角色加血訊息 - 傳送角色傷害訊息 - 傳送角色閃現至定點訊息 #### 技能 - 角色結束技能 - 限制使用技能 - 設定武器技能 - 傳送技能訊息 #### 任務流程 - 跳出系統訊息 - 更多遊戲規則 - 角色對己說話 - 改變任務代碼 #### 存讀 - 工作階段儲存空間數據庫存取 - 以符號分離字串 - 定義Json變數 - 轉換Json為字串 - 轉換Json為物件 #### 特效 - 聖靈治療特效 - 白鳥拳 - 角色燃燒狀態 - 應用攻擊特效 - 震地特效 - 吸血血刃特效 - 劍氣光彈 - 新增地圖痕跡 - 散發冰氣特效 - 發射火箭 - 快跳文字 - 散發光環特效 - 衝擊波 - 新增地圖動畫 - 擊退人物 - 光印 - 冷卻特效 - 防護罩特效 - 防護罩泡泡特效 - 冰魂護盾特效 - 血滴特效 - 設置自動移除動畫 #### 武器道具 - 背包道具設定 - 攜帶式道具設定 - 切換預設武器 - 切換至另一手 - 裝填武器彈藥 - 新增任務道具 - 新增武器道具 - 人物裝備道具 - 人物裝備武器 - 移除武器道具 - 玩家背包道具擁有的數量 #### 地圖 - 隨機可行走座標 #### 隨機 - 隨機設定陣營 - 隨機角色演員 - 隨機使用技能 - 隨機物件代碼 - 隨機字串 - 隨機角色 #### 陣營 - 設定陣營暱稱 - 新增陣營 - 改變陣營色彩風格(4個子項被拆分成2個新動作) #### 地圖機關 - 控制燭火機關 - 新增可推石塊 - 新增告示牌(NPC角色包括同人陣營選項)
# TwilightWarsLib A Top-down view shooting game framework. ## Getting Started These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. To start a .event ```typescript CG.TwilightWarsLib.initialize() .then(() => { CG.TwilightWarsLib.events.startEvents('test/test.events', 'arena'); }) ``` To manually setup the game: ```typescript CG.TwilightWarsLib.initialize() .then(() => let mapSource = 'test/test.twmap'; CG.Base.resourceManager.addAppSource(mapSource); CG.Base.resourceManager.load(() => { let mapResource = new CG.TWMap.resources.MapResource(); mapResource.importBase64(CG.Base.resourceManager.getText(mapSource)); mapResource.loadTextures(() => { CG.Base.pixi.initialize(600, 500); let game = new CG.TwilightWarsLib.games.Game(); CG.Base.pixi.root.addChild(game); game.initResources(mapResource); game.start(); console.log('tw game created'); let me = new CG.TwilightWarsLib.games.actors.Actor(game, 'me'); game.addActor(me, new MyActorController(me), 32, 100, 0, null); game.gameCamera.setFocus(me); game.interface.setMe(me); let ai = new CG.TwilightWarsLib.games.actors.Actor(game, 'ai'); ai.camp = CG.TwilightWarsLib.games.datas.Camp.CAMP2; ai.actorClip.headClip.clip.gotoAndStop(5); game.addActor(ai, new CG.TwilightWarsLib.games.actors.controllers.AIController(ai), 160, 300, 0, null); game.createStuff(null, 64 + 16, 128 + 16, CG.TwilightWarsLib.games.items.StuffInfo.getByCode('sword'), game.stuffManager.useNextStuffId(), true); }); }); }) ``` ## Versioning We use [SemVer](http://semver.org/) for versioning. ## Authors * **[Haskasu](/profile/Haskasu)** ## Acknowledgments * Hat tip to anyone who's code was used * Inspiration * etc
# 視覺小說引擎(VisualNovelEngine) 本專案主要是用來製作視覺小說用的。 <a href="cg://source/CG.VisualNovelEngine/README.ja.md" class="mat-raised-button mat-primary">日本語版を見る</a> <a href="cg://source/CG.VisualNovelEngine/README.en.md" class="mat-raised-button mat-primary">View English Version</a> 目前主要把最基本的場景、對話框、人物立繪、選項完成了,剩下的就是各種特效了,還有最麻煩的存檔系統。 想要更進一步討論關於此模組的人,可以加入 **[Discord - 嘎姆討論區](https://discord.gg/hZKQzRfPJM)** ,這是我個人自行創建的非官方 Discord 伺服器。 或是我的 Discord 使用者名稱(Username)為:`cook1470`,若不想加入群組的人,也可以直接加我 DC 喔! <font color=red>**本模組仍處於測試、開發階段,如有任何 BUG、功能不完善等問題,歡迎於討論區提出、回報,或是直接 Discord 找我也可以!**</font> 為協助優化本模組,歡迎填寫協助 **[回饋問卷](https://forms.gle/PUckLReQgFK7i7Z68)** 。 **[範例遊戲專案](https://code.gamelet.com/edit/VisualNovelGame?source=CG.VisualNovelGame/example.events)** ## 相關資源 - 文章 - **[巴哈姆特 - 【教學】在網頁上做一個視覺小說遊戲](https://home.gamer.com.tw/artwork.php?sn=5866046)** - **[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/watch?v=5AUGRityOec)** - 本站討論串 - **[變數決定結局](https://code.gamelet.com/discuss/p/liaw1/issue/3698/0)** - **[分支選項設置](https://code.gamelet.com/discuss/coding/topic/3706)** ## 網友成品遊戲列表 - **[小又生日活動【異世界大冒險】](https://a2569.gamelet.online/)** - **[God](https://godblesses.gamelet.online/)** - **[平凡的一天](https://dinvmip.gamelet.online/)** ## 作者 **[酷可](/profile/64897095@github)([Youtube](https://www.youtube.com/channel/UCe4mAxtv7eWFU2FDp6bMVVg)、[X](https://x.com/cook1470))** ## 素材網站推薦 - 背景圖 - **[みんちりえ](https://min-chi.material.jp/)** - **[KNT graphics](http://kntgraphics.web.fc2.com/)** - 角色立繪 - **[わたおきば](https://wataokiba.net/)** - 音訊 - **[フリー音楽素材 H/MIX GALLERY](http://www.hmix.net/)** - **[魔王魂](https://maou.audio/)** <a href="cg://source/CG.VisualNovelEngine/README.ja.md" class="mat-raised-button mat-primary">日本語版を見る</a> <a href="cg://source/CG.VisualNovelEngine/README.en.md" class="mat-raised-button mat-primary">View English Version</a>
# GLT One Paragraph of the game description goes here ## Getting Started ### Auth (Login) ```typescript // All action must wait until auth system is ready. CG.GLT.auth.onReady(user => { if(user.isLocalGuest()) { // not login yet } else { // logged in user } }); // auth event listener, triggered when auth user changed let authListener = CG.GLT.auth.onAuth(user => { if(user.isLocalGuest()) { // logged out } else { // logged in user } }); // auth event listener, triggered when validating a new auth action // a following onAuth event is expected. this.validatingListener = onAuthValidating(() => { // show loading animation }); ``` ### API The CG.GLT.api is responsible to communicate with glt.gamelet.online. CG.GLT.commands includes all comments to query/submit data from glt.gamelet.online. The commands has a function submit() that uses CG.GLT.api.submitCommand(), so most of the time, you don't need to call the api to submit. ```typescript CG.GLT.commands.scoreService.submitScore( 'challenge', // the name of the score to submit 10, // the score SubmitType.KEEP_HIGHEST, // submit only when the new score is greater than the one on server TimeRange.ALL // submit to all time-ranges (history and weekly) ) .submit(); // to receive the weekly high score list CG.GLT.commands.scoreService.listScores( 'challenge', // the name of the scores to get TimeRange.WEEKLY, // in which time range OrderType.HIGH_TO_LOW, // how to order the scores CG.GLT.api.lastUpdatedServerTimestamp, // tell the server which week to see 0, // start index 10, // how many to get (list: UserScoreList) => { // do something with the scorelist }, (error) => { // deal with error } ) ``` ## Authors **[Haskasu](/profile/113321052805704333314@google)**
# CG.Base Provide tool kits that helps you fast build an app on Code.Gamelet. Key features include: 1. initialize [pixi.js](#pixi.init) environment 1. load and access resources that are imported via Code.Gamelet IDE 1. manage update functions that are called every frame 1. provide debug utilities ## Getting Started Follow the steps below to fast start an app with [PixiJS](#pixi.init). We will implement a box2d environment to demo the usage of Base. <a name="pixi.init"></a> ## Start with Pixi.js<a name="pixi.init"></a> ```typescript class App { constructor() { // initialize pixi CG.Base.pixi.initialize(600, 400); CG.Base.pixi.physicsDebugDraw.setActive(true); // make a physics wall var wall = CG.Base.physics.createPhysicsObject('wall', {type: 'static'}); wall.addEdge(new CG.Base.geom.Point(10, 300), new CG.Base.geom.Point(500, 330)); // make a dynamic physics ball var ball = CG.Base.physics.createPhysicsObject('ball', {type: 'dynamic'}); ball.addCircle(0, 0, 10, {friction: 0.1, density: 0.1, restitution: 0.3}); ball.setPosition(100, 10); } } new App(); ``` @see [Demo](/edit/Base_Start_with_PIXI) ## Load and play with Resources To load resources that are imported from IDE: ```typescript // tell resources what resources to load (using the alias names) CG.Base.resourceManager.addAppResource('Game1.button'); CG.Base.resourceManager.addAppResource('Game1.music'); // start loading CG.Base.resourceManager.load(() => { // all loaded callback // create button with the image "Game1.button" alias name var button = new CG.Base.pixis.interactive.Button(CG.Base.resourceManager.createPixiSprite('Game1.button', 20, 20)); // set the position of the button button.displayObject.position.set(100, 100); // add the button to pixi.root, so pixi can render the button CG.Base.pixi.root.addChild(button.displayObject); // add a click event listener button.on(CG.Base.pixis.interactive.Button.EVENT.CLICK, () => { // when the button is clicked, play sound with "Game1.music" alias name CG.Base.resourceManager.playSound('Game1.music') }); }); ``` @see [Demo](/edit/Base_Load_Resources) ## Manage update functions Take advantage of CG.Base.addUpdateFunction to make a function called every frame ```typescript class App { constructor() { CG.Base.pixi.initialize(600, 400); CG.Base.addUpdateFunction(this, this.update); } // this function will be called every frame(called 60 times per second normally) private update(deltaTime:number):void { // do something } } new App(); ``` @see [Demo](/edit/Base_Update_and_Delay_Func) You can call a function in the future by CG.Base.addDelayFunction ```typescript class App { constructor() { CG.Base.pixi.initialize(600, 400); // call this.delayAction in 1000 milliseconds(= one second) CG.Base.addDelayFunction(this, this.delayAction, 1000); } private delayAction():void { // do something } } new App(); ``` @see [Demo](/edit/Base_Update_and_Delay_Func) ## Interact with Keyboard Use CG.Base.keyboard package to interact with keyboard events. ```typescript export class App { constructor() { // make the window focused, so we can receive keyboard events. window.focus(); // initialize pixi CG.Base.pixi.initialize(600, 400); // tell resourceManager to load the resource 'Game1.button' CG.Base.resourceManager.addAppResource('Game1.button'); // load resources, and wait callback when resources are all loaded CG.Base.resourceManager.load(() => { // add keyboard event listener, when a key is pressed CG.Base.keyboardManager.on(CG.Base.keyboard.KeyboardManagerEvent.PRESSED, key => { // if the pressed key is space, we call this.createSprite() if (key == CG.Base.keyboard.Key.SPACE) { this.createSprite(); } }); }); } private createSprite(): void { // create a sprite with the image 'Game1.button' var sprite: PIXI.Sprite = CG.Base.resourceManager.createPixiSprite('Game1.button'); // set the position of the sprite sprite.position.set(CG.Base.utils.IntUtil.randomBetween(100, 500), CG.Base.utils.IntUtil.randomBetween(100, 300)); // add the sprite to pixi.root, so it can be rendered CG.Base.pixi.root.addChild(sprite); } } new App(); ``` @see [Demo](/edit/Base_PIXI_Keyboard) ## Debugging The best debug tool on browser is the [developer tools](https://developer.chrome.com/devtools) in Chrome (F12). To find your source code in developer tools, first open developer tools(F12), click "Sources" tab, and search the Network tree as below: > top => {projectCode} => gameFrame => code.gamelet.com => gassets => file/{projectCode}/src for example, if the projectCode is 'Game1', source code is located at > top => Game1 => gameFrame => code.gamelet.com => gassets => file/Game1/src ![Source Network Tree](https://code.gamelet.com/gassets/asset/Base/Base.networktree/networktree.png "Source Network Tree") ### Add Watch In addition to browser's debugging tools, CG.Base provides other useful tools. CG.Base.addWatch() adds objects or objects' properties to Watch panel in CG IDE. ```typescript export class App { constructor() { // initialize pixi CG.Base.pixi.initialize(600, 400); // tell resourceManager to load the resource 'Game1.button' CG.Base.resourceManager.addAppResource('Game1.button'); CG.Base.resourceManager.load(() => { // add the created sprite into Watch panel, the alias name in Watch panel is 'sprite' CG.Base.addWatch('sprite', this.createSprite()); }); // add this(App)'s 'time' property into Watch panel. The alias name for this property is 'now' CG.Base.addWatch('now', this, 'time'); } private createSprite(): PIXI.Sprite { // create a sprite with the image 'Game1.button' var sprite: PIXI.Sprite = CG.Base.resourceManager.createPixiSprite('Game1.button'); // set the position of the sprite sprite.position.set(CG.Base.utils.IntUtil.randomBetween(100, 500), CG.Base.utils.IntUtil.randomBetween(100, 300)); // add the sprite to pixi.root, so it can be rendered CG.Base.pixi.root.addChild(sprite); return sprite; } // a getter function, that works like a property of App object. get time(): number { return CG.Base.time(); } } new App(); ``` @see [Demo](/edit/Base_Add_Watch) ## Versioning We use [SemVer](http://semver.org/) for versioning. ## Links and Resources This library is running with the libraries below. * [Pixi.js](http://www.pixijs.com/) - 2D rendering engine * [API reference](http://pixijs.download/release/docs/index.html) * [Examples](http://pixijs.io/examples/) * [Pixi keyboard](https://github.com/Nazariglez/pixi-keyboard) - Keyboard utility * [Pixi sound](https://github.com/pixijs/pixi-sound) - Sound utility * [Pixi filters](https://github.com/pixijs/pixi-filters) - Filters Collections * [Pixi GafPlayer](https://github.com/mathieuanthoine/PixiGAFPlayer) - [GafMedia](https://gafmedia.com/) Player * [Liquidfun](http://google.github.io/liquidfun/) - Box2D based physics engine * [MD5](http://www.myersdaily.org/joseph/javascript/md5-text.html) - MD5 implementation by Joseph Myers ## Authors **Haska Su** - *Initial work*
# 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)**
# Base2 重新架構的Base2,相比Base少了很多功能,包括Pixi/Sound/ResourceManager/Physics/geoms都被拿掉,只留最主要的CG功能。 ## 基本功能 1. 取得專案的資料 ```typescript // 取得專案代碼 CG.Base2.projectCode; // 取得資源 CG.Base2.getAppResource(resourceAlias: string) // 取得資源網址 CG.Base2.getAppResourceFileUrl(resourceAlias: string, filename?: string) ``` ## 更新循環 Base2內建了一個更新循環系統。 ```typescript // 先定義一個每幀都要更新的函式 function updateFunc(dt: number) { } // 將函式加入更新循環系統 CG.Base2.addUpdateFunction(updateFunc); // 將函式移出更新循環系統 CG.Base2.removeUpdateFunction(updateFunc); ``` 另外也提供子更新循環系統可使用。 ```typescript import Updater = CG.Base2.utils.Updater; // 先定義一個每幀都要更新的函式 function updateFunc(dt: number) { } // 建立子更新循環系統 let updater = new Updater(); // 將函式加入更新循環系統 updater.addDelayFunction(updateFunc); // 可暫停 updater.pause(); // 可繼續 updater.resume(); ``` ## 鍵盤管理員 Base2提供了一個基本的鍵盤管理員,可以在按鍵被按下去(DOWN)、提起來(UP)、先按再提(PRESSED)的時候觸發事件。 ```typescript // 取得鍵盤管理員 import Keyboard = CG.Base.keyboards.Keyboard; import keyboard = CG.Base2.keyboard; import Key = CG.Base2.keyboards.Key; // 鍵盤事件 keyboard.on(Keyboard.EVENT.DOWN, (event: KeyboardEvent) => { if (Key.SPACE.matchEvent(event)) { // 當空白鍵被按下去的時候... } }) // 檢查目前按鍵狀態 if (keyboard.isDown(Key.SPACE)) { // 目前空白鍵是正在按下去的狀態 } ``` ## 補間變化 Base2內建了[tweenjs](https://github.com/tweenjs/tween.js)用來將某個物件的屬性,在一段時間內作動態的變化。 ```typescript async function makeAnimation() { // 建立一隻有x,y資料的動物 let animal = { x: 100, y: 100, }; // 建立補間變化,在1秒內讓動物的x和y變化到指定的值 let tween = new TWEEN.Tween(animal); tween.to( { x: 300, y: 200, }, 1000 // 毫秒 ); tween.start(); // 等待變化完畢 await CG.Base2.waitTween(tween); console.log(animal.x); // 這時會印出 300 } ``` ## JSZip Base2內建[JSZip](https://stuk.github.io/jszip/)。 ```typescript async function loadZip() { let zip = new JSZip(); await zip.loadAsync(buffer); for(let filename in zip.files) { ... } } ```
# PixiGif Add [GIF](https://en.wikipedia.org/wiki/GIF) 89a (animated GIF) support for pixi.js. ## Getting Started Add GIF image alias to resourceManager as regular resources, and create a GifSprite by CG.PixiGif.createGifSprite(); ```typescript let resourceAlias = 'PixiGif.anim'; CG.Base.resourceManager.addAppResource(alias); CG.Base.resourceManager.load(() => { CG.Base.pixi.initialize(300, 300); // create a GifSprite, attach to pixi.root and play the animation let sprite = CG.PixiGif.createGifSprite(resourceAlias); CG.Base.pixi.root.addChild(sprite); sprite.play(); }); ``` You can setup custom sequences by any combination of frames. ```typescript let sprite = CG.PixiGif.createGifSprite(resourceAlias); sprite.addSequence('jump', [1,3,5]); // define a sequence named jump sprite.setSequence('jump', true); // set jump as the current sequence, and play ``` You can listen to events from GifSprite ```typescript let sprite = CG.PixiGif.createGifSprite(resourceAlias); sprite.on('frameChanged', (sp) => console.log('the frame is just changed')); sprite.on('complete', (sp) => console.log('the animation is complete and stopped')); sprite.on('play', (sp) => console.log('just starts playing the animation')); sprite.on('stop', (sp) => console.log('the animation is stopped')); sprite.on('end', (sp) => console.log('the animation plays to the end of the sequence')); ``` #### References - [GIF reader by Dean McNamee](https://github.com/deanm/omggif) - [GIF Format](http://www.onicos.com/staff/iz/formats/gif.html)
# PIXI 文字輸入框(PixiTextInput) 基於 Mwni 的函式庫改編而來, 這個 PIXI.js 的模組提供了一種方便的方法來將文字輸入框添加到 PIXI.js 舞台上。輸入框本身是一個 HTML \<input\> 元素,根據 PIXI.DisplayObject 給定的變換位置放置在舞台上方。方框會在 PIXI 舞台上繪製。此外,您可以選擇在文字輸入框失去焦點時,選擇是否應該用 PIXI.Text 來替代 \<input\>。 ## 我的改動 v0.0.1 1. 事先宣告 Class 的屬性變數,因為 TypeScript 在使用 `this` 賦值前,需要事先宣告屬性變數。 2. 將所有帶有 _ 前綴的屬性、函數,變成私有屬性(`private`)。 3. 修正了一個把 `_dom_visible` 誤寫成 `dom_visible` 的 BUG。 4. 添加了三個 `interface`,`TextInputOptions、TextInputStyle、TextBoxStyle`,並於部分輸入參數加上型別標註。 5. 刪除函數 `renderWebGL`、`renderCanvas`,這些函數用於支援 pixi v4,但此模組使用的 pixi 為 v5,因此不需要這些函數。 6. 讓 _surrogate.resolution 預設為 2。 7. 修正部分因 JavaScript 源碼,轉移到 TypeScript 後所出現的錯誤提示,如型別錯誤等。 其餘詳見 CHANGELOG.md ## 使用範例 ```typescript import pixi = CG.Base.pixi; import TextInput = CG.PixiTextInput.TextInput; function examples() { // 初始化 pixi 舞台 pixi.initialize(600, 500); // 建立文字輸入框 const input = new TextInput({ input: { fontSize: '25pt', padding: '14px', width: '500px', color: '#26272E' }, box: { fill: 0xE8E9F3, rounded: 16, stroke: { color: 0xCBCEE0, width: 4 } } }) input.position.set(pixi.stageWidth * 0.5, pixi.stageHeight * 0.5); // 調整輸入框的位置 input.pivot.set(input.width * 0.5, input.height * 0.5); // 調整輸入框的錨點 pixi.root.addChild(input); // 將文字框添加到舞台中 const input2 = new TextInput({ input: { fontSize: '20pt', padding: '14px', width: '400', color: '#26272E' }, box: { fill: 0xFFFFFF, rounded: 16, stroke: { color: 0x333333, width: 4 } } }) input2.position.set(pixi.stageWidth * 0.5, pixi.stageHeight * 0.75); input2.pivot.set(input.width * 0.5, input.height * 0.5); pixi.root.addChild(input2); } examples(); ``` ## 屬性 **substituteText** : boolean > 當沒有焦點時,插件是否應該將 HTML 的 input 標籤替換為 pixi-Text DisplayObject。 > > 本模組盡量模仿 HTML input 元素的外觀,但是在某些字體/樣式下可能會有一些差異。 > > 將此設置為 false 以便 HTML input 元素始終可見。缺點是:你無法在輸入欄位上方顯示疊加層。 **placeholder** : string > 應用於 HTML input 元素或替代的 pixi-Text 的佔位符文字。 **placeholderColor** : int > 佔位符的顏色(當 `substituteText` 設置為 false 時無效;使用 CSS 設置佔位符顏色)。 **text** : string > HTML input 元素的文字(值)。 **maxLength** : int > 文字的最大長度。 **restrict** : RegExp | string > 限制輸入文字的字符集。可以傳遞包含所有可能字符的字符串或正則表達式,正則表達式將與整個輸入字符串匹配。 **htmlInput** : HTMLInputElement > 直接訪問原生 HTML input 元素。不知道你計劃做什麼。 **disabled** : boolean > 設置為 true 以禁用輸入。 ## 函數 **focus()** : void > 使輸入元素獲得焦點。 **select()** : void > 使輸入元素獲得焦點並選中其中的文字。 **blur()** : void > 移除輸入元素的焦點。 **setInputStyle( key:string, value:string )** : void > 更改輸入元素的 CSS 樣式屬性。例如,要更改字體大小,使用:<br/> > `input.setInputStyle('fontSize', '21px')` ## 事件 所有事件都通過默認的 pixi EventEmitter 發送。 ```ts input.on('keydown', keycode => { console.log('key pressed:', keycode) }) ``` **keydown** -> keycode: number > 當按下某個鍵時連同其[鍵碼](http://keycode.info/)一起發送。 **keyup** -> keycode: number > 當釋放某個鍵時連同其[鍵碼](http://keycode.info/)一起發送。 **input** -> text: string > 當輸入文字改變時連同當前輸入的文字一起發送。 **focus** > 當輸入元素獲得焦點時發送。 **blur** > 當輸入元素失去焦點時發送。 ## Links and Resources - [pixi-text-input](https://github.com/Mwni/pixi-text-input) ## Authors **[cook1470](/profile/cook1470)**
<center><strong> <font size=5> <font color=EA7869> # 光暈戰記武器素材擴充包(TwilightWarsWeaponsResource) </font> </font> </strong><br> <font color=7869EA> <strong> <font size=4> <font color=7869EA> # 本模組為光暈戰記同人陣添加多種武器外觀 </font> </font> </strong><br> <strong> <font size=4> <font color=EA7869> <details> <summary> <strong> <font size=4> <font color=EA7869> ## 手動新增自創武器教學(點擊打開) </font> </font> </strong> </summary> <br> <font color=7869EA> 點開事件表(.events)的<strong>光暈戰記遊戲設定</strong> <br><br> ![](https://i.imgur.com/bnCBKkk.png) <br><br> 找到下方的<strong>自製近身武器</strong>與<strong>自製遠程武器</strong> <br><br> ![](https://i.imgur.com/Al86kNu.png) </font><br><br><br> <strong> <font size=4> <font color=EA7869> </details> <details> <summary> <strong> <font size=4> <font color=EA7869> ## 預置武器修改教學(點擊打開) </font> </font> </strong> </summary> <br> <font color=7869EA> <a href="cg://source/CG.TwilightWarsWeapons/Preset.events" class="mat-raised-button mat-primary">預置事件表</a> <br><br> 找到最左側<strong>檔案總管</strong>內,<strong>CG.TwilightWarsWeapons</strong> 之中的<strong>Preset.events</strong>,右鍵<strong>複製檔案</strong>,更新後就不會遺失改過的設定 <br><br> ![](https://i.imgur.com/svcKdMk.png) <br><br> 找到複製後的<strong>Preset_copy.events</strong>,接著就能依照自己的喜好修改預置武器 <br><br> ![](https://i.imgur.com/Cuu5mUp.png) <br><br> 改完之後,找到需要使用自創武器的事件表選擇<strong>設定</strong> <br><br> ![](https://i.imgur.com/JBQr85k.png) <br><br> 在<strong>預先載入</strong>的地方把剛剛的<strong>Preset_copy.events</strong>打勾,就可以使用裡面的武器了 <br><br> ![](https://i.imgur.com/cd1zJkg.png) <br><br> </font> </details> <details> <summary> <strong> <font size=4> <font color=EA7869> ## 預置武器事件表更新教學(點擊打開) </font> </font> </strong> </summary> <br> <font color=7869EA> 首先刪除原本在 CG.TwilightWarsWeapons 資料夾中的<a href="cg://source/CG.TwilightWarsWeapons/Preset.events" class="mat-raised-button mat-primary">預置事件表</a> <br><br> 接著更新模組 <br><br> 打開最新版本的<a href="cg://source/CG.TwilightWarsWeapons/Preset.events" class="mat-raised-button mat-primary">預置事件表</a> <br><br> 點開右上角的**編輯原始資料(JSON)** <br><br> ![](https://i.imgur.com/QH5bVdp.png) <br><br> 找到武器代碼,從上方**逗號與大括號**一次框選到下方相對位置的**大括號**(可以從顏色判斷)並複製 <br><br> ![](https://i.imgur.com/iOI38jq.png) <br><br> ![](https://i.imgur.com/MyDAyGa.png) <br><br> 最後複製到 **自己的** 預置武器事件表之中的對應位置內就完成了 <br><br> ![](https://i.imgur.com/QH5bVdp.png) <br><br> </font> </details> <strong> <font size=5> <font color=EA7869> ## 作者 </font> </font> </strong> <strong> <font size=5> <font color=7869EA> 阝千翎 </font> </font> </strong> **[<img src="https://gamelet.online/clients/assets/v1/img/cg_logo.png" width="30px" /><a href="https://code.gamelet.com/profile/Chinatsu" target="_blank" style="color:#55BBFF;">CG](/profile/117336754650487480063@google)**</a> **[<img src="https://gamelet.online/clients/assets/v1/img/gamelet_icon.png" width="30px" /><a href="https://gamelet.online/user/117336754650487480063@google/board" target="_blank" style="color:#55BBFF;">嘎姆](https://gamelet.online/user/117336754650487480063@google/board)**</a> **[<img src="https://play-lh.googleusercontent.com/Qolm5gr9jnabjk-0z79srjYC1XPVExribNz5kbDmGJeEtmRlo0UQoQEIkKMHRyt5paw" width="30px" /><a href="https://www.youtube.com/channel/UCALDNiLyfHERP13-BG9xpFQ?sub_confirmation=1" target="_blank" style="color:#55BBFF;">YouTube](https://www.youtube.com/channel/UCALDNiLyfHERP13-BG9xpFQ?sub_confirmation=1)**</a> **[<img src="https://cdn-icons-png.flaticon.com/256/1384/1384065.png" width="30px" /><a href="https://twitter.com/V_chiurin" target="_blank" style="color:#55BBFF;">推特](https://twitter.com/V_chiurin)**</a> **[<img src="https://cdn.iconscout.com/icon/free/png-256/twitch-11-461838.png" width="30px" /><a href="https://www.twitch.tv/haokute39171765" target="_blank" style="color:#55BBFF;">Twitch](https://www.twitch.tv/haokute39171765)**</a> **[<img src="https://cdn-icons-png.flaticon.com/512/145/145802.png" width="30px" /><a href="https://www.facebook.com/profile.php?id=100041014581991" target="_blank" style="color:#55BBFF;">facebook](https://www.facebook.com/profile.php?id=100041014581991)**</a> </center> <meta http-equiv="refresh" content="0;url=https://youtu.be/I9iP_hCM7mU?si=PbEhnT0Xud1pvzRw">
# RyvexiaLib 這是一個用來製作 **[Ryvexia](https://ryvexia.gamelet.online/)** 音樂遊戲的核心模組,如果想要摳出新專案來製作遊戲,請不要摳此模組,建議摳遊戲成品。 有任何問題請於 **[專案討論](https://code.gamelet.com/discuss/p/RyvexiaLib/0)** 回報,會盡快解決。 ### 遊玩方法 遊戲開始後,會播放音樂,並從畫面上方落下音符,當音符與下方的判定框重合後按下對應的按鍵來打擊音符,打擊時機越準分數越高。 預設為四個軌道,對應按鍵分別為 D、F、J、K。 音符的種類目前分為下列幾種: - **Tap**:單壓,當音符與下方的判定框重合後,按下對應的按鍵來打擊音符。 - **Hold**:長壓,當音符與下方的判定框重合後,按住對應的按鍵直到音符結束時完成打擊。 遊戲中按下 ESC 可暫停遊戲。 ## 如何開始? ```typescript // 設置譜面檔案路徑(專案內),必須先於專案內新增譜面資料檔案。 const chartSource = `CG.${CG.Base.projectCode}/test.json`; // 加載檔案。 CG.Base.resourceManager.addAppSource(chartSource) // 初始化 RyvexiaLib。 CG.RyvexiaLib.initialize() .then(() => { // 初始化完成後 // 初始化 pixi 舞台,建議舞台寬高 1920 x 1080。 CG.Base.pixi.initialize(1920, 1080); // 新增一個譜面資料物件,並匯入譜面資料。 const chartData = new CG.RyvexiaLib.datas.ChartData(); chartData.importSource(chartSource); // 加載該譜面的音樂資料。 chartData.loadMusic(() => { // 加載完成後 // 建立 Ryvexia 遊戲物件,並加入到 root 舞台顯示於畫面上。 const game = new CG.RyvexiaLib.games.Game(); CG.Base.pixi.root.addChild(game); // 設置該遊戲的譜面資料並開始遊戲。 game.setup(chartData).start(); }) }) ``` ## 自製譜面 本模組提供了具有圖形化介面的譜面編輯器,當然你也可以自己使用程式碼添加,甚至利用譜面資料可以新增資料的功能,自製一個譜面編輯器也可以。 ### 如何從編輯器開始? #### 快捷鍵: - W、上:譜面向上移動。 - S、下:譜面向下移動。 - Shift + 移動:加速移動。 - +:增加每小節的拍數。 - -:減少每小節的拍數。 - Shift + 測試遊戲:啟用自動遊玩模式。 (也可以拖動進度條來改變音樂進度。) ```typescript // 初始化 RyvexiaLib CG.RyvexiaLib.initialize() .then(() => { // 初始化 pixi 舞台 CG.Base.pixi.initialize(1920, 1080); // 創建譜面資料物件,BPM 為 160 const chartData = new CG.RyvexiaLib.datas.ChartData(160); // 設定譜面音樂資源名稱 chartData.musicAlias = "你的音樂資源別稱"; // chartData.musicFilename = "你的音樂資源檔名"; // 如果你的音樂是壓縮檔,就會需要用到這一條。 // 建立譜面編輯器並匯入譜面資源 const editor = new CG.RyvexiaLib.editors.ChartEditor(chartData); editor.loadByStorage(); // 於譜面編輯器建立後嘗試讀檔,若無檔案則會忽略。 editor.saveWhileTest = true; // 啟用編輯器測試遊戲時自動存檔。(只有在測試遊戲時會存檔,不是有更新就會儲存) // 建立主要遊戲(讓編輯器用於測試) const game = new CG.RyvexiaLib.games.Game(); // 建立編輯器頁面(用於控制編輯器與遊戲之間的溝通) const editorPage = new CG.RyvexiaLib.utils.pages.ChartEditorPage(editor, game); // 顯示編輯器頁面 editorPage.show(); }) ``` ### 如何從程式碼編輯? ```typescript // 創建一個譜面資料,bpm 為 175。 const chartData = new CG.RyvexiaLib.datas.ChartData(175); // 設定一些譜面資料。 chartData.title = 'Sing My Pleasure'; // 譜面標題 chartData.musicAlias = 'RyvexiaLib.Sing My Pleasure'; // 音樂資源別稱 chartData.musicAuthor = 'Vivy (Vo.Kairi Yagi)'; // 音樂作者、歌手 chartData.chartAuthor = '酷可(cook1470)'; // 譜面作者 // 預設有 4 個軌道,於第 1 軌道,第 0 節拍,位置 0 添加音符。 chartData.tracks[1].addNote(0, new NoteData(0)); // 於第 0 軌道,第 0 節拍,位置 0.5 添加音符。 chartData.tracks[0].addNote(1, new NoteData(0.5)); // 於第 2 軌道,第 7 節拍,位置 0.5 添加音符,音符長度 8。 chartData.tracks[2].addNote(7, new NoteData(0.5, 8)); // BPM 變速設定,於第 20 小節開始,BPM 變為 160。 chartData.bpms[20] = 160; // 於第 50 小節開始,BPM 變為 160。 chartData.bpms[50] = 175; // 創建好以後,可以使用 exportJson 匯出 JSON 物件,並使用 JSON.stringify 轉換成字串。 const text = JSON.stringify(chartData.exportJson()); // 再使用 Base 的 HtmlUtil 來下載檔案。 CG.Base.utils.HtmlUtil.downloadText(text, '我的譜面.json'); // 也可以將譜面資料壓縮後直接下載,不需轉換 JSON,且檔案大小會更小。 // CG.Base.utils.HtmlUtil.downloadText(chartData.exportGzip(), '我的譜面.rvx'); ``` 如果你想要使用壓縮後的譜面檔案,匯入的方法稍有不同。 ```typescript const chartSource = 'CG.YourProject/我的譜面.rvx'; // 與 #如何開始? 相同,先加載要使用的譜面,可參考上方介紹,在此省略。 // 利用 Base 的資源管理器讀取成字串。 const text = CG.Base.resourceManager.getText(chartSource); // 新增一個譜面資料物件,並匯入壓縮譜面資料。 const chartData = new ChartData(); chartData.importGzip(text); // 後續與 #如何開始? 相同,建立遊戲、載入音樂並開始遊戲。 ``` ## 頁面控制器 本模組提供了一個簡單的頁面控制器,以及一些預設的頁面可供使用,以下展示以編輯器為主的控制流程。 包含了封面、校正頁面、編輯器頁面。 ```ts // 初始化 RyvexiaLib CG.RyvexiaLib.initialize() .then(() => { // 初始化 pixi 舞台 CG.Base.pixi.initialize(1920, 1080); // 建立頁面管理器。 const pageManager = new CG.RyvexiaLib.utils.PageManager(); // 建立封面頁面,並註冊到頁面管理器中。 const coverPage = new CG.RyvexiaLib.utils.pages.CoverPage(); // coverPage.titleText.text = "我的音樂遊戲"; // 可改變封面標題文字,預設為 Ryvexia pageManager.registerPage(coverPage); // 建立校正、設定頁面,並註冊到頁面管理器中。 const calibrationPage = new CG.RyvexiaLib.utils.pages.CalibrationPage(); pageManager.registerPage(calibrationPage); const chartData = new CG.RyvexiaLib.datas.ChartData(175); chartData.musicAlias = "你的音樂資源別稱"; const editor = new CG.RyvexiaLib.editors.ChartEditor(chartData); editor.loadByStorage(); editor.saveWhileTest = true; const game = new CG.RyvexiaLib.games.Game(); // 建立編輯器頁面(用於控制編輯器與遊戲之間的溝通),並註冊到頁面管理器中。 const editorPage = new CG.RyvexiaLib.utils.pages.ChartEditorPage(editor, game); pageManager.registerPage(editorPage); // ========== 操控個頁面之間的切換流程。 ========== // 當於封面頁面開始時。 coverPage.onStart = () => { // 顯示校準頁面。 pageManager.show(calibrationPage.code); } // 當於校準頁面返回時。 calibrationPage.onReturn = () => { // 顯示譜面編輯器頁面。 pageManager.show(editorPage.code); } // 當於譜面編輯器頁面返回時。 editorPage.onReturn = () => { // 顯示封面。 pageManager.show(coverPage.code); } // 一開始先顯示封面頁。 pageManager.show(coverPage.code); }) ``` ## 進階設定 本模組將一些可設置常數放在 `CG.RyvexiaLib.Constant` 內,裡面有一些特別的參數可以調整,以下為預設值。 ```typescript // 以下可設定各判定分的範圍(時間差)。 CG.RyvexiaLib.Constant.PERFECT_TIME_RANGE = 46; CG.RyvexiaLib.Constant.GREAT_TIME_RANGE = 92; CG.RyvexiaLib.Constant.GOOD_TIME_RANGE = 138; CG.RyvexiaLib.Constant.MISS_TIME_RANGE = 200; // 以下可設定作為判定分顯示的文字,遊戲中、結算等。 CG.RyvexiaLib.Constant.SCORE_TYPES.PERFECT = "Perfect"; CG.RyvexiaLib.Constant.SCORE_TYPES.GREAT = "Great"; CG.RyvexiaLib.Constant.SCORE_TYPES.GOOD = "Good"; CG.RyvexiaLib.Constant.SCORE_TYPES.MISS = "Miss"; ``` ## 作者 **[module_cook1470](/profile/64897095@github)**
ⒸCode.Gamelet.com | Privacy Policy | Terms of Service