registerWeather

This commit is contained in:
ckcz123 2021-08-10 19:48:23 +08:00
parent 657e6dd673
commit aa9f0fc978
6 changed files with 194 additions and 79 deletions

View File

@ -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)
更新领域、夹击、阻击的伤害地图

View File

@ -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
```

View File

@ -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<br/>倍率存放在flag: '__'+name+'_buff__' 中<br/>例如core.setBuff('atk', 0.5); // 主角能发挥出的攻击力减半<br/>name: 属性的英文名请注意只能用于数值类属性哦否则随后的乘法会得到NaN<br/>value: 新的百分比修正倍率不填效果上视为1",
"!type": "fn(name: string, value: number)"
@ -2460,6 +2464,10 @@ var terndefs_f6783a0a_522d_417e_8407_94c67b692e50 = [
"!doc": "注册一个resize函数<br/>name: 名称,可供注销使用<br/>func: 可以是一个函数或者是插件中的函数名可以接受obj参数详见resize函数。",
"!type": "fn(name: string, func: fn(obj: ?))"
},
"registerWeather": {
"!doc": "注册一个天气<br/>name: 要注册的天气名<br/>initFunc: 当切换到此天气时的初始化接受level天气等级为参数可用于创建多个节点如初始化雪花<br/>frameFunc: 每帧的天气效果变化可接受timestamp从页面加载完毕到当前所经过的时间和level天气等级作为参数<br/>天气应当仅在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)"

View File

@ -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<number;a++) {
core.animateFrame.weather.nodes.push({
'x': Math.random()*core.bigmap.width*32,
'y': Math.random()*core.bigmap.height*32,
'l': Math.random() * 2.5,
'xs': -4 + Math.random() * 4 + 2,
'ys': Math.random() * 10 + 10
})
}
break;
case 'snow':
for (var a=0;a<number;a++) {
core.animateFrame.weather.nodes.push({
'x': Math.random()*core.bigmap.width*32,
'y': Math.random()*core.bigmap.height*32,
'r': Math.random() * 5 + 1,
'd': Math.random() * Math.min(level, 200),
})
}
break;
case 'fog':
if (core.animateFrame.weather.fog) {
core.animateFrame.weather.nodes = [{
'level': number,
'x': 0,
'y': -core.__PIXELS__ / 2,
'dx': -Math.random() * 1.5,
'dy': Math.random(),
'delta': 0.001,
}];
}
break;
case 'cloud':
if (core.animateFrame.weather.cloud) {
core.animateFrame.weather.nodes = [{
'level': number,
'x': 0,
'y': -core.__PIXELS__ / 2,
'dx': -Math.random() * 1.5,
'dy': Math.random(),
'delta': 0.001,
}];
}
break;
case 'sun':
if (core.animateFrame.weather.sun) {
// 直接绘制
core.clearMap('weather');
core.setAlpha('weather', level / 10);
core.drawImage('weather', core.animateFrame.weather.sun, 0, 0, core.animateFrame.weather.sun.width, core.animateFrame.weather.sun.height, 0, 0, core.__PIXELS__, core.__PIXELS__);
core.setAlpha('weather', 1);
}
break;
////// 注册一个天气 //////
// name为天气类型如 sun, rain, snow 等
// initFunc 为设置为此天气时的初始化接受level参数
// frameFunc 为该天气下每帧的效果接受和timestamp参数从页面加载完毕到当前经过的时间
control.prototype.registerWeather = function (name, initFunc, frameFunc) {
this.unregisterWeather(name);
this.weathers[name] = { initFunc: initFunc, frameFunc: frameFunc };
}
////// 取消注册一个天气 //////
control.prototype.unregisterWeather = function (name) {
delete this.weathers[name];
if (core.animateFrame.weather.type == name) {
this.setWeather(null);
}
}
control.prototype._weather_rain = function (level) {
var number = level * parseInt(20*core.bigmap.width*core.bigmap.height/(core.__SIZE__*core.__SIZE__));
for (var a=0;a<number;a++) {
core.animateFrame.weather.nodes.push({
'x': Math.random()*core.bigmap.width*32,
'y': Math.random()*core.bigmap.height*32,
'l': Math.random() * 2.5,
'xs': -4 + Math.random() * 4 + 2,
'ys': Math.random() * 10 + 10
})
}
}
control.prototype._weather_snow = function (level) {
var number = level * parseInt(20*core.bigmap.width*core.bigmap.height/(core.__SIZE__*core.__SIZE__));
for (var a=0;a<number;a++) {
core.animateFrame.weather.nodes.push({
'x': Math.random()*core.bigmap.width*32,
'y': Math.random()*core.bigmap.height*32,
'r': Math.random() * 5 + 1,
'd': Math.random() * Math.min(level, 200),
})
}
}
control.prototype._weather_fog = function (level) {
if (!core.animateFrame.weather.fog) return;
var number = level * parseInt(20*core.bigmap.width*core.bigmap.height/(core.__SIZE__*core.__SIZE__));
core.animateFrame.weather.nodes = [{
'image': core.animateFrame.weather.fog,
'level': number,
'x': 0,
'y': -core.__PIXELS__ / 2,
'dx': -Math.random() * 1.5,
'dy': Math.random(),
'delta': 0.001,
}];
}
control.prototype._weather_cloud = function (level) {
if (!core.animateFrame.weather.cloud) return;
var number = level * parseInt(20*core.bigmap.width*core.bigmap.height/(core.__SIZE__*core.__SIZE__));
core.animateFrame.weather.nodes = [{
'image': core.animateFrame.weather.cloud,
'level': number,
'x': 0,
'y': -core.__PIXELS__ / 2,
'dx': -Math.random() * 1.5,
'dy': Math.random(),
'delta': 0.001,
}];
}
control.prototype._weather_sun = function (level) {
if (!core.animateFrame.weather.sun) return;
// 直接绘制
core.clearMap('weather');
core.drawImage('weather', core.animateFrame.weather.sun, 0, 0, core.animateFrame.weather.sun.width, core.animateFrame.weather.sun.height, 0, 0, core.__PIXELS__, core.__PIXELS__);
core.setOpacity('weather', level / 10);
core.animateFrame.weather.nodes = [{opacity: level / 10, delta: 0.01}];
}
////// 更改画面色调 //////
control.prototype.setCurtain = function(color, time, callback) {
if (time == null) time=750;

View File

@ -460,6 +460,7 @@ events.prototype.battle = function (id, x, y, force, callback) {
if (!id) return core.clearContinueAutomaticRoute(callback);
// 非强制战斗
if (!core.enemys.canBattle(id, x, y) && !force && !core.status.event.id) {
core.stopSound();
core.playSound('操作失败');
core.drawTip("你打不过此怪物!", id);
return core.clearContinueAutomaticRoute(callback);

6
runtime.d.ts vendored
View File

@ -559,6 +559,12 @@ declare class control {
*/
setWeather(type?: 'rain' | 'snow' | 'sun' | 'fog' | 'cloud', level?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10): void
/** 注册一个天气 */
registerWeather(name: string, initFunc: (level: number) => void, frameFunc?: (timestamp: number, level: number) => void): void
/** 注销一个天气 */
unregisterWeather(name: string) : void;
/**
* 使core.events._action_setCurtain()
* @example core.setCurtain(); // 恢复画面色调,用时四分之三秒