From aa9f0fc978a1092d19495200f961a7e02a8a7e73 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Tue, 10 Aug 2021 19:48:23 +0800 Subject: [PATCH] registerWeather --- _docs/api.md | 10 ++ _docs/script.md | 47 +++++++++ _server/CodeMirror/defs.js | 8 ++ libs/control.js | 201 ++++++++++++++++++++++--------------- libs/events.js | 1 + runtime.d.ts | 6 ++ 6 files changed, 194 insertions(+), 79 deletions(-) diff --git a/_docs/api.md b/_docs/api.md index 2bfd3918..3f40d96f 100644 --- a/_docs/api.md +++ b/_docs/api.md @@ -503,6 +503,13 @@ registerResize: fn(name: string, func: fn(obj: ?)) name: 名称,可供注销使用 func: 可以是一个函数,或者是插件中的函数名;可以接受obj参数,详见resize函数。 +registerWeather: fn(name: string, initFunc: fn(level: number), frameFunc?: fn(timestamp: number, level: number)) +注册一个天气 +name: 要注册的天气名 +initFunc: 当切换到此天气时的初始化;接受level(天气等级)为参数;可用于创建多个节点(如初始化雪花) +frameFunc: 每帧的天气效果变化;可接受timestamp(从页面加载完毕到当前所经过的时间)和level(天气等级)作为参数 +天气应当仅在weather层进行绘制,推荐使用core.animateFrame.weather.nodes用于节点信息。 + removeFlag: fn(name: string) 删除某个flag/变量 @@ -698,6 +705,9 @@ unregisterReplayAction: fn(name: string) unregisterResize: fn(name: string) 注销一个resize函数 +unregisterWeather: fn(name: string) +注销一个天气 + updateCheckBlock: fn(floorId?: string) 更新领域、夹击、阻击的伤害地图 diff --git a/_docs/script.md b/_docs/script.md index 3ba53acd..3c94be54 100644 --- a/_docs/script.md +++ b/_docs/script.md @@ -480,6 +480,53 @@ core.registerReplayAction('commonEvent', function (action) { }); ``` +### registerWeather + +``` +registerWeather: fn(name: string, initFunc: fn(level: number), frameFunc?: fn(timestamp: number, level: number)) +注册一个天气 +name: 要注册的天气名 +initFunc: 当切换到此天气时的初始化;接受level(天气等级)为参数;可用于创建多个节点(如初始化雪花) +frameFunc: 每帧的天气效果变化;可接受timestamp(从页面加载完毕到当前所经过的时间)和level(天气等级)作为参数 +天气应当仅在weather层进行绘制,推荐使用core.animateFrame.weather.nodes用于节点信息。 +``` + +`registerWeather`允许你注册一个天气。 + +在游戏时,楼层属性中可以设置天气如 `["snow", 5]`,或者脚本 `core.setWeather("snow", 5)` 来切换天气。 + +下面是一个例子: + +```js +// 注册一个”血“天气,每200ms就随机在界面上的绘制红色斑点 +core.registerWeather('blood', function (level) { + // 切换到此天气时应当执行的脚本吗,如播放一个音效 + core.playSound('blood.mp3'); +}, function (timestamp, level) { + // 我们希望每200ms就界面上随机绘制 level^2 个红点,半径在0~32像素之间 + + // 检查是否经过了200ms + if (timestamp - core.animateFrame.weather.time < 200) return; + // 当且仅当在weather层上绘制 + core.clearMap('weather'); + for (var i = 0; i < level * level; ++i) { + // 随机界面中的一个点,半径在0~32之间 + var px = Math.random() * core.__PIXELS__; + var py = Math.random() * core.__PIXELS__; + var r = Math.random() * 32; + core.fillCircle('weather', px, py, r, 'red'); + } + // 设置本次天气调用的时间 + core.animateFrame.weather.time = timestamp; +}); +``` + +值得注意的是,天气当且仅当在`weather`层进行绘制,推荐使用或设置`core.animateFrame.weather.time`作为上次天气调用的时间避免太过于频繁的调用。 + +推荐使用`core.animateFrame.weather.nodes`来存储天气的节点,这样会在取消天气时自动被移除。 + +样板的云`cloud`和雾`fog`均由多个图片叠加移动实现;如果你想实现类似效果,可直接使用`core.control.__animateFrame_weather_image`作为`frameFunc`,详见样板的云雾实现。 + ### registerSystemEvent ``` diff --git a/_server/CodeMirror/defs.js b/_server/CodeMirror/defs.js index 8d522deb..f8c363e8 100644 --- a/_server/CodeMirror/defs.js +++ b/_server/CodeMirror/defs.js @@ -2324,6 +2324,10 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [ "!doc": "注销一个录像行为", "!type": "fn(name: string)" }, + "unregisterWeather": { + "!doc": "注销一个天气", + "!type": "fn(name: string)" + }, "setBuff": { "!doc": "设置主角某个属性的百分比修正倍率,初始值为1,
倍率存放在flag: '__'+name+'_buff__' 中
例如:core.setBuff('atk', 0.5); // 主角能发挥出的攻击力减半
name: 属性的英文名,请注意只能用于数值类属性哦,否则随后的乘法会得到NaN
value: 新的百分比修正倍率,不填(效果上)视为1", "!type": "fn(name: string, value: number)" @@ -2460,6 +2464,10 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [ "!doc": "注册一个resize函数
name: 名称,可供注销使用
func: 可以是一个函数,或者是插件中的函数名;可以接受obj参数,详见resize函数。", "!type": "fn(name: string, func: fn(obj: ?))" }, + "registerWeather": { + "!doc": "注册一个天气
name: 要注册的天气名
initFunc: 当切换到此天气时的初始化;接受level(天气等级)为参数;可用于创建多个节点(如初始化雪花)
frameFunc: 每帧的天气效果变化;可接受timestamp(从页面加载完毕到当前所经过的时间)和level(天气等级)作为参数
天气应当仅在weather层进行绘制,推荐使用core.animateFrame.weather.nodes用于节点信息。", + "!type": "fn(name: string, initFunc: fn(level: number), frameFunc?: fn( timestamp: number, level: number))" + }, "stopReplay": { "!doc": "停止播放", "!type": "fn(force?: bool)" diff --git a/libs/control.js b/libs/control.js index e4b899bb..913b5b29 100644 --- a/libs/control.js +++ b/libs/control.js @@ -16,6 +16,7 @@ control.prototype._init = function () { this.controldata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.control; this.renderFrameFuncs = []; this.replayActions = []; + this.weathers = {}; this.resizes = []; // --- 注册系统的animationFrame this.registerAnimationFrame("totalTime", false, this._animationFrame_totalTime); @@ -26,6 +27,12 @@ control.prototype._init = function () { this.registerAnimationFrame("weather", true, this._animationFrame_weather); this.registerAnimationFrame("tip", true, this._animateFrame_tip); this.registerAnimationFrame("parallelDo", false, this._animationFrame_parallelDo); + // --- 注册系统的天气 + this.registerWeather("rain", this._weather_rain, this._animationFrame_weather_rain); + this.registerWeather("snow", this._weather_snow, this._animationFrame_weather_snow); + this.registerWeather("fog", this._weather_fog, this.__animateFrame_weather_image); + this.registerWeather("cloud", this._weather_cloud, this.__animateFrame_weather_image); + this.registerWeather("sun", this._weather_sun, this._animationFrame_weather_sun); // --- 注册系统的replay this.registerReplayAction("move", this._replayAction_move); this.registerReplayAction("item", this._replayAction_item); @@ -199,13 +206,19 @@ control.prototype._animationFrame_heroMoving = function (timestamp) { } control.prototype._animationFrame_weather = function (timestamp) { - var weather = core.animateFrame.weather; - if (timestamp - weather.time <= 30 || !core.dymCanvas.weather) return; - core.control["_animationFrame_weather_"+weather.type](); - weather.time = timestamp; + var weather = core.animateFrame.weather, type = weather.type; + if (!core.dymCanvas.weather || !core.control.weathers[type] || !core.control.weathers[type].frameFunc) return; + try { + core.doFunc(core.control.weathers[type].frameFunc, core.control, timestamp, core.animateFrame.weather.level); + } catch (e) { + main.log(e); + main.log("ERROR in weather["+type+"]:已自动注销该项。"); + core.unregisterWeather(type); + } } -control.prototype._animationFrame_weather_rain = function () { +control.prototype._animationFrame_weather_rain = function (timestamp, level) { + if (timestamp - core.animateFrame.weather.time < 30) return; var ctx = core.dymCanvas.weather, ox = core.bigmap.offsetX, oy = core.bigmap.offsetY; core.clearMap('weather'); ctx.strokeStyle = 'rgba(174,194,224,0.8)'; @@ -228,9 +241,11 @@ control.prototype._animationFrame_weather_rain = function () { }); ctx.fill(); + core.animateFrame.weather.time = timestamp; } -control.prototype._animationFrame_weather_snow = function () { +control.prototype._animationFrame_weather_snow = function (timestamp, level) { + if (timestamp - core.animateFrame.weather.time < 30) return; var ctx = core.dymCanvas.weather, ox = core.bigmap.offsetX, oy = core.bigmap.offsetY; core.clearMap('weather'); ctx.fillStyle = "rgba(255, 255, 255, 0.8)"; @@ -260,11 +275,15 @@ control.prototype._animationFrame_weather_snow = function () { } }); ctx.fill(); + core.animateFrame.weather.time = timestamp; } -control.prototype.__animateFrame_weather_image = function (image) { - if (!image) return; +control.prototype.__animateFrame_weather_image = function (timestamp, level) { + if (timestamp - core.animateFrame.weather.time < 30) return; var node = core.animateFrame.weather.nodes[0]; + var image = node.image; + if (!image) return; + core.clearMap('weather'); core.setAlpha('weather', node.level / 500); var wind = 1.5; var width = image.width, height = image.height; @@ -296,20 +315,18 @@ control.prototype.__animateFrame_weather_image = function (image) { } } core.setAlpha('weather',1); + core.animateFrame.weather.time = timestamp; } -control.prototype._animationFrame_weather_fog = function () { - core.clearMap('weather'); - this.__animateFrame_weather_image(core.animateFrame.weather.fog); -} - -control.prototype._animationFrame_weather_cloud = function () { - core.clearMap('weather'); - this.__animateFrame_weather_image(core.animateFrame.weather.cloud); -} - -control.prototype._animationFrame_weather_sun = function () { - // do nothing here. +control.prototype._animationFrame_weather_sun = function (timestamp, level) { + if (timestamp - core.animateFrame.weather.time < 30) return; + var node = core.animateFrame.weather.nodes[0]; + var opacity = node.opacity + node.delta; + if (opacity > level / 10 + 0.3 || opacity < level / 10 - 0.3) + node.delta = -node.delta; + node.opacity = opacity; + core.setOpacity('weather', core.clamp(opacity, 0, 1)); + core.animateFrame.weather.time = timestamp; } control.prototype._animateFrame_tip = function (timestamp) { @@ -2542,7 +2559,7 @@ control.prototype.getMappedName = function (name) { ////// 更改天气效果 ////// control.prototype.setWeather = function (type, level) { // 非雨雪 - if (type == null) { + if (type == null || !this.weathers[type]) { core.deleteCanvas('weather') core.animateFrame.weather.type = null; core.animateFrame.weather.nodes = []; @@ -2555,72 +2572,98 @@ control.prototype.setWeather = function (type, level) { // 计算当前的宽高 core.createCanvas('weather', 0, 0, core.__PIXELS__, core.__PIXELS__, 80); + core.setOpacity('weather', 1.0); core.animateFrame.weather.type = type; core.animateFrame.weather.level = level; core.animateFrame.weather.nodes = []; - this._setWeather_createNodes(type, level); + try { + core.doFunc(this.weathers[type].initFunc, this, level); + } catch (e) { + main.log(e); + main.log("ERROR in weather["+type+"]:已自动注销该项。"); + core.unregisterWeather(type); + } } -control.prototype._setWeather_createNodes = function (type, level) { - var number = level * parseInt(20*core.bigmap.width*core.bigmap.height/(core.__SIZE__*core.__SIZE__)); - switch (type) { - case 'rain': - for (var a=0;a void, frameFunc?: (timestamp: number, level: number) => void): void + + /** 注销一个天气 */ + unregisterWeather(name: string) : void; + /** * 更改画面色调,不计入存档。如需长期生效请使用core.events._action_setCurtain()函数 * @example core.setCurtain(); // 恢复画面色调,用时四分之三秒