Merge branch 'v2.x' of https://github.com/ckcz123/mota-js into v2.x
20
README.md
@ -57,6 +57,26 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
|
||||
|
||||
## 更新说明
|
||||
|
||||
### 2020.6.20 HTML5魔塔样板V2.7.1
|
||||
|
||||
* [x] 编辑器中支持直接对大地图进行编辑
|
||||
* [x] 编辑器支持深色模式
|
||||
* [x] blockly的多行文本显示
|
||||
* [x] 高层塔分区指定
|
||||
* [x] 将素材文件拖到素材区直接自动追加并注册。
|
||||
* [x] 地图多选点(绑定机关门的实现)
|
||||
* [x] 录像折叠
|
||||
* [x] 跳跃事件支持dx和dy
|
||||
* [x] 道具商店支持经验
|
||||
* [x] 瞬移可穿透楼梯;短距离瞬移录像
|
||||
* [x] 编辑器可以回到上个楼层
|
||||
* [x] 跟着存档走的存档笔记
|
||||
* [x] 内置了包含怪物境界、多角色等在内的更多插件
|
||||
* [x] 数据统计指定楼层范围
|
||||
* [x] 重写云雾效果
|
||||
* [x] 毒衰咒不再走公共事件;中毒状态自动寻路毒网
|
||||
* [x] 修复blockly事件块复制粘贴位置的问题
|
||||
|
||||
### 2020.6.7 HTML5魔塔样板V2.7
|
||||
|
||||
* [x] 大幅增强脚本编辑的自动补全和代码提示等功能
|
||||
|
||||
@ -3345,8 +3345,8 @@ AssignOperator_List
|
||||
/*AssignOperator_List ['=','+=','-=','*=','/=','**=','//=','%=']*/;
|
||||
|
||||
Weather_List
|
||||
: '无'|'雨'|'雪'|'雾'
|
||||
/*Weather_List ['null','rain','snow','fog']*/;
|
||||
: '无'|'雨'|'雪'|'雾'|'云'
|
||||
/*Weather_List ['null','rain','snow','fog','cloud']*/;
|
||||
|
||||
B_0_List
|
||||
: '不改变'|'不可通行'|'可以通行'
|
||||
|
||||
@ -45,6 +45,30 @@ var plugins_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
|
||||
"_range": "typeof(thiseval)=='string' || thiseval==null",
|
||||
"_data": "道具商店"
|
||||
},
|
||||
"enemyLevel": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "typeof(thiseval)=='string' || thiseval==null",
|
||||
"_data": "手册显示怪物境界"
|
||||
},
|
||||
"dynamicHp": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "typeof(thiseval)=='string' || thiseval==null",
|
||||
"_data": "动态血量变化"
|
||||
},
|
||||
"multiHeros": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "typeof(thiseval)=='string' || thiseval==null",
|
||||
"_data": "多角色"
|
||||
},
|
||||
"flyHideFloors": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_range": "typeof(thiseval)=='string' || thiseval==null",
|
||||
"_data": "楼传可以跳过楼层"
|
||||
},
|
||||
"smoothCamera": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
|
||||
@ -258,35 +258,50 @@ control.prototype._animationFrame_weather_snow = function () {
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
control.prototype._animationFrame_weather_fog = function () {
|
||||
var ctx = core.dymCanvas.weather, ox = core.bigmap.offsetX, oy = core.bigmap.offsetY;
|
||||
core.clearMap('weather');
|
||||
if (core.animateFrame.weather.fog) {
|
||||
var w = core.__PIXELS__, h = core.__PIXELS__;
|
||||
core.setAlpha('weather', 0.5);
|
||||
core.animateFrame.weather.nodes.forEach(function (p) {
|
||||
core.drawImage(ctx, core.animateFrame.weather.fog, p.x - ox, p.y - oy, w, h);
|
||||
p.x += p.xs;
|
||||
p.y += p.ys;
|
||||
if (p.x > core.bigmap.width*32 - w/2) {
|
||||
p.x = core.bigmap.width*32 - w/2 - 1;
|
||||
p.xs = -p.xs;
|
||||
}
|
||||
if (p.x < -w/2) {
|
||||
p.x = -w/2+1;
|
||||
p.xs = -p.xs;
|
||||
}
|
||||
if (p.y > core.bigmap.height*32 - h/2) {
|
||||
p.y = core.bigmap.height*32 - h/2 - 1;
|
||||
p.ys = -p.ys;
|
||||
}
|
||||
if (p.y < -h/2) {
|
||||
p.y = -h/2+1;
|
||||
p.ys = -p.ys;
|
||||
}
|
||||
});
|
||||
core.setAlpha('weather',1);
|
||||
control.prototype.__animateFrame_weather_image = function (image) {
|
||||
if (!image) return;
|
||||
var node = core.animateFrame.weather.nodes[0];
|
||||
core.setAlpha('weather', node.level / 500);
|
||||
var wind = 1.5;
|
||||
var width = image.width, height = image.height;
|
||||
node.x += node.dx * wind;
|
||||
node.y += (2 * node.dy - 1) * wind;
|
||||
if (node.x + 3 * width <= core.__PIXELS__) {
|
||||
node.x += 4 * width;
|
||||
while (node.x > 0) node.x -= width;
|
||||
}
|
||||
node.dy += node.delta;
|
||||
if (node.dy >= 1) {
|
||||
node.delta = -0.001;
|
||||
} else if (node.dy <= 0) {
|
||||
node.delta = 0.001;
|
||||
}
|
||||
if (node.y + 3 * height <= core.__PIXELS__) {
|
||||
node.y += 4 * height;
|
||||
while (node.y > 0) node.y -= height;
|
||||
}
|
||||
else if (node.y >= 0) {
|
||||
node.y -= height;
|
||||
}
|
||||
for (var i = 0; i < 3; ++i) {
|
||||
for (var j = 0; j < 3; ++j) {
|
||||
if (node.x + (i + 1) * width <= 0 || node.x + i * width >= core.__PIXELS__
|
||||
|| node.y + (j + 1) * height <= 0 || node.y + j * height >= core.__PIXELS__)
|
||||
continue;
|
||||
core.drawImage('weather', image, node.x + i * width, node.y + j * height);
|
||||
}
|
||||
}
|
||||
core.setAlpha('weather',1);
|
||||
}
|
||||
|
||||
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._animateFrame_tip = function (timestamp) {
|
||||
@ -2279,14 +2294,26 @@ control.prototype._setWeather_createNodes = function (type, level) {
|
||||
break;
|
||||
case 'fog':
|
||||
if (core.animateFrame.weather.fog) {
|
||||
for (var a=0;a<level/10;a++) {
|
||||
core.animateFrame.weather.nodes.push({
|
||||
'x': Math.random()*core.bigmap.width*32 - 208,
|
||||
'y': Math.random()*core.bigmap.height*32 - 208,
|
||||
'xs': Math.random() * 4 - 2,
|
||||
'ys': Math.random() * 4 - 2
|
||||
})
|
||||
}
|
||||
core.animateFrame.weather.nodes = [{
|
||||
'level': level,
|
||||
'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': level,
|
||||
'x': 0,
|
||||
'y': -core.__PIXELS__ / 2,
|
||||
'dx': -Math.random() * 1.5,
|
||||
'dy': Math.random(),
|
||||
'delta': 0.001,
|
||||
}];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -392,6 +392,7 @@ core.prototype._init_others = function () {
|
||||
core.material.groundPattern = core.material.groundCanvas.createPattern(core.material.groundCanvas.canvas, 'repeat');
|
||||
core.bigmap.tempCanvas = document.createElement('canvas').getContext('2d');
|
||||
core.loadImage("materials", 'fog', function (name, img) { core.animateFrame.weather.fog = img; });
|
||||
core.loadImage("materials", "cloud", function (name, img) { core.animateFrame.weather.cloud = img; })
|
||||
core.loadImage("materials", 'keyboard', function (name, img) {core.material.images.keyboard = img; });
|
||||
// 记录存档编号
|
||||
core.saves.saveIndex = core.getLocalStorage('saveIndex', 1);
|
||||
|
||||
@ -1581,7 +1581,7 @@ events.prototype._action_screenFlash = function (data, x, y, prefix) {
|
||||
|
||||
events.prototype._action_setWeather = function (data, x, y, prefix) {
|
||||
core.setWeather(data.name, data.level);
|
||||
if ((data.name == 'rain' || data.name == 'snow' || data.name == 'fog') && data.keep)
|
||||
if (data.keep && ['rain', 'snow', 'fog', 'cloud'].indexOf(data.name) >= 0)
|
||||
core.setFlag('__weather__', [data.name, data.level]);
|
||||
else core.removeFlag('__weather__');
|
||||
core.doAction();
|
||||
|
||||
2
main.js
@ -187,7 +187,7 @@ function main() {
|
||||
this.canvas = {};
|
||||
|
||||
this.__VERSION__ = "2.7.1";
|
||||
this.__VERSION_CODE__ = 153;
|
||||
this.__VERSION_CODE__ = 176;
|
||||
}
|
||||
|
||||
main.prototype.init = function (mode, callback) {
|
||||
|
||||
@ -11,8 +11,8 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
||||
"floorPartitions": [],
|
||||
"images": [
|
||||
"bg.jpg",
|
||||
"winskin.png",
|
||||
"hero.png"
|
||||
"hero.png",
|
||||
"winskin.png"
|
||||
],
|
||||
"tilesets": [
|
||||
"magictower.png"
|
||||
|
||||
@ -223,8 +223,8 @@ main.floors.sample0=
|
||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0,10169, 0,10177, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0,10170, 0,10178, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0,10171, 0,10179, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0,10170, 0,10185, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0,10169, 0,10179, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0,10172, 0,10180, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0,10186, 0,10181, 0, 0, 0, 0, 0],
|
||||
[ 0, 0, 0, 0, 0,10187, 0,10182, 0, 0, 0, 0, 0],
|
||||
|
||||
BIN
project/images/brave.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
project/materials/cloud.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB |
@ -317,12 +317,12 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
|
||||
}
|
||||
},
|
||||
"fiveLayers": function () {
|
||||
// 是否启用五图层(增加背景2层和前景2层) 将__enableFiveLayers置为true即会启用;启用后请保存后刷新编辑器
|
||||
// 是否启用五图层(增加背景2层和前景2层) 将__enable置为true即会启用;启用后请保存后刷新编辑器
|
||||
// 背景层2将会覆盖背景层 被事件层覆盖 前景层2将会覆盖前景层
|
||||
// 另外 请注意加入两个新图层 会让大地图的性能降低一些
|
||||
// 插件作者:ad
|
||||
var __enableFiveLayers = false;
|
||||
if (!__enableFiveLayers) return;
|
||||
var __enable = false;
|
||||
if (!__enable) return;
|
||||
|
||||
// 创建新图层
|
||||
function createCanvas(name, zIndex) {
|
||||
@ -344,6 +344,8 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
|
||||
var fg2Canvas = createCanvas('fg2', 63);
|
||||
// 大地图适配
|
||||
core.bigmap.canvas = ["bg2", "fg2", "bg", "event", "event2", "fg", "damage"];
|
||||
core.initStatus.bg2maps = {};
|
||||
core.initStatus.fg2maps = {};
|
||||
|
||||
if (main.mode == 'editor') {
|
||||
/*插入编辑器的图层 不做此步新增图层无法在编辑器显示*/
|
||||
@ -891,14 +893,356 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 =
|
||||
]);
|
||||
}
|
||||
|
||||
},
|
||||
"enemyLevel": function () {
|
||||
// 此插件将提供怪物手册中的怪物境界显示
|
||||
// 使用此插件需要先给每个怪物定义境界,方法如下:
|
||||
// 点击怪物的【配置表格】,找到“【怪物】相关的表格配置”,然后在【名称】仿照增加境界定义:
|
||||
/*
|
||||
"level": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_string": true,
|
||||
"_data": "境界"
|
||||
},
|
||||
*/
|
||||
// 然后保存刷新,可以看到怪物的属性定义中出现了【境界】。再开启本插件即可。
|
||||
|
||||
// 是否开启本插件,默认禁用;将此改成 true 将启用本插件。
|
||||
var __enable = false;
|
||||
if (!__enable) return;
|
||||
|
||||
// 这里定义每个境界的显示颜色;可以写'red', '#RRGGBB' 或者[r,g,b,a]四元数组
|
||||
var levelToColors = {
|
||||
"萌新一阶": "red",
|
||||
"萌新二阶": "#FF0000",
|
||||
"萌新三阶": [255, 0, 0, 1],
|
||||
};
|
||||
|
||||
// 复写 _drawBook_drawName
|
||||
var originDrawBook = core.ui._drawBook_drawName;
|
||||
core.ui._drawBook_drawName = function (index, enemy, top, left, width) {
|
||||
// 如果没有境界,则直接调用原始代码绘制
|
||||
if (!enemy.level) return originDrawBook.call(core.ui, index, enemy, top, left, width);
|
||||
// 存在境界,则额外进行绘制
|
||||
core.setTextAlign('ui', 'center');
|
||||
if (enemy.specialText.length == 0) {
|
||||
core.fillText('ui', enemy.name, left + width / 2,
|
||||
top + 27, '#DDDDDD', this._buildFont(17, true));
|
||||
core.fillText('ui', enemy.level, left + width / 2,
|
||||
top + 51, core.arrayToRGBA(levelToColors[enemy.level] || '#DDDDDD'), this._buildFont(14, true));
|
||||
} else {
|
||||
core.fillText('ui', enemy.name, left + width / 2,
|
||||
top + 20, '#DDDDDD', this._buildFont(17, true), width);
|
||||
switch (enemy.specialText.length) {
|
||||
case 1:
|
||||
core.fillText('ui', enemy.specialText[0], left + width / 2,
|
||||
top + 38, core.arrayToRGBA((enemy.specialColor || [])[0] || '#FF6A6A'),
|
||||
this._buildFont(14, true), width);
|
||||
break;
|
||||
case 2:
|
||||
// Step 1: 计算字体
|
||||
var text = enemy.specialText[0] + " " + enemy.specialText[1];
|
||||
core.setFontForMaxWidth('ui', text, width, this._buildFont(14, true));
|
||||
// Step 2: 计算总宽度
|
||||
var totalWidth = core.calWidth('ui', text);
|
||||
var leftWidth = core.calWidth('ui', enemy.specialText[0]);
|
||||
var rightWidth = core.calWidth('ui', enemy.specialText[1]);
|
||||
// Step 3: 绘制
|
||||
core.fillText('ui', enemy.specialText[0], left + (width + leftWidth - totalWidth) / 2,
|
||||
top + 38, core.arrayToRGBA((enemy.specialColor || [])[0] || '#FF6A6A'));
|
||||
core.fillText('ui', enemy.specialText[1], left + (width + totalWidth - rightWidth) / 2,
|
||||
top + 38, core.arrayToRGBA((enemy.specialColor || [])[1] || '#FF6A6A'));
|
||||
break;
|
||||
default:
|
||||
core.fillText('ui', '多属性...', left + width / 2,
|
||||
top + 38, '#FF6A6A', this._buildFont(14, true), width);
|
||||
}
|
||||
core.fillText('ui', enemy.level, left + width / 2,
|
||||
top + 56, core.arrayToRGBA(levelToColors[enemy.level] || '#DDDDDD'), this._buildFont(14, true));
|
||||
}
|
||||
}
|
||||
|
||||
// 也可以复写其他的属性颜色如怪物攻防等,具体参见下面的例子的注释部分
|
||||
core.ui._drawBook_drawRow1 = function (index, enemy, top, left, width, position) {
|
||||
// 绘制第一行
|
||||
core.setTextAlign('ui', 'left');
|
||||
var b13 = this._buildFont(13, true),
|
||||
f13 = this._buildFont(13, false);
|
||||
var col1 = left,
|
||||
col2 = left + width * 9 / 25,
|
||||
col3 = left + width * 17 / 25;
|
||||
core.fillText('ui', '生命', col1, position, '#DDDDDD', f13);
|
||||
core.fillText('ui', core.formatBigNumber(enemy.hp || 0), col1 + 30, position, /*'red' */ null, b13);
|
||||
core.fillText('ui', '攻击', col2, position, null, f13);
|
||||
core.fillText('ui', core.formatBigNumber(enemy.atk || 0), col2 + 30, position, /* '#FF0000' */ null, b13);
|
||||
core.fillText('ui', '防御', col3, position, null, f13);
|
||||
core.fillText('ui', core.formatBigNumber(enemy.def || 0), col3 + 30, position, /* [255, 0, 0, 1] */ null, b13);
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
"dynamicHp": function () {
|
||||
// 此插件允许人物血量动态进行变化
|
||||
// 原作:Fux2(老黄鸡)
|
||||
|
||||
// 是否开启本插件,默认禁用;将此改成 true 将启用本插件。
|
||||
var __enable = false;
|
||||
if (!__enable) return;
|
||||
|
||||
var speed = 0.05; // 动态血量变化速度,越大越快。
|
||||
|
||||
var _currentHp = null;
|
||||
var _lastStatus = null;
|
||||
var _check = function () {
|
||||
if (_lastStatus != core.status.hero) {
|
||||
_lastStatus = core.status.hero;
|
||||
_currentHp = core.status.hero.hp;
|
||||
}
|
||||
}
|
||||
|
||||
core.registerAnimationFrame('dynamicHp', true, function () {
|
||||
_check();
|
||||
if (core.status.hero.hp != _currentHp) {
|
||||
var dis = (_currentHp - core.status.hero.hp) * speed;
|
||||
if (Math.abs(dis) < 2) {
|
||||
_currentHp = core.status.hero.hp;
|
||||
} else {
|
||||
_currentHp -= dis;
|
||||
}
|
||||
core.setStatusBarInnerHTML('hp', _currentHp);
|
||||
}
|
||||
});
|
||||
},
|
||||
"multiHeros": function () {
|
||||
// 多角色插件
|
||||
// Step 1: 启用本插件
|
||||
// Step 2: 定义每个新的角色各项初始数据(参见下方注释)
|
||||
// Step 3: 在游戏中的任何地方都可以调用 `core.changeHero()` 进行切换;也可以 `core.changeHero(1)` 来切换到某个具体的角色上
|
||||
|
||||
// 是否开启本插件,默认禁用;将此改成 true 将启用本插件。
|
||||
var __enable = false;
|
||||
if (!__enable) return;
|
||||
|
||||
// 在这里定义全部的新角色属性
|
||||
// 请注意,在这里定义的内容不会多角色共用,在切换时会进行恢复。
|
||||
// 你也可以自行新增或删除,比如不共用金币则可以加上"money"的初始化,不共用道具则可以加上"items"的初始化,
|
||||
// 多角色共用hp的话则删除hp,等等。总之,不共用的属性都在这里进行定义就好。
|
||||
var hero1 = {
|
||||
"floorId": "MT0", // 该角色初始楼层ID;如果共用楼层可以注释此项
|
||||
"image": "brave.png", // 角色的行走图名称;此项必填不然会报错
|
||||
"name": "1号角色",
|
||||
"lv": 1,
|
||||
"hp": 10000, // 如果HP共用可注释此项
|
||||
"atk": 1000,
|
||||
"def": 1000,
|
||||
"mdef": 0,
|
||||
// "money": 0, // 如果要不共用金币则取消此项注释
|
||||
// "exp": 0, // 如果要不共用经验则取消此项注释
|
||||
"loc": { "x": 0, "y": 0, "direction": "up" }, // 该角色初始位置;如果共用位置可注释此项
|
||||
"items": {
|
||||
"tools": {}, // 如果共用消耗道具(含钥匙)则可注释此项
|
||||
// "constants": {}, // 如果不共用永久道具(如手册)可取消注释此项
|
||||
"equips": {}, // 如果共用在背包的装备可注释此项
|
||||
},
|
||||
"equipment": [], // 如果共用装备可注释此项;此项和上面的「共用在背包的装备」需要拥有相同状态,不然可能出现问题
|
||||
};
|
||||
// 也可以类似新增其他角色
|
||||
// 新增的角色,各项属性共用与不共用的选择必须和上面完全相同,否则可能出现问题。
|
||||
// var hero2 = { ...
|
||||
|
||||
var heroCount = 2; // 包含默认角色在内总共多少个角色,该值需手动修改。
|
||||
|
||||
this.initHeros = function () {
|
||||
core.setFlag("hero1", core.clone(hero1)); // 将属性值存到变量中
|
||||
// core.setFlag("hero2", core.clone(hero2)); // 更多的角色也存入变量中;每个定义的角色都需要新增一行
|
||||
|
||||
// 检测是否存在装备
|
||||
if (hero1.equipment) {
|
||||
if (!hero1.items || !hero1.items.equips) {
|
||||
alert('多角色插件的equipment和道具中的equips必须拥有相同状态!');
|
||||
}
|
||||
// 存99号套装为全空
|
||||
var saveEquips = core.getFlag("saveEquips", []);
|
||||
saveEquips[99] = [];
|
||||
core.setFlag("saveEquips", saveEquips);
|
||||
} else {
|
||||
if (hero1.items && hero1.items.equips) {
|
||||
alert('多角色插件的equipment和道具中的equips必须拥有相同状态!');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 在游戏开始注入initHeros
|
||||
var _startGame_setHard = core.events._startGame_setHard;
|
||||
core.events._startGame_setHard = function () {
|
||||
_startGame_setHard.call(core.events);
|
||||
core.initHeros();
|
||||
}
|
||||
|
||||
// 切换角色
|
||||
// 可以使用 core.changeHero() 来切换到下一个角色
|
||||
// 也可以 core.changeHero(1) 来切换到某个角色(默认角色为0)
|
||||
this.changeHero = function (toHeroId) {
|
||||
var currHeroId = core.getFlag("heroId", 0); // 获得当前角色ID
|
||||
if (toHeroId == null) {
|
||||
toHeroId = (currHeroId + 1) % heroCount;
|
||||
}
|
||||
if (currHeroId == toHeroId) return;
|
||||
|
||||
var saveList = Object.keys(hero1);
|
||||
|
||||
// 保存当前内容
|
||||
var toSave = {};
|
||||
// 暂时干掉 drawTip 和 音效,避免切装时的提示
|
||||
var _drawTip = core.ui.drawTip;
|
||||
core.ui.drawTip = function () {};
|
||||
var _playSound = core.control.playSound;
|
||||
core.control.playSound = function () {}
|
||||
// 优先判定装备
|
||||
if (hero1.equipment) {
|
||||
core.items.quickSaveEquip(100 + currHeroId);
|
||||
core.items.quickLoadEquip(99);
|
||||
}
|
||||
|
||||
saveList.forEach(function (name) {
|
||||
if (name == 'floorId') toSave[name] = core.status.floorId; // 楼层单独设置
|
||||
else if (name == 'items') {
|
||||
toSave.items = core.clone(core.status.hero.items);
|
||||
Object.keys(toSave.items).forEach(function (one) {
|
||||
if (!hero1.items[one]) delete toSave.items[one];
|
||||
});
|
||||
} else toSave[name] = core.clone(core.status.hero[name]); // 使用core.clone()来创建新对象
|
||||
});
|
||||
|
||||
core.setFlag("hero" + currHeroId, toSave); // 将当前角色信息进行保存
|
||||
var data = core.getFlag("hero" + toHeroId); // 获得要切换的角色保存内容
|
||||
|
||||
// 设置角色的属性值
|
||||
saveList.forEach(function (name) {
|
||||
if (name == "floorId");
|
||||
else if (name == "items") {
|
||||
Object.keys(core.status.hero.items).forEach(function (one) {
|
||||
if (data.items[one]) core.status.hero.items[one] = core.clone(data.items[one]);
|
||||
});
|
||||
} else {
|
||||
core.status.hero[name] = core.clone(data[name]);
|
||||
}
|
||||
});
|
||||
// 最后装上装备
|
||||
if (hero1.equipment) {
|
||||
core.items.quickLoadEquip(100 + toHeroId);
|
||||
}
|
||||
|
||||
core.ui.drawTip = _drawTip;
|
||||
core.control.playSound = _playSound;
|
||||
|
||||
// 插入事件:改变角色行走图并进行楼层切换
|
||||
var toFloorId = data.floorId || core.status.floorId;
|
||||
var toLoc = data.loc || core.status.hero.loc;
|
||||
core.insertAction([
|
||||
{ "type": "setHeroIcon", "name": data.image || "hero.png" }, // 改变行走图
|
||||
// 同层则用changePos,不同层则用changeFloor;这是为了避免共用楼层造成触发eachArrive
|
||||
toFloorId != core.status.floorId ? {
|
||||
"type": "changeFloor",
|
||||
"floorId": toFloorId,
|
||||
"loc": [toLoc.x, toLoc.y],
|
||||
"direction": toLoc.direction,
|
||||
"time": 0 // 可以在这里设置切换时间
|
||||
} : { "type": "changePos", "loc": [toLoc.x, toLoc.y], "direction": toLoc.direction }
|
||||
// 你还可以在这里执行其他事件,比如增加或取消跟随效果
|
||||
]);
|
||||
core.setFlag("heroId", toHeroId); // 保存切换到的角色ID
|
||||
}
|
||||
},
|
||||
"flyHideFloors": function () {
|
||||
// 此插件可以让用户在楼传页面手动隐藏某些楼层
|
||||
// 原作:一桶天下
|
||||
|
||||
// 是否开启本插件,默认禁用;将此改成 true 将启用本插件。
|
||||
var __enable = false;
|
||||
if (!__enable) return;
|
||||
|
||||
var _drawFly = core.ui.drawFly;
|
||||
core.ui.drawFly = function (page) {
|
||||
_drawFly.call(core.ui, page);
|
||||
// 绘制「显示本层」和「显示全部」
|
||||
var __hideFloors__ = core.getFlag('__hideFloors__', {});
|
||||
var __showAllFloor__ = core.getFlag('__showAllFloor__', false);
|
||||
var floorId = core.floorIds[page];
|
||||
core.fillText('ui', '显示该层', this.HPIXEL - 120, 60, __hideFloors__[floorId] ? '#FFFFFF' : 'yellow', this._buildFont(20, false));
|
||||
core.fillText('ui', '显示全部', this.HPIXEL + 120, 60, !__showAllFloor__ ? '#FFFFFF' : 'yellow', this._buildFont(20, false));
|
||||
}
|
||||
|
||||
var _clickFly = core.actions._clickFly;
|
||||
core.actions._clickFly = function (x, y) {
|
||||
_clickFly.call(core.actions, x, y);
|
||||
|
||||
var __hideFloors__ = core.getFlag('__hideFloors__', {})
|
||||
var __showAllFloor__ = core.getFlag('__showAllFloor__', false)
|
||||
var _floorId = core.floorIds[core.status.event.data]
|
||||
|
||||
if (y == 1 && x >= this.HSIZE - 5 && x <= this.HSIZE - 2) {
|
||||
__hideFloors__[_floorId] = !__hideFloors__[_floorId]
|
||||
core.setFlag('__hideFloors__', __hideFloors__)
|
||||
core.ui.drawFly(this._getNextFlyFloor(0))
|
||||
}
|
||||
if (y == 1 && x >= this.HSIZE + 2 && x <= this.HSIZE + 5) {
|
||||
core.setFlag('__showAllFloor__', !__showAllFloor__)
|
||||
core.ui.drawFly(this._getNextFlyFloor(0))
|
||||
}
|
||||
}
|
||||
|
||||
var _keyUpFly = core.actions._keyUpFly;
|
||||
core.actions._keyUpFly = function (keycode) {
|
||||
_keyUpFly.call(core.actions, keycode);
|
||||
|
||||
var __hideFloors__ = core.getFlag('__hideFloors__', {})
|
||||
var __showAllFloor__ = core.getFlag('__showAllFloor__', false)
|
||||
var _floorId = core.floorIds[core.status.event.data]
|
||||
|
||||
// Q
|
||||
if (keycode == 81) {
|
||||
__hideFloors__[_floorId] = !__hideFloors__[_floorId]
|
||||
core.setFlag('__hideFloors__', __hideFloors__)
|
||||
core.ui.drawFly(this._getNextFlyFloor(0));
|
||||
} else if (keycode == 69) {
|
||||
// E
|
||||
core.setFlag('__showAllFloor__', !__showAllFloor__)
|
||||
core.ui.drawFly(this._getNextFlyFloor(0))
|
||||
}
|
||||
}
|
||||
|
||||
core.actions._getNextFlyFloor = function (delta, index) {
|
||||
var __hideFloors__ = core.getFlag('__hideFloors__', {})
|
||||
var __showAllFloor__ = core.getFlag('__showAllFloor__', false)
|
||||
if (index == null) index = core.status.event.data;
|
||||
if (delta == 0) return index;
|
||||
var sign = Math.sign(delta);
|
||||
delta = Math.abs(delta);
|
||||
var ans = index;
|
||||
while (true) {
|
||||
index += sign;
|
||||
if (index < 0 || index >= core.floorIds.length) break;
|
||||
var floorId = core.floorIds[index];
|
||||
if (core.status.maps[floorId].canFlyTo && core.hasVisitedFloor(floorId) && (__showAllFloor__ || !__hideFloors__[floorId])) {
|
||||
delta--;
|
||||
ans = index;
|
||||
}
|
||||
if (delta == 0) break;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
"smoothCamera": function () {
|
||||
// 此插件开启后,大地图的瞬间移动将开启平滑镜头移动,避免突兀感
|
||||
// 插件作者:老黄鸡
|
||||
|
||||
// 是否启用本插件,默认不启用
|
||||
this.__enableSmoothCamera = false;
|
||||
if (!this.__enableSmoothCamera) return;
|
||||
var __enable = false;
|
||||
if (!__enable) return;
|
||||
|
||||
this.Camera = function () {
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 162 KiB |
5
runtime.d.ts
vendored
@ -533,7 +533,7 @@ declare class control {
|
||||
* @param type 新天气的类型,不填视为晴天
|
||||
* @param level 新天气(晴天除外)的级别,必须为不大于10的正整数,不填视为5
|
||||
*/
|
||||
setWeather(type?: 'rain' | 'snow' | 'fog', level?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10): void
|
||||
setWeather(type?: 'rain' | 'snow' | 'fog' | 'cloud', level?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10): void
|
||||
|
||||
/**
|
||||
* 更改画面色调,不计入存档。如需长期生效请使用core.events._action_setCurtain()函数
|
||||
@ -2690,7 +2690,8 @@ type core = {
|
||||
type: any
|
||||
nodes: [],
|
||||
data: any
|
||||
fog: any
|
||||
fog: any,
|
||||
cloud: any,
|
||||
},
|
||||
tips: {
|
||||
time: number
|
||||
|
||||