17
17
18
18
#### Step1 安装启动剧情Cli工具
19
19
20
- 确保安装Node .js与npm包管理器时,只需在你的PC命令行中输入:
20
+ 确保正确安装Node .js与npm包管理器时,只需在你的PC命令行中输入:
21
21
22
22
``` sh
23
23
npm install launch-opera-cli -g
24
24
```
25
25
26
- 有时可能需要以管理员身份运行 。
26
+ 有时可能需要以管理员身份运行该命令 。
27
27
28
28
#### Step2 创建剧情工程
29
29
@@ -56,14 +56,23 @@ lacop watch
56
56
57
57
接下来请你使用 JavaScript 代码编辑器打开本仓库目录(如 VSCode 打开),找到 ` /src/launchOperaPlay/index.ts ` 脚本。
58
58
59
- 请修改脚本中大约第 72 行的 URL 文本地址为 :
59
+ 请修改脚本中大约第 51 行的 skipButton 的 setParams 参数为 :
60
60
61
61
``` js
62
- // url: 'https://testcos.merge.qq.com/mini-mm-release/1.0.5/StreamingAssets/Movies/CG_Trim.mp4', // 修改前
63
- url: ' https://testcos.merge.qq.com/mini-mm-release/1.0.5/StreamingAssets/Movies/CG_Trim.mp4' , // 修改后
62
+ skipButton .setParams ({
63
+ // right: 30, // 修改前
64
+ left: 30 , // 修改后
65
+ bottom: 60 ,
66
+ width: 173 / 1.5 ,
67
+ height: 64 / 1.5 ,
68
+ url: ' launchOperaPlay/skip.png' ,
69
+ visible: true ,
70
+ });
64
71
```
65
72
66
- 此时保存这个文件,如果你的 Step3 中启动的开发模式还在工作,那么 ` /minigame ` 目录资源也将被实时更新,此时 ` 微信开发者工具 ` 通常也将重新加载游戏内容,你会看到被你刚刚修改的新的剧情内容。
73
+ 此时保存这个文件,如果你的 Step3 中启动的开发模式还在工作,那么 ` /minigame ` 目录资源也将被实时更新,此时 ` 微信开发者工具 ` 通常也将重新加载游戏内容,你会看到被你刚刚修改的按钮贴图位置从右下角变成左下角。
74
+
75
+ 以此类推,你可以快速修改你看到的很多属性内容,比如位置信息、URL地址从而改变剧情的内容。
67
76
68
77
#### Step6 导出剧本
69
78
@@ -85,4 +94,202 @@ lacop build
85
94
86
95
启动剧情能够设计很复杂的交互剧情内容,但是这对于初学者还需要阅读本文更多的内容,后续请查阅 [ 进阶指南] ( #4进阶指南 ) 。如果你想快速应用场景,类似 Step5 中这样仅修改属性值就可以替换成自己的游戏素材还是十分便捷。我们提供了多种模板可供选择,只需要在命令行中输入 ` lacop template ` 可以快速切换提供的多种模板效果拿来使用。
87
96
88
- ** 实际上你可以直接执行 ` lacop ` 而无需带后面的参数进行能力的自主选择**
97
+ ** 实际上你可以直接执行 ` lacop ` 而无需带后面的参数进行能力的自主选择**
98
+
99
+ ## 4.进阶指南
100
+
101
+ 如果模板还不能满足你的需要,请仔细阅读本节,你将学会设计复杂的剧情内容。
102
+
103
+ ### 4.1 了解构建工具
104
+
105
+ 本构建工具已经为开发者配置好了相关类型声明,如果你使用例如 ` VScode ` 等具备 JavaScript/TypeScript 解析的 IDE 工具将可以享受到函数名联想及参数注释能力。
106
+
107
+ 在使用前请了解本工具的一些行为约束:
108
+
109
+ - ` src ` 目录中资源将根据层级结构覆盖构建至 ` minigame ` 目录中,因此你可以将图片资源放置在本目录中以供引用,其中 ` .ts ` 结尾的脚本不会覆盖;
110
+ - ` src/launchOperaPlay ` 是固定的启动剧情资源目录,请勿修改名称;
111
+ - ` src/launchOperaPlay/index.ts ` 是固定的剧情撰写文件,请勿修改名称;
112
+ - 视频、音频资源均需要存放至 CDN 中,贴图资源只能放置 ` src ` 目录中;
113
+ - ` operaData ` 是整个剧情的编辑句柄,剧情的设计将由操作它开始。
114
+
115
+
116
+ ### 4.2 基本概念
117
+
118
+ 在启动剧情中由两个剧本元素组成,分别是 ** 关键动作帧(Frame)** 、** 故事线(StoryLine)** ,关键动作帧更像是一个“函数”,核心思想在于执行到该帧时会引发某种动作,而故事线则是将多个独立的关键动作帧串联有序执行。
119
+
120
+ #### 4.2.1 关键动作帧
121
+
122
+ 有关关键动作帧的种类,请查阅 [ API速查] ( #5api速查 ) 。每个关键动作帧均有两个必要的组成部分:属性、事件。
123
+
124
+ ##### 4.2.1.1 属性
125
+
126
+ 属性是从关键动作帧激活的那一刻起被赋予其特定的值,属性决定了该帧的真实视图表现。例如:
127
+
128
+ ``` js
129
+ // 创建了一个 Image,并赋予了他一些初始化的属性
130
+ const skipButton = operaData .createFrame (FrameType .createImage , {
131
+ url: ` launchOpera/skip_button.png` ,
132
+ right: 25 ,
133
+ bottom: 25 ,
134
+ width: 100 ,
135
+ height: 100 ,
136
+ });
137
+
138
+ // 也可以创建后再修改其属性,与上面的写法实际效果完全一样
139
+ const skipButton = operaData .createFrame (FrameType .createImage );
140
+ skipButton .setParams ({
141
+ url: ` launchOpera/skip_button.png` ,
142
+ right: 25 ,
143
+ bottom: 25 ,
144
+ width: 100 ,
145
+ height: 100 ,
146
+ });
147
+
148
+ // 注意设置属性是一个最终态的表现,也就意味着如下设置只有最后一个是生效的
149
+ skipButton .setParams ({
150
+ height: 100 , // 会因下面设置会覆盖,因此该设置无效
151
+ });
152
+ skipButton .setParams ({
153
+ height: 101 , // 会因下面设置会覆盖,因此该设置无效
154
+ });
155
+ skipButton .setParams ({
156
+ height: 102 , // 因最后赋值则有效,skipButton 的 height 初始值则为 102
157
+ });
158
+ ```
159
+
160
+ ##### 4.2.1.2 事件
161
+
162
+ 事件是对于不同关键动作帧存在不同的事件从而可以引发新的故事线的能力。比如 图片 可以存在被点击(onClick)的事件,视频组件存在开始播放(onPlay)、播放到第n秒时(onPlayTimeAt)、播放结束时(onEnded)等事件,当发生某种事件自然也就可以触发新的故事线内容。
163
+
164
+ 其中,播放到第n秒时(onPlayTimeAt),n 是一个可变系数,因此事件也是支持配置参数的。
165
+
166
+ 例子:
167
+
168
+ ``` js
169
+ const video1 = operaData .createFrame (FrameType .createVideo , { ... });
170
+ // 设置多个不同的事件
171
+ // ①
172
+ video1 .setEvents ({
173
+ event : ' onPlayTimeAt' ,
174
+ params: {
175
+ sec: 9 ,
176
+ },
177
+ bind: nextStoryLine,
178
+ });
179
+ // ②
180
+ video1 .setEvents ({
181
+ event : ' onPlayTimeAt' ,
182
+ params: {
183
+ sec: 2 ,
184
+ },
185
+ keep: true ,
186
+ bind: [ skipButton ],
187
+ });
188
+ // ③
189
+ skipButton .setEvents ({
190
+ event : ' onClick' ,
191
+ bind: [ operaData .EndFrame ]
192
+ });
193
+ ```
194
+
195
+ 上面的例子展示了实际应用的多种可能,首先是不同于 [ 属性] ( #4211-属性 ) 的后设置的值将覆盖前设置特点,同名事件是支持创建多个并同时生效(对照① ②中均是 pnPlayTimeAt 事件,但都是独立生效)。② 中使用了一个 keep 字段告诉剧情引擎该事件是反复有效,意味着实际运行时多次达到该事件条件都会引发该事件,而 ① ③ 没有设置 keep 发生一次事件后再达成条件也不会再次引发该事件。
196
+
197
+ 再次观察 ① ② 的 bind,可以发现发生事件后执行的新的故事线其实可以存在多种表达方式,① 中是上下文中开发者自行创建的名为 ` nextStoryLine ` 故事线,有关故事线创建请阅读 [ 故事线] ( #422-故事线 ) 小节,而 ② 中是放了一个由 关键动作帧 组成的数组,这其实是一种匿名故事线。
198
+
199
+ 最后 ③ 中的 ` operaData.EndFrame ` 实际上最特殊的关键动作帧,当执行到该帧后,启动剧情将立即结束。
200
+
201
+ #### 4.2.2 故事线
202
+
203
+ 故事线是将一个或多个关键动作帧有序打包的容器,比较特殊的是,启动剧情需要存在一个主故事线作为启动入口。
204
+
205
+ ##### 4.2.2.1 创建及添加关键动作帧
206
+
207
+ 创建故事线以及添加关键动作帧很简单,使用 operaData 句柄执行:
208
+
209
+ ``` js
210
+ // 创建
211
+ const storyLine = operaData .createStoryLine ();
212
+
213
+ // 创建一系列的动作帧.....
214
+
215
+ // 如需添加动作帧
216
+ storyLine .add (var_GC_GUIDE_STEP, startImg, video1, ... .. );
217
+ ```
218
+
219
+ ##### 4.2.2.2 主故事线
220
+
221
+ 主故事线是启动剧情启动后最先执行的内容,当你第一次创建故事线时,那条线也就是主故事线了。
222
+
223
+ 主故事线有一些很常见的用途,比如挂载一些全局变量放到主故事线上就很合理,这样你可以在任何时候对全局变量进行使用,对于全局变量的详细介绍请阅读 [ 全局变量] ( ) 小节。
224
+
225
+
226
+ ## 5.API速查
227
+
228
+ 了解基本概念后,你也就知道驱动整个剧情发展无非3点。
229
+ - 合适的时机执行需要的关键动作帧;
230
+ - 用故事线串联一系列动作帧让他们有序执行;
231
+ - 关键动作帧可以达成某种事件从而产生新的一条故事线。
232
+
233
+ 故事线的理解比较简单,重点是了解微信小游戏为开发者们提供了哪些关键动作帧,你可以略读 FrameType速查表 大概知道有哪些能力,并可以具体查看每一个 FrameType 的使用说明,来完成剧情的自主设计。
234
+
235
+ ### FrameType速查表
236
+
237
+ 点击名称可快速查阅说明
238
+
239
+ FrameType | 释义
240
+ -|-
241
+ [ createVideo] ( #createvideo ) | 创建视频组件
242
+ [ pauseVide] ( ) | 将某个视频组件进行暂停
243
+ [ playVideo] ( ) | 将某个视频组件进行继续播放
244
+ [ createAudio] ( ) | 创建音频组件
245
+ [ pauseAudio] ( ) | 将某个音频组件进行暂停
246
+ [ playAudio] ( ) | 将某个音频组件进行继续播放
247
+ [ createImage] ( ) | 创建贴图
248
+ [ createRect] ( ) | 创建矩形区域(可透明、填充纯色、用于区域点击识别)
249
+ [ var] ( ) | 创建全局变量
250
+ [ setParam] ( ) | 设置某个关键动作帧的属性
251
+ [ setTimeout] ( ) | 创建延迟执行
252
+ [ setParamSize] ( ) | 设置组件的Size属性
253
+ [ setParamPosition] ( ) | 设置组件的Position属性
254
+ [ setParamSizeAndPosition] ( ) | 同时设置组件的Size、Position属性
255
+ [ createAnimationFunction] ( ) | 创建动画函数
256
+ [ if] ( ) | 条件判断
257
+ [ report] ( ) | 创建上报节点
258
+ [ checkPoint] ( ) | 剧情检查点
259
+ [ reportCheckPointCount] ( ) | 上报剧情检查点个数
260
+
261
+ ### 视频相关
262
+
263
+ #### createVideo
264
+
265
+ 创建视频组件。
266
+
267
+ ##### 属性
268
+
269
+ ...
270
+
271
+ ##### 事件
272
+
273
+ ##### 案例
274
+
275
+ ## 6.常见Q&A
276
+
277
+ #### 6.1 图片资源可以使用网络图片吗?
278
+ 目前图片资源只能存放于小游戏 minigame 目录中,不可使用网络图片。
279
+
280
+ #### 6.2 为什么要放首帧图片(firstFramePic)
281
+ 图片资源是跟随微信小游戏包上传至微信服务器,所以在小游戏主逻辑运行时,图片资源也处于就绪状态可以同步加载,因此玩家打开游戏时首帧将看到具体的游戏画面。而视频是存放在CDN的远程资源,不可避免的存在加载延迟问题,所以配置好首帧图片后,在视频可播放后再隐藏图片资源。
282
+
283
+ #### 6.3 如何托管自己的剧本?
284
+
285
+ 你可以将本仓库 Fork 至自己 GitHub 名下,私有化后独立维护剧本创作。
286
+
287
+ ## 7.分享你的模板
288
+
289
+ 如果你很了解启动剧情剧本的设计,非常欢迎分享出你设计的剧情。请 Fork 本仓库后进行相应的创作,并提交至本仓库。
290
+
291
+ 你的作品需存放至 ` template ` 的子目录中,子目录名称根据时间先后数字排序(提交后可能被二次修改),将作品名称填写至作品目录的 ` readme.md ` 文件头(长度不要超过10个中文字符),正如 ` template/0/readme.md ` 相同的格式。
292
+
293
+ 注意:提交仅接受剧情相关文件,如贴图、.ts剧情撰写代码、说明文档,并且切换模板能够正常播放体验。
294
+
295
+ 请勿提供未确认版权的演示内容。
0 commit comments