HumanBreak/public/project/floors/MT9.js
2023-08-28 16:05:52 +08:00

134 lines
11 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

main.floors.MT9=
{
"floorId": "MT9",
"title": "主塔 9 层",
"name": "9",
"width": 15,
"height": 15,
"canFlyTo": true,
"canFlyFrom": true,
"canUseQuickShop": true,
"cannotViewMap": false,
"images": [],
"ratio": 1,
"defaultGround": "ground",
"bgm": "cave.mp3",
"firstArrive": [],
"eachArrive": [],
"parallelDo": "",
"events": {
"5,1": [
"本层将展示着色器特效的动画效果。",
"动画效果的核心依然是高级动画插件,使用它来让一个值动态变化,从而达到动画的效果。本层将展示若干个示例。"
],
"3,1": [
"这里是第一个实例。",
"本实例将做出一个画面逐渐变黑白的特效虽然使用css更为方便但是为了教学插件怎么用就使用着色器插件进行制作",
" 首先我们要知道要让画面变黑白应该让它的rgb变成相同的一般来说为了让效果更真实会有特殊的算法进行优化不过这里方便起见直接取平均值。\n 那么要有一个动画效果,我们应当声明一个可以变化的值来表示灰度百分比,表现在着色器中就是\r[gold]uniform全局变量\r声明。",
" 那么片元着色器的代码就是:\n\r[yellow]uniform float uGrayscale;\n\nvoid main() {\n vec4 rgb = texture2D(uSampler, vTextureCoord);\n float avr = (rgb.r + rgb.g + rgb.b) / 3.0;\n float dr = (rgb.r - avr) * (1.0 - uGrayscale);\n float dg = (rgb.g - avr) * (1.0 - uGrayscale);\n float db = (rgb.b - avr) * (1.0 - uGrayscale);\n\n gl_FragColor = vec4(avr + dr, avr + dg, avr + db, rgb.a);\n}\r",
" 稍微解析一下这段代码。这段代码首先声明了一个浮点型的\r[yellow]uGrayscale\r全局变量然后在\r[yellow]main\r函数里面获取了当前像素的rgba值计算平均值和差值然后最后的rgba值就是平均值加上差值了。",
" 那么前面的代码我们可以很轻松地写出来了,跟上一层的一样,不同的是我们还需要引入高级动画插件:\n\r[yellow]const { ShaderEffect, setTickerFor, replaceGameCanvas } = core.plugin.shaderEffect;\nconst { Animation, hyper } = core.plugin.animate;\nconst canvas = ['bg', 'bg2', 'event', 'fg', 'fg2', 'hero'];\neffect.baseImage(...canvas.map(v => core.canvas[v].canvas));\neffect.vs(ShaderEffect.defaultVs);\neffect.fs(/* 上面那一段着色器脚本 */);\r",
" 在这后面就出现与之前不一样的地方了,之前我们直接使用\r[yellow]update\r函数进行渲染但是这里不一样需要使用\r[yellow]compile\r函数先进行编译\n\r[yellow]effect.compile();\r",
" 编译完成之后,我们就可以对\r[gold]uniform\r进行操作了我们需要创建一个全局变量绑定器\n\r[yellow]const binder = effect.createUniformBinder('uGrayscale', 1, 'f', '');\r\n 这一句话的信息量很大,我们来解析一下。\n 这个方法的第一个参数是全局变量的名称,着色器中我们使用了\r[gold]uGrayScale\r这里也填它。\n 第二个参数是变量的元素数量,由于是一个浮点型数字,因此只有一个元素,所以填\r[gold]1\r。\n 第三个参数是元素的数值类似,是浮点数,所以填\r[gold]'f'\r整型的话应该填\r[gold]'i'\r。\n 第四个参数是这个变量是否是向量,浮点数不是向量,因此填\r[gold]''\r注意不能不填应当填空字符串。",
" 下一步我们需要对这个全局变量进行初始化操作,使用\r[gold]set\r方法进行赋值即可初始化\n\r[yellow]binder.set(0);\r",
" 下面我们就可以使用js来操作这个\r[gold]uniform\r了也就是说我们可以使用高级动画插件操作这个全局变量来实现动画效果了。下面我们直接创建高级动画实例进行动画操作\n\r[yellow]const ani = new Animation();\nani.register('grayscale', 0);\nani.time(5000).mode(hyper('sin', 'in-out')).absolute().apply('grayscale', 1);\r\n 这样我们就创建了一个动画属性下面我们要将它与全局变量绑定器联系起来。这里的高级动画的意思是动画时间5000毫秒速率曲线为hyper sin双曲正弦函数in-out慢-快-慢变化方式绝对变化最终grayscale变为1",
" 联系起来的方式很简单,直接使用内置方法每帧赋值即可:\n\r[yellow]ani.ticker.add(() => binder.set(ani.value.grayscale));\r",
" 这样动画也配置完毕了,后面便可以直接渲染特效,然后在页面上展示了,唯一不同的点是不能再向\r[gold]update\r的第一个参数传入true了这会重新编译着色器导致绑定器失效。下面是后面的代码\n\r[yellow]effect.update();\nconst ticker = setTickerFor(effect);\nconst manager = replaceGameCanvas(effect, canvas);\r\n 由于全部源码较长,这里就不放完整源码了。",
"下面是最终效果。",
{
"type": "function",
"function": "function(){\nflags.lastShaderSample?.end();\nflags.lastShaderSample = core.shaderSample5();\n}"
}
],
"1,1": [
"这里是第二个特效实例。",
"这个实例将模拟老实电视的显示不稳定",
"这个特效本质上是对颜色进行一定程度的噪声处理,因此我们只需要创建一个噪声偏移量的全局变量,然后让它一直以恒定的速率增加就行了,这甚至不需要高级动画实例的参与。",
" 它的片元着色器脚本:\n\r[yellow]uniform float uOffset;\n\nfloat noise(float x) {\n float y = fract(sin(x) * 100000.0);\n return y;\n}\n \nvoid main() {\n vec4 rgba = texture2D(uSampler, vTextureCoord);\n float n = noise(rgba.r + rgba.g + rgba.b + uOffset) / 10.0;\n \n gl_FragColor = vec4(rgba.rgb + n, rgba.a);\n}\r",
"它在动画部分的脚本注意从高级动画插件引入Ticker\n\r[yellow]const ticker = new Ticker();\nticker.add(() => binder.set(binder.get() + 0.01));\r",
{
"type": "function",
"function": "function(){\nflags.lastShaderSample?.end();\nflags.lastShaderSample = core.shaderSample6();\n}"
}
],
"9,1": [
"这里是第三个特效实例。",
"这个实例将让上一层的第四个实例动起来",
"实际伤这与本层的第三实例类似依然是加一个offset在噪声上。",
" 它的片元着色器脚本:\n\r[yellow]uniform float uOffset;\n\nfloat noise(float x) {\n float y = fract(sin(x) * 100000.0);\n return y;\n}\n\nvoid main() {\n float brigtness = -0.1 + noise(uOffset) / 50.0;\n vec2 xy = vTextureCoord;\n float x = xy.x + noise(xy.y + uOffset) / 100.0;\n float y = xy.y;\n vec4 color = texture2D(uSampler, vec2(x, y));\n vec4 color1 = vec4(color.rgb + vec3(brigtness), color.a);\n\n gl_FragColor = color1;\n}\r",
"它在动画部分的脚本注意从高级动画插件引入Ticker\n\r[yellow]const ticker = new Ticker();\nticker.add(() => binder.set(binder.get() + 0.01));\r",
{
"type": "function",
"function": "function(){\nflags.lastShaderSample?.end();\nflags.lastShaderSample = core.shaderSample7();\n}"
}
],
"11,1": [
"这里是第四个特效实例。",
"这个实例将做一个四周边缘周期性变黑的特效",
" 它需要用到当前像素的位置,因此需要从顶点着色器中用\r[gold]varying\r变量传递至片元着色器中那么它的顶点着色器\n\r[yellow]varying vec4 vpos;\n\nvoid main() {\n vTextureCoord = aTextureCoord;\n vpos = aVertexPosition;\n gl_Position = aVertexPosition;\n}\r",
" 它的片元着色器脚本:\n\r[yellow]uniform float uStrength;\nvarying vec4 vpos;\n\nvoid main() {\n float alpha = clamp(distance(vec2(0, 0), vpos.xy) - 0.6, 0.0, 1.0) * uStrength;\n vec4 tex = texture2D(uSampler, vTextureCoord);\n gl_FragColor = vec4(tex.rgb * (1.0 - alpha), 1.0);\n}\r",
"它在动画部分的脚本注意从高级动画插件引入Ticker\n\r[yellow]const ticker = new Ticker();\nticker.add(time => binder.set((Math.sin(time / 2000 - Math.PI / 2) + 1) / 2);\r",
{
"type": "function",
"function": "function(){\nflags.lastShaderSample?.end();\nflags.lastShaderSample = core.shaderSample8();\n}"
}
],
"13,1": [
"这里是第五个特效实例。",
"这个实例将吧前两个特效结合起来,粗略实现泰拉瑞亚中月球领主来临前的特效。",
" 顶点着色器与第四个特效相同:\n\r[yellow]varying vec4 vpos;\n\nvoid main() {\n vTextureCoord = aTextureCoord;\n vpos = aVertexPosition;\n gl_Position = aVertexPosition;\n}\r",
" 它的片元着色器脚本:\n\r[yellow]uniform float uStrength;\nvarying vec4 vpos;\n\nfloat noise(float x) {\n float y = fract(sin(x) * 100000.0);\n return y;\n}\n\nvoid main() {\n float brigtness = -uStrength / 10.0;\n vec2 xy = vTextureCoord;\n float x = xy.x + noise(xy.y + uStrength) / 300.0 * uStrength;\n float y = xy.y;\n vec4 color = texture2D(uSampler, vec2(x, y));\n vec4 color1 = vec4(color.rgb + vec3(brigtness), color.a);\n float alpha = clamp(distance(vec2(0, 0), vpos.xy) - 0.6, 0.0, 1.0) * uStrength;\n gl_FragColor = vec4(color1.rgb * (1.0 - alpha), 1.0);\n}\r",
"它在动画部分的脚本注意从高级动画插件引入Ticker\n\r[yellow]const ticker = new Ticker();\nticker.add(time => binder.set((Math.sin(time / 2000 - Math.PI / 2) + 1) / 2);\r",
{
"type": "function",
"function": "function(){\nflags.lastShaderSample?.end();\nflags.lastShaderSample = core.shaderSample9();\n}"
}
]
},
"changeFloor": {
"7,1": {
"floorId": ":before",
"stair": "upFloor"
},
"7,13": {
"floorId": ":next",
"stair": "downFloor"
}
},
"beforeBattle": {},
"afterBattle": {},
"afterGetItem": {},
"afterOpenDoor": {},
"autoEvent": {},
"cannotMove": {},
"cannotMoveIn": {},
"map": [
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 1,129, 0,129, 0,129, 0, 88, 0,129, 0,129, 0,129, 1],
[ 1,10187, 0,10186, 0,10185, 0, 0, 0,10188, 0,10189, 0,10193, 1],
[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1,201, 0,202, 0,203, 0,204, 0,205, 0,206, 0,207, 1],
[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1,333, 0,336, 0,340, 0,345, 0,351, 0,358, 0,366, 1],
[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1,376, 0,378, 0,381, 0,385, 0, 35, 0, 37, 0, 39, 1],
[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1, 31, 0, 32, 0, 33, 0, 34, 0, 36, 0, 38, 0, 40, 1],
[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[ 1, 0, 0, 0, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 1],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
],
"bgmap": [
],
"fgmap": [
],
"bg2map": [
],
"fg2map": [
]
}