commit
aa4c3a9251
17
README.md
17
README.md
@ -53,6 +53,23 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
|
||||
|
||||
## 更新说明
|
||||
|
||||
### 2019.2.4 V2.5.4
|
||||
|
||||
* [x] 发布15x15的版本
|
||||
* [x] 支持多重装备(一个装备可以装到多个孔上)
|
||||
* [x] 工具栏按钮增添至8个,快捷商店和虚拟键盘同时显示
|
||||
* [x] 点击状态栏的金币图标也可以打开快捷商店
|
||||
* [x] 等待事件提供flag:px和flag:py在0~415之间
|
||||
* [x] 事件:呼出存读档界面;呼出怪物手册
|
||||
* [x] 事件:使用道具,暂停背景音乐,暂停所有音效
|
||||
* [x] type:trigger可以触发系统事件
|
||||
* [x] 独立开关
|
||||
* [x] 贴图也可以支持帧动画了
|
||||
* [x] 图块内置颜色选择器
|
||||
* [x] 标题界面增加音乐按钮
|
||||
* [x] 等待事件可被Ctrl(长按)跳过
|
||||
* [x] 部分Bug修复,大量细节优化,性能进一步得到提升
|
||||
|
||||
### 2018.12.22 V2.5.3
|
||||
|
||||
* [x] 标题界面事件化;现在可以用事件流来处理标题界面了
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
# editor
|
||||
|
||||
>! 以下均是v2.0时的说明, 未及时改动
|
||||
|
||||
本目录下所有文件,以及`../editor.html`和`../启动服务.exe`([源码](http://github.com/ckcz123/mota-js-server/))是地图编辑器的所有组件.
|
||||
|
||||
`editor.js`,`editor_file.js`和`editor_mode.js`耦合较强,`editor_blockly.js`和`editor_multi.js`和`fs.js`基本可以独立使用.
|
||||
@ -103,23 +105,6 @@ editor_mode.onmode(editor_mode._ids[node.getAttribute('id')]);
|
||||
|
||||
`editor.mode.listen`中提供了追加素材的支持.
|
||||
|
||||
处理注释的特殊指令
|
||||
```
|
||||
$range(evalstr:thiseval)$end
|
||||
限制取值范围,要求修改后的eval(evalstr)为true
|
||||
$leaf(evalstr:thiseval)$end
|
||||
强制指定为叶节点,如果eval(evalstr)为true
|
||||
|
||||
//以下几个中选一个 [
|
||||
$select(evalstr)$end
|
||||
渲染成<select>,选项为数组eval(evalstr)['values']
|
||||
$input(evalstr)$end
|
||||
渲染成<input>
|
||||
$textarea(evalstr)$end
|
||||
渲染成<textarea>
|
||||
默认选项为$textarea()$end
|
||||
// ]
|
||||
```
|
||||
|
||||
### editor_blockly.js
|
||||
|
||||
@ -177,9 +162,3 @@ fs.readdir(path, callback)
|
||||
//所有参数不允许缺省
|
||||
```
|
||||
|
||||
## z-index
|
||||
|
||||
目前主体部分使用了 0-15,75,100
|
||||
|
||||
blockly使用 200,201
|
||||
多行文本编辑器使用 300
|
||||
@ -26,17 +26,6 @@ code=JSON.stringify(code,null,2).split('"data_asdfefw"').join('[\n'+action_0+']\
|
||||
return code;
|
||||
*/;
|
||||
|
||||
//加点 事件编辑器入口之一
|
||||
point_m
|
||||
: '加点' BGNL? Newline choicesContext+ BEND
|
||||
|
||||
|
||||
/* point_m
|
||||
tooltip : 加点事件
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=%e5%8a%a0%e7%82%b9%e4%ba%8b%e4%bb%b6
|
||||
var code = '{"type": "choices", "choices": [\n'+choicesContext_0+']}\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
//升级 事件编辑器入口之一
|
||||
level_m
|
||||
@ -217,6 +206,18 @@ var code = '{"floorId": "'+toFloorId+'"'+loc+DirectionEx_List_0+Int_0+Bool_0+' }
|
||||
return code;
|
||||
*/;
|
||||
|
||||
//commonEvent 事件编辑器入口之一
|
||||
commonEvent_m
|
||||
: '公共事件' BGNL? Newline action+ BEND
|
||||
|
||||
|
||||
/* commonEvent_m
|
||||
tooltip : 公共事件
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event
|
||||
var code = '[\n'+action_0+']\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
//为了避免关键字冲突,全部加了_s
|
||||
//动作
|
||||
action
|
||||
@ -235,7 +236,8 @@ action
|
||||
| show_s
|
||||
| hide_s
|
||||
| trigger_s
|
||||
| insert_s
|
||||
| insert_1_s
|
||||
| insert_2_s
|
||||
| revisit_s
|
||||
| exit_s
|
||||
| setBlock_s
|
||||
@ -284,6 +286,7 @@ action
|
||||
| loadBgm_s
|
||||
| freeBgm_s
|
||||
| playSound_s
|
||||
| stopSound_s
|
||||
| setVolume_s
|
||||
| win_s
|
||||
| lose_s
|
||||
@ -598,13 +601,26 @@ var code = '{"type": "trigger", "loc": ['+PosString_0+','+PosString_1+']},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
insert_s
|
||||
insert_1_s
|
||||
: '插入公共事件' EvalString Newline
|
||||
|
||||
|
||||
/* insert_1_s
|
||||
tooltip : insert: 插入公共事件并执行
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=insert%ef%bc%9a%e6%8f%92%e5%85%a5%e5%85%ac%e5%85%b1%e4%ba%8b%e4%bb%b6%e6%88%96%e5%8f%a6%e4%b8%80%e4%b8%aa%e5%9c%b0%e7%82%b9%e7%9a%84%e4%ba%8b%e4%bb%b6%e5%b9%b6%e6%89%a7%e8%a1%8c
|
||||
default : ["加点事件"]
|
||||
colour : this.eventColor
|
||||
var code = '{"type": "insert", "name": "'+EvalString_0+'"},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
insert_2_s
|
||||
: '插入事件' 'x' PosString ',' 'y' PosString '楼层' IdString? Newline
|
||||
|
||||
|
||||
/* insert_s
|
||||
/* insert_2_s
|
||||
tooltip : insert: 立即插入另一个地点的事件执行,当前事件不会中断,事件坐标不会改变
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=insert%ef%bc%9a%e6%8f%92%e5%85%a5%e5%8f%a6%e4%b8%80%e4%b8%aa%e5%9c%b0%e7%82%b9%e7%9a%84%e4%ba%8b%e4%bb%b6
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=insert%ef%bc%9a%e6%8f%92%e5%85%a5%e5%85%ac%e5%85%b1%e4%ba%8b%e4%bb%b6%e6%88%96%e5%8f%a6%e4%b8%80%e4%b8%aa%e5%9c%b0%e7%82%b9%e7%9a%84%e4%ba%8b%e4%bb%b6%e5%b9%b6%e6%89%a7%e8%a1%8c
|
||||
default : ["0","0",""]
|
||||
colour : this.eventColor
|
||||
IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"');
|
||||
@ -785,7 +801,7 @@ setBgFgBlock_s
|
||||
/* setBgFgBlock_s
|
||||
tooltip : setBgFgBlock:设置某个图层块,忽略坐标楼层则为当前点
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=setblock%EF%BC%9A%E8%AE%BE%E7%BD%AE%E6%9F%90%E4%B8%AA%E5%9B%BE%E5%9D%97
|
||||
colour : this.eventColor
|
||||
colour : this.dataColor
|
||||
default : ["bg",0,"","",""]
|
||||
var floorstr = '';
|
||||
if (PosString_0 && PosString_1) {
|
||||
@ -889,20 +905,21 @@ return code;
|
||||
*/;
|
||||
|
||||
openDoor_s
|
||||
: '开门' 'x' PosString? ',' 'y' PosString? '楼层' IdString? Newline
|
||||
: '开门' 'x' PosString? ',' 'y' PosString? '楼层' IdString? '需要钥匙' Bool? Newline
|
||||
|
||||
|
||||
/* openDoor_s
|
||||
tooltip : openDoor: 开门,楼层可不填表示当前层
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=opendoor%EF%BC%9A%E5%BC%80%E9%97%A8
|
||||
default : ["","",""]
|
||||
default : ["","","",false]
|
||||
colour : this.dataColor
|
||||
IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"');
|
||||
var floorstr = '';
|
||||
if (PosString_0 && PosString_1) {
|
||||
floorstr = ', "loc": ['+PosString_0+','+PosString_1+']';
|
||||
}
|
||||
var code = '{"type": "openDoor"'+floorstr+IdString_0+'},\n';
|
||||
Bool_0 = Bool_0 ? ', "needKey": true' : '';
|
||||
var code = '{"type": "openDoor"'+floorstr+IdString_0+Bool_0+'},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
@ -1366,6 +1383,18 @@ var code = '{"type": "playSound", "name": "'+EvalString_0+'"},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
stopSound_s
|
||||
: '停止所有音效' Newline
|
||||
|
||||
|
||||
/* stopSound_s
|
||||
tooltip : stopSound: 停止所有音效
|
||||
helpUrl : https://h5mota.com/games/template/docs/#/event?id=stopSound%ef%bc%9a%e5%81%9c%e6%ad%a2%e6%89%80%e6%9c%89%e9%9f%b3%e6%95%88
|
||||
colour : this.soundColor
|
||||
var code = '{"type": "stopSound"},\n';
|
||||
return code;
|
||||
*/;
|
||||
|
||||
setVolume_s
|
||||
: '设置音量' Int '渐变时间' Int? '不等待执行完毕' Bool Newline
|
||||
|
||||
@ -1960,15 +1989,6 @@ ActionParser.prototype.parse = function (obj,type) {
|
||||
obj.time,!this.isset(obj.portalWithoutTrigger)
|
||||
]);
|
||||
|
||||
case 'point':
|
||||
if(!obj)obj={};
|
||||
var text_choices = null;
|
||||
for(var ii=obj.choices.length-1,choice;choice=obj.choices[ii];ii--) {
|
||||
text_choices=MotaActionBlocks['choicesContext'].xmlText([
|
||||
choice.text,this.parseList(choice.action),text_choices]);
|
||||
}
|
||||
return MotaActionBlocks['point_m'].xmlText([text_choices]);
|
||||
|
||||
case 'level':
|
||||
if(!obj)obj={};
|
||||
var text_choices = null;
|
||||
@ -2264,7 +2284,7 @@ ActionParser.prototype.parseAction = function() {
|
||||
case "openDoor": // 开一个门, 包括暗墙
|
||||
data.loc=data.loc||['','']
|
||||
this.next = MotaActionBlocks['openDoor_s'].xmlText([
|
||||
data.loc[0],data.loc[1],data.floorId||'',this.next]);
|
||||
data.loc[0],data.loc[1],data.floorId||'',data.needKey||false,this.next]);
|
||||
break;
|
||||
case "useItem": // 使用道具
|
||||
this.next = MotaActionBlocks['useItem_s'].xmlText([
|
||||
@ -2287,8 +2307,14 @@ ActionParser.prototype.parseAction = function() {
|
||||
data.loc[0],data.loc[1],this.next]);
|
||||
break;
|
||||
case "insert": // 强制插入另一个点的事件在当前事件列表执行,当前坐标和楼层不会改变
|
||||
this.next = MotaActionBlocks['insert_s'].xmlText([
|
||||
if (this.isset(data.name)) {
|
||||
this.next = MotaActionBlocks['insert_1_s'].xmlText([
|
||||
data.name, this.next]);
|
||||
}
|
||||
else {
|
||||
this.next = MotaActionBlocks['insert_2_s'].xmlText([
|
||||
data.loc[0],data.loc[1],data.floorId||'',this.next]);
|
||||
}
|
||||
break;
|
||||
case "playSound":
|
||||
this.next = MotaActionBlocks['playSound_s'].xmlText([
|
||||
@ -2314,6 +2340,10 @@ ActionParser.prototype.parseAction = function() {
|
||||
this.next = MotaActionBlocks['freeBgm_s'].xmlText([
|
||||
data.name,this.next]);
|
||||
break
|
||||
case "stopSound":
|
||||
this.next = MotaActionBlocks['stopSound_s'].xmlText([
|
||||
this.next]);
|
||||
break
|
||||
case "setVolume":
|
||||
this.next = MotaActionBlocks['setVolume_s'].xmlText([
|
||||
data.value, data.time||0, data.async||false, this.next]);
|
||||
|
||||
@ -62,6 +62,7 @@ editor.prototype.init = function (callback) {
|
||||
editor.mode.floor();
|
||||
editor.mode.tower();
|
||||
editor.mode.functions();
|
||||
editor.mode.commonevent();
|
||||
editor.mode.showMode('tower');
|
||||
|
||||
editor_multi = editor_multi();
|
||||
|
||||
@ -23,17 +23,6 @@ editor_blockly = function () {
|
||||
{"type": "hide", "time": 500},
|
||||
],'event'),
|
||||
MotaActionBlocks['changeFloor_m'].xmlText(),
|
||||
//MotaActionFunctions.actionParser.parse({"type": "choices", "choices": [
|
||||
// {"text": "攻击+\${point}", "action": [
|
||||
// {"type": "setValue", "name": "status:atk", "value": "status:atk+\${point}"},
|
||||
// ]},
|
||||
// {"text": "防御+\${2*point}", "action": [
|
||||
// {"type": "setValue", "name": "status:def", "value": "status:def+\${2*point}"},
|
||||
// ]},
|
||||
// {"text": "生命+\${200*point}", "action": [
|
||||
// {"type": "setValue", "name": "status:hp", "value": "status:hp+\${200*point}"},
|
||||
// ]},
|
||||
//]},'point'),
|
||||
MotaActionFunctions.actionParser.parse([{
|
||||
"id": "moneyShop1",
|
||||
"name": "贪婪之神",
|
||||
@ -55,6 +44,7 @@ editor_blockly = function () {
|
||||
MotaActionBlocks['firstArrive_m'].xmlText(),
|
||||
MotaActionBlocks['eachArrive_m'].xmlText(),
|
||||
MotaActionBlocks['level_m'].xmlText(),
|
||||
MotaActionBlocks['commonEvent_m'].xmlText(),
|
||||
],
|
||||
'显示文字':[
|
||||
MotaActionBlocks['text_0_s'].xmlText(),
|
||||
@ -103,6 +93,7 @@ editor_blockly = function () {
|
||||
MotaActionBlocks['useItem_s'].xmlText(),
|
||||
MotaActionBlocks['openShop_s'].xmlText(),
|
||||
MotaActionBlocks['setBlock_s'].xmlText(),
|
||||
MotaActionBlocks['setBgFgBlock_s'].xmlText(),
|
||||
MotaActionBlocks['setHeroIcon_s'].xmlText(),
|
||||
MotaActionBlocks['follow_s'].xmlText(),
|
||||
MotaActionBlocks['unfollow_s'].xmlText(),
|
||||
@ -125,9 +116,9 @@ editor_blockly = function () {
|
||||
MotaActionBlocks['hideFloorImg_s'].xmlText(),
|
||||
MotaActionBlocks['showBgFgMap_s'].xmlText(),
|
||||
MotaActionBlocks['hideBgFgMap_s'].xmlText(),
|
||||
MotaActionBlocks['setBgFgBlock_s'].xmlText(),
|
||||
MotaActionBlocks['trigger_s'].xmlText(),
|
||||
MotaActionBlocks['insert_s'].xmlText(),
|
||||
MotaActionBlocks['insert_1_s'].xmlText(),
|
||||
MotaActionBlocks['insert_2_s'].xmlText(),
|
||||
MotaActionBlocks['move_s'].xmlText(),
|
||||
MotaActionBlocks['jump_s'].xmlText(),
|
||||
MotaActionBlocks['disableShop_s'].xmlText(),
|
||||
@ -150,6 +141,7 @@ editor_blockly = function () {
|
||||
MotaActionBlocks['loadBgm_s'].xmlText(),
|
||||
MotaActionBlocks['freeBgm_s'].xmlText(),
|
||||
MotaActionBlocks['playSound_s'].xmlText(),
|
||||
MotaActionBlocks['stopSound_s'].xmlText(),
|
||||
MotaActionBlocks['setVolume_s'].xmlText(),
|
||||
MotaActionBlocks['callBook_s'].xmlText(),
|
||||
MotaActionBlocks['callSave_s'].xmlText(),
|
||||
@ -607,7 +599,8 @@ function omitedcheckUpdateFunction(event) {
|
||||
'exit_s',
|
||||
'revisit_s',
|
||||
'sleep_s',
|
||||
'setBlock_s'
|
||||
'setBlock_s',
|
||||
'insert_1_s'
|
||||
]; // 最常用的15个图块
|
||||
editor_blockly.lastUsedTypeNum=15;
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ editor_file = function (editor, callback) {
|
||||
'comment': 'comment',
|
||||
'data.comment': 'dataComment',
|
||||
'functions.comment': 'functionsComment',
|
||||
'events.comment': 'eventsComment',
|
||||
}
|
||||
for (var key in commentjs) {
|
||||
(function (key) {
|
||||
@ -49,25 +50,7 @@ editor_file = function (editor, callback) {
|
||||
throw('未设置callback')
|
||||
}
|
||||
;
|
||||
/* var fs = editor.fs;
|
||||
fs.readFile('project/floors/'+filename+'.js','utf-8',function(err, data){
|
||||
if (err!=null){callback(err);return;}
|
||||
data=data.split('=');
|
||||
data=[data[0],data.slice(1).join('=')];
|
||||
var varnameId = data[0].split('.').slice(-1)[0].trim();
|
||||
var filenameId = filename.split('/').slice(-1)[0].split('\\').slice(-1)[0];
|
||||
eval('b3917d1d_71c2_41f2_a8aa_481b215ffb99='+data[1]);
|
||||
var floorData = b3917d1d_71c2_41f2_a8aa_481b215ffb99;
|
||||
delete(b3917d1d_71c2_41f2_a8aa_481b215ffb99);
|
||||
var floorId = floorData.floorId;
|
||||
if (varnameId!=filenameId || filenameId!=floorId){
|
||||
callback('文件名,第一行的变量名以及floorId不一致');
|
||||
return;
|
||||
}
|
||||
editor.currentFloorId = floorId;
|
||||
editor.currentFloorData = floorData;
|
||||
callback(null)
|
||||
}); */
|
||||
|
||||
editor.currentFloorId = editor.core.status.floorId;
|
||||
editor.currentFloorData = editor.core.floors[editor.currentFloorId];
|
||||
}
|
||||
@ -833,6 +816,39 @@ editor_file = function (editor, callback) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
editor_file.editCommonEvent = function (actionList, callback) {
|
||||
/*actionList:[
|
||||
["change","['test']",['123']],
|
||||
]
|
||||
为[]时只查询不修改
|
||||
*/
|
||||
var data_obj = events_c12a15a8_c380_4b28_8144_256cba95f760.commonEvent;
|
||||
if (!isset(callback)) {
|
||||
printe('未设置callback');
|
||||
throw('未设置callback')
|
||||
}
|
||||
;
|
||||
if (isset(actionList) && actionList.length > 0) {
|
||||
actionList.forEach(function (value) {
|
||||
value[1] = "['commonEvent']" + value[1];
|
||||
});
|
||||
saveSetting('events', actionList, function (err) {
|
||||
callback([
|
||||
Object.assign({},data_obj),
|
||||
editor_file.eventsComment._data.commonEvent,
|
||||
err]);
|
||||
});
|
||||
} else {
|
||||
callback([
|
||||
Object.assign({},data_obj),
|
||||
editor_file.eventsComment._data.commonEvent,
|
||||
null]);
|
||||
}
|
||||
}
|
||||
//callback([obj,commentObj,err:String])
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
var isset = function (val) {
|
||||
if (val == undefined || val == null) {
|
||||
return false;
|
||||
@ -996,37 +1012,20 @@ editor_file = function (editor, callback) {
|
||||
editor_file.saveFloorFile(callback);
|
||||
return;
|
||||
}
|
||||
if (file == 'events') {
|
||||
actionList.forEach(function (value) {
|
||||
eval("events_c12a15a8_c380_4b28_8144_256cba95f760" + value[1] + '=' + JSON.stringify(value[2]));
|
||||
});
|
||||
var datastr = 'var events_c12a15a8_c380_4b28_8144_256cba95f760 = \n';
|
||||
datastr += JSON.stringify(events_c12a15a8_c380_4b28_8144_256cba95f760, null, '\t');
|
||||
fs.writeFile('project/events.js', encode(datastr), 'base64', function (err, data) {
|
||||
callback(err);
|
||||
});
|
||||
return;
|
||||
}
|
||||
callback('出错了,要设置的文件名不识别');
|
||||
}
|
||||
|
||||
/*
|
||||
$select({\"values\":[\"keys\",\"items\",\"constants\",\"tools\"]})$end
|
||||
$range(thiseval==~~thiseval &&thiseval>0)$end
|
||||
$leaf(true)$end
|
||||
$select({\"values\":[true]})$end
|
||||
$select({\"values\":[false]})$end
|
||||
$select({\"values\":[true,false]})$end
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
所有注释中的特殊指令
|
||||
$range(evalstr:thiseval)$end
|
||||
限制取值范围,要求修改后的eval(evalstr)为true
|
||||
$leaf(evalstr:thiseval)$end
|
||||
强制指定为叶节点,如果eval(evalstr)为true
|
||||
|
||||
//以下几个中选一个 [
|
||||
$select(evalstr)$end
|
||||
渲染成<select>,选项为数组eval(evalstr)['values']
|
||||
$input(evalstr)$end
|
||||
渲染成<input>
|
||||
$textarea(evalstr)$end
|
||||
渲染成<textarea>
|
||||
默认选项为$textarea()$end
|
||||
// ]
|
||||
|
||||
*/
|
||||
return editor_file;
|
||||
}
|
||||
//editor_file = editor_file(editor);
|
||||
@ -11,6 +11,8 @@ editor_mode = function (editor) {
|
||||
|
||||
'map': 'left',
|
||||
'appendpic': 'left1',
|
||||
|
||||
'commonevent': 'left9',
|
||||
}
|
||||
this._ids = {}
|
||||
this.dom = {}
|
||||
@ -223,21 +225,29 @@ editor_mode = function (editor) {
|
||||
editor_mode.addAction(['delete', field, undefined]);
|
||||
editor_mode.onmode('save');//自动保存 删掉此行的话点保存按钮才会保存
|
||||
} else {
|
||||
printe(field + ' : 该值不允许为null,无法删除');
|
||||
printe(field + ' : 该值不允许为null,无法删除');
|
||||
}
|
||||
}
|
||||
var addfunc=function(){
|
||||
editor_mode.onmode(editor_mode._ids[modeNode.getAttribute('id')]);
|
||||
|
||||
var mode = document.getElementById('editModeSelect').value;
|
||||
|
||||
// 1.输入id
|
||||
var newid=prompt('请输入新项的id');
|
||||
var newid=prompt('请输入新项的ID(仅公共事件支持中文ID)');
|
||||
if (newid == null || newid.length==0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查commentEvents
|
||||
if (mode !== 'commonevent') {
|
||||
// 2.检查id是否符合规范或与已有id重复
|
||||
if (!/^[a-zA-Z0-9_]+$/.test(newid)){
|
||||
printe('id不符合规范, 请使用大小写字母数字下划线来构成');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var conflict=true;
|
||||
var basefield=field.replace(/\[[^\[]*\]$/,'');
|
||||
if (basefield==="['main']"){
|
||||
@ -341,75 +351,40 @@ editor_mode = function (editor) {
|
||||
editor_mode.prototype.doActionList = function (mode, actionList) {
|
||||
if (actionList.length == 0) return;
|
||||
printf('修改中...');
|
||||
switch (mode) {
|
||||
case 'loc':
|
||||
|
||||
editor.file.editLoc(editor_mode.pos.x, editor_mode.pos.y, actionList, function (objs_) {//console.log(objs_);
|
||||
var cb=function(objs_){
|
||||
if (objs_.slice(-1)[0] != null) {
|
||||
printe(objs_.slice(-1)[0]);
|
||||
throw(objs_.slice(-1)[0])
|
||||
}
|
||||
;printf('修改成功');
|
||||
}
|
||||
switch (mode) {
|
||||
case 'loc':
|
||||
editor.file.editLoc(editor_mode.pos.x, editor_mode.pos.y, actionList, function (objs_) {
|
||||
cb(objs_);
|
||||
editor.drawPosSelection();
|
||||
});
|
||||
break;
|
||||
case 'enemyitem':
|
||||
|
||||
if (editor_mode.info.images == 'enemys' || editor_mode.info.images == 'enemy48') {
|
||||
editor.file.editEnemy(editor_mode.info.id, actionList, function (objs_) {//console.log(objs_);
|
||||
if (objs_.slice(-1)[0] != null) {
|
||||
printe(objs_.slice(-1)[0]);
|
||||
throw(objs_.slice(-1)[0])
|
||||
}
|
||||
;printf('修改成功')
|
||||
});
|
||||
editor.file.editEnemy(editor_mode.info.id, actionList, cb);
|
||||
} else if (editor_mode.info.images == 'items') {
|
||||
editor.file.editItem(editor_mode.info.id, actionList, function (objs_) {//console.log(objs_);
|
||||
if (objs_.slice(-1)[0] != null) {
|
||||
printe(objs_.slice(-1)[0]);
|
||||
throw(objs_.slice(-1)[0])
|
||||
}
|
||||
;printf('修改成功')
|
||||
});
|
||||
editor.file.editItem(editor_mode.info.id, actionList, cb);
|
||||
} else {
|
||||
editor.file.editMapBlocksInfo(editor_mode.info.idnum, actionList, function (objs_) {//console.log(objs_);
|
||||
if (objs_.slice(-1)[0] != null) {
|
||||
printe(objs_.slice(-1)[0]);
|
||||
throw(objs_.slice(-1)[0])
|
||||
}
|
||||
;printf('修改成功');
|
||||
});
|
||||
editor.file.editMapBlocksInfo(editor_mode.info.idnum, actionList, cb);
|
||||
}
|
||||
break;
|
||||
case 'floor':
|
||||
|
||||
editor.file.editFloor(actionList, function (objs_) {//console.log(objs_);
|
||||
if (objs_.slice(-1)[0] != null) {
|
||||
printe(objs_.slice(-1)[0]);
|
||||
throw(objs_.slice(-1)[0])
|
||||
}
|
||||
;printf('修改成功');
|
||||
});
|
||||
editor.file.editFloor(actionList, cb);
|
||||
break;
|
||||
case 'tower':
|
||||
|
||||
editor.file.editTower(actionList, function (objs_) {//console.log(objs_);
|
||||
if (objs_.slice(-1)[0] != null) {
|
||||
printe(objs_.slice(-1)[0]);
|
||||
throw(objs_.slice(-1)[0])
|
||||
}
|
||||
;printf('修改成功')
|
||||
});
|
||||
editor.file.editTower(actionList, cb);
|
||||
break;
|
||||
case 'functions':
|
||||
|
||||
editor.file.editFunctions(actionList, function (objs_) {//console.log(objs_);
|
||||
if (objs_.slice(-1)[0] != null) {
|
||||
printe(objs_.slice(-1)[0]);
|
||||
throw(objs_.slice(-1)[0])
|
||||
}
|
||||
;printf('修改成功')
|
||||
});
|
||||
editor.file.editFunctions(actionList, cb);
|
||||
break;
|
||||
case 'commonevent':
|
||||
editor.file.editCommonEvent(actionList, cb);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -540,6 +515,19 @@ editor_mode = function (editor) {
|
||||
if (Boolean(callback)) callback();
|
||||
}
|
||||
|
||||
editor_mode.prototype.commonevent = function (callback) {
|
||||
var objs = [];
|
||||
editor.file.editCommonEvent([], function (objs_) {
|
||||
objs = objs_;
|
||||
//console.log(objs_)
|
||||
});
|
||||
//只查询不修改时,内部实现不是异步的,所以可以这么写
|
||||
var tableinfo = editor_mode.objToTable_(objs[0], objs[1]);
|
||||
document.getElementById('table_b7bf0124_99fd_4af8_ae2f_0017f04a7c7d').innerHTML = tableinfo.HTML;
|
||||
tableinfo.listen(tableinfo.guids);
|
||||
if (Boolean(callback)) callback();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
editor_mode.prototype.listen = function (callback) {
|
||||
@ -1208,11 +1196,11 @@ editor_mode = function (editor) {
|
||||
editor_mode.changeDoubleClickModeByButton=function(mode){
|
||||
({
|
||||
delete:function(){
|
||||
printf('下一次双击表格的项删除, 编辑后刷新浏览器生效 (正常模式下双击是用事件或文本编辑器编辑);切换下拉菜单可取消。');
|
||||
printf('下一次双击表格的项删除,切换下拉菜单可取消;编辑后需刷新浏览器生效。');
|
||||
editor_mode.doubleClickMode=mode;
|
||||
},
|
||||
add:function(){
|
||||
printf('下一次双击表格的项, 在同级添加新项, 编辑后刷新浏览器生效 (正常模式下双击是用事件或文本编辑器编辑);切换下拉菜单可取消。');
|
||||
printf('下一次双击表格的项则在同级添加新项,切换下拉菜单可取消;编辑后需刷新浏览器生效。');
|
||||
editor_mode.doubleClickMode=mode;
|
||||
}
|
||||
}[mode])();
|
||||
|
||||
36
_server/events.comment.js
Normal file
36
_server/events.comment.js
Normal file
@ -0,0 +1,36 @@
|
||||
var events_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
{
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"commonEvent": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": function (key) {
|
||||
var obj = {
|
||||
"加点事件": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_range": "thiseval instanceof Array",
|
||||
"_event": "commonEvent",
|
||||
"_data": "打败怪物后进行加点"
|
||||
},
|
||||
"毒衰咒处理": {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_range": "thiseval instanceof Array",
|
||||
"_event": "commonEvent",
|
||||
"_data": "对毒衰咒效果进行的处理"
|
||||
},
|
||||
}
|
||||
if (obj[key]) return obj[key];
|
||||
return {
|
||||
"_leaf": true,
|
||||
"_type": "event",
|
||||
"_event": "commonEvent",
|
||||
"_data": "自定义公共事件,可以双击进入事件编辑器"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
var maps_comment_90f36752_8815_4be8_b32b_d7fad1d0542e =
|
||||
var maps_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
{
|
||||
////////////////////////// 地形部分 //////////////////////////
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# V2.0版本介绍
|
||||
|
||||
?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.4**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
目前样板已经更新到V2.0版本以上,本章将对V2.0的一些内容进行介绍。
|
||||
|
||||
|
||||
13
docs/api.md
13
docs/api.md
@ -1,6 +1,6 @@
|
||||
# 附录: API列表
|
||||
|
||||
?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.4**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
**这里只列出所有可能会被造塔者用到的常用API,更多的有关内容请在代码内进行查询。**
|
||||
|
||||
@ -124,6 +124,9 @@ core.insertAction(list, x, y, callback)
|
||||
x和y如果设置则覆盖"当前事件点"的坐标,callback如果设置则覆盖事件执行完毕后的回调函数。
|
||||
例如: core.insertAction(["楼层切换", {"type":"changeFloor", "floorId": "MT3"}])
|
||||
将依次显示剧情文本,并执行一个楼层切换的自定义事件。
|
||||
--------
|
||||
从V2.5.4开始提出了“公共事件”的说法,这里也可以插入一个公共事件名。
|
||||
例如:core.insertAction("毒衰咒处理") 将插入公共事件“毒衰咒处理”。
|
||||
|
||||
|
||||
core.changeFloor(floorId, stair, heroLoc, time, callback) [异步]
|
||||
@ -430,6 +433,10 @@ core.events.doAction()
|
||||
执行下一个事件。此函数中将对所有自定义事件类型分别处理。
|
||||
|
||||
|
||||
core.events.getCommonEvent(name)
|
||||
根据名称获得一个公共事件;如果不存在对应的公共事件则返回null。
|
||||
|
||||
|
||||
core.events.openShop(shopId, needVisited) [异步]
|
||||
打开一个全局商店。needVisited表示是否需要该商店已被打开过。
|
||||
|
||||
@ -610,6 +617,10 @@ core.utils.cropImage(image, size)
|
||||
纵向对图片进行切分(裁剪)。
|
||||
|
||||
|
||||
core.utils.push(a,b)
|
||||
向某个数组后插入另一个数组或元素
|
||||
|
||||
|
||||
core.utils.unshift(a, b)
|
||||
向某个数组前插入另一个数组或元素
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 元件说明
|
||||
|
||||
?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.4**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 事件
|
||||
|
||||
?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.4**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
本章内将对样板所支持的事件进行介绍。
|
||||
|
||||
@ -573,23 +573,31 @@ NPC对话事件结束后如果需要NPC消失也需要调用 `{"type": "hide"}`
|
||||
|
||||
例如上面这个例子,下面的文字将不会再被显示,而是直接跳转到`"3,6"`对应的事件列表从头执行。
|
||||
|
||||
### insert:插入另一个地点的事件
|
||||
!> 从V2.5.4开始,允许执行另一个点的“系统事件”,如打怪、开门、拾取道具等等。对应点的战后事件等也会被执行。
|
||||
|
||||
`{"type":"insert"}` 会插入另一个地点的事件执行。
|
||||
### insert:插入公共事件或另一个地点的事件并执行
|
||||
|
||||
`{"type":"insert"}` 会插入公共事件或另一个地点的事件并执行。
|
||||
|
||||
其基本写法如下:
|
||||
|
||||
``` js
|
||||
"x,y": [ // 实际执行的事件列表
|
||||
{"type": "insert", "name": "加点事件"}, // 插入公共事件:加点事件
|
||||
{"type": "insert", "name": "毒衰咒处理"}, // 插入公共事件:毒衰咒处理
|
||||
{"type": "insert", "loc": [3,6]}, // 插入[3,6]点的事件并执行
|
||||
{"type": "insert", "loc": [10,10], "floorId": "MT1"}, // 插入MT1层[10,10]点的事件并执行
|
||||
"上面的插入事件执行完毕后会接着继续执行后面的事件"
|
||||
]
|
||||
```
|
||||
|
||||
loc是必须的,代表另一个地点的坐标。
|
||||
`insert`的写法有两种,可以写`name`,或者`loc`。
|
||||
|
||||
floorId可选,代表另一个地点所在的楼层;如果不写则默认为当前层。
|
||||
- 如果写了`"name": "xxx"`,则会去公共事件列表中找寻对应的事件,并执行。
|
||||
- name为公共事件的名称,如果对应公共事件不存在则跳过。
|
||||
- 否则,如果写了`"loc": [x,y]`,则会插入另一个地点的事件
|
||||
- loc为另一个地点的坐标
|
||||
- floorId可选,代表另一个地点所在的楼层;如果不写则默认为当前层。
|
||||
|
||||
和`type:trigger`不同的是,**`type:trigger`是立刻将当前事件结束(剩下所有内容都忽略),然后重新启动另一个地点的action事件。**
|
||||
|
||||
@ -597,8 +605,6 @@ floorId可选,代表另一个地点所在的楼层;如果不写则默认为
|
||||
|
||||
**这个过程中,当前事件不会被结束,当前的楼层和事件坐标不会发生改变。** 插入的事件执行完毕后,会继续执行接下来的内容。
|
||||
|
||||
我们某个事件写在某个角落的墙上然后远程调用,从而达到“公共事件”的效果。
|
||||
|
||||
### revisit:立即重启当前事件
|
||||
|
||||
revisit和trigger完全相同,只不过是立刻触发的还是本地点的事件
|
||||
@ -836,6 +842,7 @@ name是可选的,代表目标行走图的文件名。
|
||||
"x,y": [ // 实际执行的事件列表
|
||||
{"type": "openDoor", "loc": [3,6], "floorId": "MT1"}, // 打开MT1层的[3,6]位置的门
|
||||
{"type": "openDoor", "loc": [3,6]}, // 如果是本层则可省略floorId
|
||||
{"type": "openDoor", "loc": [3,6], "needKey": true} // 打开此门需要钥匙
|
||||
]
|
||||
```
|
||||
|
||||
@ -845,6 +852,10 @@ loc指定门的坐标,floorId指定门所在的楼层ID。如果是当前层
|
||||
|
||||
如果loc所在的点既不是门也不是墙壁,则忽略本事件。
|
||||
|
||||
needKey是可选的,如果设置为true则需要钥匙才能打开此门。如果没有钥匙则跳过此事件。
|
||||
|
||||
!> needKey仅对当前楼层开门有效!跨楼层的门仍然不需要钥匙即可打开,如有需求请自行判定。
|
||||
|
||||
### changeFloor:楼层切换
|
||||
|
||||
在事件中也可以对楼层进行切换。一个比较典型的例子就是TSW中,勇士在三楼的陷阱被扔到了二楼,就是一个楼层切换事件。
|
||||
@ -1302,13 +1313,19 @@ async可选,如果为true则会异步执行(即不等待当前事件执行
|
||||
|
||||
值得注意的是,如果是额外添加进文件的音效,则需在main.js中this.sounds里加载它。
|
||||
|
||||
### stopSound:停止所有音效
|
||||
|
||||
使用`{"type": "stopSound"}`可以停止所有音效。
|
||||
|
||||
这在人物对话音效时很有用。
|
||||
|
||||
### setVolume:设置音量
|
||||
|
||||
使用setVolume可以设置音量大小。
|
||||
|
||||
使用方法: `{"type": "setVolume", "value": 90, "time": 500, "async": true}`
|
||||
|
||||
value为音量大小,在0到100之间,默认为100。设置后,BGM和SE都将使用该音量进行播放。
|
||||
value为音量大小,在0到100之间,默认为100。设置后,BGM将使用该音量进行播放。SE的音量大小不会发生改变。
|
||||
|
||||
可以设置time为音量渐变时间。
|
||||
|
||||
|
||||
BIN
docs/img/commonEvent.png
Normal file
BIN
docs/img/commonEvent.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 36 KiB |
@ -1,6 +1,6 @@
|
||||
# HTML5 魔塔样板说明文档
|
||||
|
||||
?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.4**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 个性化
|
||||
|
||||
?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.4**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。
|
||||
|
||||
@ -21,7 +21,7 @@ HTML5魔塔是使用画布(canvas)来绘制,存在若干个图层,它们
|
||||
- route**[D]**:路线层;主要用来绘制勇士的行走路线图。 (z-index: 95)
|
||||
- paint**[D]**:绘图层;主要用来进行绘图模式。(z-index: 95)
|
||||
- curtain:色调层;用来控制当前楼层的画面色调 (z-index: 125)
|
||||
- image\***[D]**:图片层;用来绘制图片等操作。(z-index: 100+code, 101~150;也就是图片编号在1~25的在色调层之下,26~50的在色调层之上)
|
||||
- image1\~50**[D]**:图片层;用来绘制图片等操作。(z-index: 100+code, 101~150;也就是图片编号在1~25的在色调层之下,26~50的在色调层之上)
|
||||
- ui:UI层;用来绘制一切UI窗口,如剧情文本、怪物手册、楼传器、系统菜单等等 (z-index: 160)
|
||||
- data:数据层;用来绘制一些顶层的或更新比较快的数据,如左上角的提示,战斗界面中数据的变化等等。 (z-index: 170)
|
||||
|
||||
@ -84,13 +84,13 @@ core.fillText('test', '这是一段文字', 10, 30, '#FF0000', '16px Verdana');
|
||||
|
||||
由于HTML5功能(素材)有限,导致了对很多比较复杂的素材(比如房子内)等无法有着较好的绘图方式。
|
||||
|
||||
为了解决这个问题,我们允许用户自己放置一张或多张图片作为某一层的背景素材。
|
||||
为了解决这个问题,我们允许用户自己放置一张或多张图片作为某一层的背景/前景素材。
|
||||
|
||||
要启用这个功能,我们首先需要在`data.js`中将可能的图片进行加载。
|
||||
|
||||
``` js
|
||||
"images": [ // 在此存放所有可能使用的图片
|
||||
// 图片可以被作为背景图(的一部分),也可以直接用自定义事件进行显示。
|
||||
// 图片可以被作为背景/前景图,也可以直接用自定义事件进行显示。
|
||||
// 图片名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
|
||||
// 建议对于较大的图片,在网上使用在线的“图片压缩工具(http://compresspng.com/zh/)”来进行压缩,以节省流量
|
||||
"bg.jpg", "house.png", "bed.png"// 依次向后添加
|
||||
@ -99,18 +99,21 @@ core.fillText('test', '这是一段文字', 10, 30, '#FF0000', '16px Verdana');
|
||||
|
||||
!> 请使用网上的一些[在线图片压缩工具](http://compresspng.com/zh/)对图片进行压缩,以节省流量。
|
||||
|
||||
之后,我们可以在每层剧本的`"images"`里来定义该层的默认背景图片素材。
|
||||
之后,我们可以在每层剧本的`"images"`里来定义该层的默认背景/前景层的图片素材。
|
||||
|
||||
从V2.5.4开始,贴图也允许进行帧动画,只要设置第五项的数值。
|
||||
|
||||
``` js
|
||||
"images": [[3,5,"bg.jpg",0]], // 背景图;你可以选择一张或多张图片来作为背景/前景素材。
|
||||
"images": [[96,120,"bg.jpg",0]], // 背景图;你可以选择一张或多张图片来作为背景/前景素材。
|
||||
"images": [], // 无任何背景图
|
||||
"images": [[1,1,"house.png",0], [6,7,"bed.png",1]] // 在(1,1)放一个house.png在背景层,且(6,7)放bed.png在前景层
|
||||
"images": [[3,5,"tree.png",2]] // 如果写2,则会自动调节遮挡效果
|
||||
"images": [[32,32,"house.png",0], [160,170,"bed.png",1]] // 在(32,32)放一个house.png在背景层,且(160,170)放bed.png在前景层
|
||||
"images": [[96,120,"tree.png",2]] // 如果写2,则会自动调节遮挡效果
|
||||
"images": [[64,0,"x.png",1,4]] // 这是一个前景层的4帧动画贴图
|
||||
```
|
||||
|
||||
images为一个数组,代表当前层所有作为背景素材的图片信息。
|
||||
images为一个数组,代表当前层所有作为背景素材的图片信息。每一项为一个五元组,分别为该背景素材的x,y,图片名,遮挡方式和帧数。
|
||||
|
||||
每一项为一个四元组,分别为该背景素材的x,y,图片名和遮挡方式。其中x和y分别为横纵坐标,在0-12之间;图片名则必须在上面的images中定义过。
|
||||
其中x和y分别为左上角的像素坐标;图片名则必须在全塔属性的images中定义过。
|
||||
|
||||
第四项为遮挡方式,定义如下:
|
||||
|
||||
@ -118,17 +121,33 @@ images为一个数组,代表当前层所有作为背景素材的图片信息
|
||||
- 1:该图片将全部画在前景层,可以遮挡勇士。举例:云彩等效果。
|
||||
- 2:该图片将上部分画在前景层,下部分画在背景层。从而可以达到一个“自动调节遮挡的效果”。举例:树、房子等等。
|
||||
|
||||
!> 如果写2的话,请确保图片高度是32的倍数!
|
||||
!> 如果写2的话,最好让x,y和图片高度都是32的倍数!
|
||||
|
||||
第五项为图片的帧数,可选。如果进行了设置,则会将该贴图视为帧动画,并切分成对应的帧数。
|
||||
|
||||
例如,假设图片是100x100的,且帧数设为4,则视为四帧帧动画,每次绘制的图片大小实际上是25x100。
|
||||
|
||||
关于楼层贴图和前景、背景层的层叠覆盖关系,默认是:**地板 - 背景贴图 - 背景图块 - 事件 - 勇士 - 前景贴图 - 前景图块**。
|
||||
|
||||
可以通过修改`libs/maps.js`的`drawMap`函数中下面三行的顺序来改变其覆盖关系。
|
||||
|
||||
``` js
|
||||
// ----- 可以调整这三行的顺序来修改覆盖关系;同层画布上,后绘制的覆盖先绘制的
|
||||
// ----- ui.js的drawThumbnail函数也需要对应进行修改。
|
||||
|
||||
// 绘制楼层贴图
|
||||
core.maps.drawFloorImages(floorId, images);
|
||||
// 绘制背景层图块
|
||||
core.maps.drawBgFgMap(floorId, core.canvas.bg, "bg", true);
|
||||
// 绘制前景层图块
|
||||
core.maps.drawBgFgMap(floorId, core.canvas.fg, "fg", true);
|
||||
```
|
||||
|
||||
楼层贴图可以被事件隐藏和显示,详见[隐藏贴图](event#hideFloorImg:隐藏贴图)的写法。
|
||||
|
||||
**如果你需要让某些点不可通行(比如你建了个房子,墙壁和家具等位置不让通行),则需在`events`中指定`{"noPass": false}`,参见[自定义事件](event#自定义事件)的写法。**
|
||||
**如果要让贴图的某些点不可通行,则可以使用noPass或者空气墙。**
|
||||
|
||||
``` js
|
||||
"events": {
|
||||
"x,y": {"noPass": true} // (x,y)点不可通行
|
||||
}
|
||||
```
|
||||
!> 小技巧:可以使用帧动画贴图来贴一些大型怪物,比如魔龙、章鱼,或者《永不复还》中的恐怖利刃等等。如果使用帧贴图来贴怪物,则可以使用一个“透明的怪物”放置在对应位置并写上具体属性数值(这样就可以进行战斗和显伤了);然后可以使用[displayIdInBook](element#怪物的朝向问题)在怪物手册中将该透明怪物映射到另一个有素材的怪物ID上。战斗完毕后使用[隐藏贴图](event#hideFloorImg:隐藏贴图)事件将贴图隐藏即可。
|
||||
|
||||
### 使用便捷PS工具生成素材
|
||||
|
||||
@ -543,18 +562,17 @@ case 89: // 使用该按键的keyCode,比如Y键就是89
|
||||
|
||||
## 公共事件
|
||||
|
||||
从2.5.1开始,H5提供了`{"type":"insert"}`事件,完美支持了公共事件的写法。
|
||||
从V2.5.4开始,样板提供了“公共事件”下拉框,我们可以在里面用事件编辑器进行编辑,并通过`{"type":"insert"}`进行调用。
|
||||
|
||||
我们只需要将需要的公共事件放在某个角落的墙上(或者甚至单独弄一层专门摆放公共事件),并使用“插入事件”,即可进行调用。
|
||||

|
||||
|
||||
具体详见[插入另一个地点的事件](event#insert:插入另一个地点的事件)。
|
||||
具体详见[插入公共事件或另一个地点的事件并执行](event#insert:插入公共事件或另一个地点的事件并执行)。
|
||||
|
||||
当然,继续使用**插件**的写法也是可以的。具体参见“脚本编辑 - 插件编写”。
|
||||
当然,继续使用**插件**的写法也是可以的。
|
||||
|
||||
<!--
|
||||
在RM中,存在公共事件的说法;也就是通过某个指令来调用一系列事件的触发。
|
||||
## 插件系统
|
||||
|
||||
在H5中,我们可以使用“插件”的形式来达成这个效果。具体参见“脚本编辑 - 插件编写”。
|
||||
在H5中,提供了“插件”系统。具体参见“脚本编辑 - 插件编写”。
|
||||
|
||||

|
||||
|
||||
@ -562,7 +580,7 @@ case 89: // 使用该按键的keyCode,比如Y键就是89
|
||||
|
||||
在这个插件编写的过程中,我们可以使用任何[常见API](api)里面的代码调用;也可以通过`core.insertAction`来插入自定义事件执行。
|
||||
|
||||
下面是一个很简单的例子,我编写一个公共事件(插件),其效果是让勇士生命值变成原来的x倍,并令面前的图块消失。
|
||||
下面是一个很简单的例子,我编写一个插件函数,其效果是让勇士生命值变成原来的x倍,并令面前的图块消失。
|
||||
|
||||
``` js
|
||||
this.myfunc = function(x) {
|
||||
@ -575,10 +593,9 @@ this.myfunc = function(x) {
|
||||
}
|
||||
```
|
||||
|
||||
然后比如我们在某个道具的使用效果 `useItemEffect` 中写 `core.plugin.myfunc(2)` 即可调用此公共事件(插件)。也可以在战后事件或自定义脚本等位置来写。
|
||||
然后比如我们在某个道具的使用效果 `useItemEffect` 中写 `core.plugin.myfunc(2)` 即可调用此插件函数。也可以在战后事件或自定义脚本等位置来写。
|
||||
|
||||
通过这种,将脚本和自定义事件混用的方式,可以达到和RM中公共事件类似的效果,即一个调用触发一系列事件。
|
||||
-->
|
||||
网站上也提供了一个[插件库](https://h5mota.com/plugins/),欢迎大家把自己写的插件进行共享。
|
||||
|
||||
## 标题界面事件化
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# 快速上手
|
||||
|
||||
?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} *
|
||||
?> 目前版本**v2.5.4**,上次更新时间:* {docsify-updated} *
|
||||
|
||||
在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔!
|
||||
|
||||
|
||||
@ -185,7 +185,6 @@
|
||||
<select id="entryType" disabled="disabled" style="display: none">
|
||||
<option value="event">event</option>
|
||||
<option value="changeFloor">changeFloor</option>
|
||||
<option value="point">point</option>
|
||||
<option value="level">level</option>
|
||||
<option value="shop">shop</option>
|
||||
<option value="afterBattle">afterBattle</option>
|
||||
@ -193,6 +192,7 @@
|
||||
<option value="afterOpenDoor">afterOpenDoor</option>
|
||||
<option value="firstArrive">firstArrive</option>
|
||||
<option value="eachArrive">eachArrive</option>
|
||||
<option value="commonEvent">commonEvent</option>
|
||||
</select>
|
||||
<button onclick="editor_blockly.confirm()">确认</button>
|
||||
<button onclick="editor_blockly.parse()">解析</button>
|
||||
@ -242,6 +242,23 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="left9" class='leftTab' style="z-index:-1;opacity: 0;"><!-- commonevent -->
|
||||
<h3 class="leftTabHeader">公共事件 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<div class='etable'>
|
||||
<table>
|
||||
<tbody id='table_b7bf0124_99fd_4af8_ae2f_0017f04a7c7d'>
|
||||
<tr>
|
||||
<td>条目</td>
|
||||
<td>注释</td>
|
||||
<td>值</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="mid">
|
||||
<div class="col" id='mapColMark'></div>
|
||||
<div class="row" id='mapRowMark'></div>
|
||||
@ -309,6 +326,7 @@
|
||||
<option value="tower">全塔属性</option>
|
||||
<option value="functions">脚本编辑</option>
|
||||
<option value="appendpic">追加素材</option>
|
||||
<option value="commonevent">公共事件</option>
|
||||
</select>
|
||||
<select id="brushMod" style="clear:right">
|
||||
<option value="line">画线</option>
|
||||
|
||||
20
editor.html
20
editor.html
@ -181,7 +181,6 @@
|
||||
<select id="entryType" disabled="disabled" style="display: none">
|
||||
<option value="event">event</option>
|
||||
<option value="changeFloor">changeFloor</option>
|
||||
<option value="point">point</option>
|
||||
<option value="level">level</option>
|
||||
<option value="shop">shop</option>
|
||||
<option value="afterBattle">afterBattle</option>
|
||||
@ -189,6 +188,7 @@
|
||||
<option value="afterOpenDoor">afterOpenDoor</option>
|
||||
<option value="firstArrive">firstArrive</option>
|
||||
<option value="eachArrive">eachArrive</option>
|
||||
<option value="commonEvent">commonEvent</option>
|
||||
</select>
|
||||
<button onclick="editor_blockly.confirm()">确认</button>
|
||||
<button onclick="editor_blockly.parse()">解析</button>
|
||||
@ -238,6 +238,23 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="left9" class='leftTab' style="z-index:-1;opacity: 0;"><!-- commonevent -->
|
||||
<h3 class="leftTabHeader">公共事件 <button onclick="editor.mode.onmode('save')">保存</button> <button onclick="editor.mode.changeDoubleClickModeByButton('add')">添加</button> <button onclick="editor.mode.changeDoubleClickModeByButton('delete')">删除</button>
|
||||
</h3>
|
||||
<div class="leftTabContent">
|
||||
<div class='etable'>
|
||||
<table>
|
||||
<tbody id='table_b7bf0124_99fd_4af8_ae2f_0017f04a7c7d'>
|
||||
<tr>
|
||||
<td>条目</td>
|
||||
<td>注释</td>
|
||||
<td>值</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="mid">
|
||||
<table class="col" id='mapColMark'></table>
|
||||
<table class="row" id='mapRowMark'></table>
|
||||
@ -277,6 +294,7 @@
|
||||
<option value="tower">全塔属性</option>
|
||||
<option value="functions">脚本编辑</option>
|
||||
<option value="appendpic">追加素材</option>
|
||||
<option value="commonevent">公共事件</option>
|
||||
</select>
|
||||
<br/>
|
||||
<span style="font-size: 12px;">
|
||||
|
||||
@ -70,8 +70,17 @@ control.prototype.setRequestAnimationFrame = function () {
|
||||
core.drawBlock(block, core.status.globalAnimateStatus % (block.event.animate||1));
|
||||
});
|
||||
|
||||
// Global floor images
|
||||
core.maps.drawFloorImages(core.status.floorId, core.status.floorAnimateObjs||[], core.status.globalAnimateStatus);
|
||||
|
||||
// Global Autotile Animate
|
||||
core.status.autotileAnimateObjs.blocks.forEach(function (block) {
|
||||
// ------ 界面外的动画不绘制
|
||||
if (block.x * 32 < core.bigmap.offsetX - 64 || block.x * 32 > core.bigmap.offsetX + 416 + 32
|
||||
|| block.y * 32 < core.bigmap.offsetY - 64 || block.y * 32 > core.bigmap.offsetY + 416 + 32 + 16) {
|
||||
return;
|
||||
}
|
||||
|
||||
var cv = core.isset(block.name)?core.canvas[block.name]:core.canvas.event;
|
||||
cv.clearRect(block.x * 32, block.y * 32, 32, 32);
|
||||
if (core.isset(block.name)) {
|
||||
@ -1416,6 +1425,7 @@ control.prototype.screenFlash = function (color, time, times, callback) {
|
||||
control.prototype.updateDamage = function (floorId, canvas) {
|
||||
floorId = floorId || core.status.floorId;
|
||||
if (!core.isset(floorId)) return;
|
||||
if (core.status.gameOver) return;
|
||||
if (!core.isset(canvas)) {
|
||||
canvas = core.canvas.damage;
|
||||
core.clearMap('damage');
|
||||
@ -2666,6 +2676,10 @@ control.prototype.playSound = function (sound) {
|
||||
var source = core.musicStatus.audioContext.createBufferSource();
|
||||
source.buffer = core.material.sounds[sound];
|
||||
source.connect(core.musicStatus.gainNode);
|
||||
var id = parseInt(Math.random()*10000000);
|
||||
source.onended = function () {
|
||||
delete core.musicStatus.playingSounds[id];
|
||||
}
|
||||
try {
|
||||
source.start(0);
|
||||
}
|
||||
@ -2675,8 +2689,10 @@ control.prototype.playSound = function (sound) {
|
||||
}
|
||||
catch (ee) {
|
||||
main.log(ee);
|
||||
return;
|
||||
}
|
||||
}
|
||||
core.musicStatus.playingSounds[id] = source;
|
||||
}
|
||||
else {
|
||||
core.material.sounds[sound].volume = core.musicStatus.volume;
|
||||
@ -2689,6 +2705,23 @@ control.prototype.playSound = function (sound) {
|
||||
}
|
||||
}
|
||||
|
||||
control.prototype.stopSound = function () {
|
||||
for (var i in core.musicStatus.playingSounds) {
|
||||
var source = core.musicStatus.playingSounds[i];
|
||||
try {
|
||||
source.stop();
|
||||
}
|
||||
catch (e) {
|
||||
try {
|
||||
source.noteOff(0);
|
||||
}
|
||||
catch (e) {
|
||||
main.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
control.prototype.checkBgm = function() {
|
||||
core.playBgm(core.musicStatus.playingBgm || main.startBgm);
|
||||
}
|
||||
|
||||
17
libs/core.js
17
libs/core.js
@ -54,6 +54,7 @@ function core() {
|
||||
'soundStatus': true, // 是否播放SE
|
||||
'playingBgm': null, // 正在播放的BGM
|
||||
'gainNode': null,
|
||||
'playingSounds': {}, // 正在播放的SE
|
||||
'volume': 1.0, // 音量
|
||||
'cachedBgms': [], // 缓存BGM内容
|
||||
'cachedBgmCount': 4, // 缓存的bgm数量
|
||||
@ -196,6 +197,7 @@ function core() {
|
||||
|
||||
// 动画
|
||||
'globalAnimateObjs': [],
|
||||
'floorAnimateObjs': [],
|
||||
'boxAnimateObjs': [],
|
||||
'autotileAnimateObjs': {"blocks": [], "map": null, "bgmap": null, "fgmap": null},
|
||||
"globalAnimateStatus": 0,
|
||||
@ -1071,6 +1073,11 @@ core.prototype.unshift = function (a,b) {
|
||||
return core.utils.unshift(a,b);
|
||||
}
|
||||
|
||||
////// 向某个数组后插入另一个数组或元素 //////
|
||||
core.prototype.push = function (a,b) {
|
||||
return core.utils.push(a,b);
|
||||
}
|
||||
|
||||
////// 设置本地存储 //////
|
||||
core.prototype.setLocalStorage = function(key, value) {
|
||||
return core.utils.setLocalStorage(key, value);
|
||||
@ -1388,6 +1395,11 @@ core.prototype.insertAction = function (list, x, y, callback) {
|
||||
core.events.insertAction(list, x, y, callback);
|
||||
}
|
||||
|
||||
////// 获得一个公共事件内容 //////
|
||||
core.prototype.getCommonEvent = function (name) {
|
||||
return core.events.getCommonEvent(name);
|
||||
}
|
||||
|
||||
////// 锁定状态栏,常常用于事件处理 //////
|
||||
core.prototype.lockControl = function () {
|
||||
core.control.lockControl();
|
||||
@ -1491,6 +1503,11 @@ core.prototype.playSound = function (sound) {
|
||||
core.control.playSound(sound);
|
||||
}
|
||||
|
||||
////// 停止所有音效 //////
|
||||
core.prototype.stopSound = function () {
|
||||
core.control.stopSound();
|
||||
}
|
||||
|
||||
////// 动画显示某对象 //////
|
||||
core.prototype.show = function (obj, speed, callback) {
|
||||
core.utils.show(obj, speed, callback);
|
||||
|
||||
155
libs/events.js
155
libs/events.js
@ -7,39 +7,24 @@ function events() {
|
||||
////// 初始化 //////
|
||||
events.prototype.init = function () {
|
||||
this.eventdata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.events;
|
||||
this.commonEvent = events_c12a15a8_c380_4b28_8144_256cba95f760.commonEvent;
|
||||
this.events = {
|
||||
'battle': function (data, core, callback) {
|
||||
// 正在执行自定义事件:不允许战斗
|
||||
if (core.status.event.id == 'action') {
|
||||
if (core.isset(callback)) callback();
|
||||
return;
|
||||
}
|
||||
'battle': function (data, callback) {
|
||||
core.battle(data.event.id, data.x, data.y);
|
||||
if (core.isset(callback))
|
||||
callback();
|
||||
},
|
||||
'getItem': function (data, core, callback) {
|
||||
'getItem': function (data, callback) {
|
||||
core.getItem(data.event.id, 1, data.x, data.y);
|
||||
if (core.isset(callback))
|
||||
callback();
|
||||
},
|
||||
'openDoor': function (data, core, callback) {
|
||||
// 正在执行自定义事件:不允许开门
|
||||
if (core.status.event.id == 'action') {
|
||||
if (core.isset(callback)) callback();
|
||||
return;
|
||||
}
|
||||
'openDoor': function (data, callback) {
|
||||
core.openDoor(data.event.id, data.x, data.y, true, function () {
|
||||
if (core.isset(callback)) callback();
|
||||
core.replay();
|
||||
});
|
||||
},
|
||||
'changeFloor': function (data, core, callback) {
|
||||
// 正在执行自定义事件:不允许切换楼层
|
||||
if (core.status.event.id == 'action') {
|
||||
if (core.isset(callback)) callback();
|
||||
return;
|
||||
}
|
||||
'changeFloor': function (data, callback) {
|
||||
var heroLoc = {};
|
||||
if (core.isset(data.event.data.loc))
|
||||
heroLoc = {'x': data.event.data.loc[0], 'y': data.event.data.loc[1]};
|
||||
@ -49,30 +34,29 @@ events.prototype.init = function () {
|
||||
core.changeFloor(data.event.data.floorId, data.event.data.stair,
|
||||
heroLoc, data.event.data.time, function () {
|
||||
if (core.isset(callback)) callback();
|
||||
core.replay();
|
||||
});
|
||||
},
|
||||
'passNet': function (data, core, callback) {
|
||||
'passNet': function (data, callback) {
|
||||
core.events.passNet(data);
|
||||
if (core.isset(callback))
|
||||
callback();
|
||||
},
|
||||
"changeLight": function (data, core, callback) {
|
||||
"changeLight": function (data, callback) {
|
||||
core.events.changeLight(data.x, data.y);
|
||||
if (core.isset(callback))
|
||||
callback();
|
||||
},
|
||||
"ski": function (data, core, callback) {
|
||||
"ski": function (data, callback) {
|
||||
core.events.ski();
|
||||
if (core.isset(callback))
|
||||
callback();
|
||||
},
|
||||
"pushBox": function (data, core, callback) {
|
||||
"pushBox": function (data, callback) {
|
||||
core.events.pushBox(data);
|
||||
if (core.isset(callback))
|
||||
callback();
|
||||
},
|
||||
'action': function (data, core, callback) {
|
||||
'action': function (data, callback) {
|
||||
var ev = core.clone(data.event.data), ex = data.x, ey = data.y;
|
||||
// 检查是否需要改变朝向
|
||||
if (ex == core.nextX() && ey == core.nextY()) {
|
||||
@ -232,6 +216,11 @@ events.prototype.gameOver = function (ending, fromReplay, norank) {
|
||||
core.setWeather();
|
||||
core.ui.closePanel();
|
||||
|
||||
if (main.isCompetition && core.isset(ending)) {
|
||||
if (ending == "") ending = "恭喜通关";
|
||||
ending += "[比赛]";
|
||||
}
|
||||
|
||||
// 下载录像
|
||||
var confirmDownload = function () {
|
||||
|
||||
@ -852,7 +841,7 @@ events.prototype.doAction = function() {
|
||||
}
|
||||
var floorId=data.floorId || core.status.floorId;
|
||||
if (floorId==core.status.floorId)
|
||||
core.openDoor(null, x, y, false, function() {
|
||||
core.openDoor(null, x, y, data.needKey, function() {
|
||||
core.lockControl();
|
||||
core.events.doAction();
|
||||
})
|
||||
@ -898,27 +887,49 @@ events.prototype.doAction = function() {
|
||||
var block=core.getBlock(toX, toY);
|
||||
if (block!=null) {
|
||||
block = block.block;
|
||||
if (core.isset(block.event) && block.event.trigger=='action') {
|
||||
// 触发
|
||||
if (core.isset(block.event) && core.isset(block.event.trigger)) {
|
||||
core.status.event.data.x=block.x;
|
||||
core.status.event.data.y=block.y;
|
||||
core.status.event.data.list = [
|
||||
{"todo": [], "total": [], "condition": "false"}
|
||||
];
|
||||
if (block.event.trigger == 'action') {
|
||||
core.status.event.data.list = [
|
||||
{"todo": core.clone(block.event.data), "total": core.clone(block.event.data), "condition": "false"}
|
||||
];
|
||||
core.status.event.data.x=block.x;
|
||||
core.status.event.data.y=block.y;
|
||||
}
|
||||
else {
|
||||
core.material.events[block.event.trigger](block, function () {
|
||||
core.lockControl();
|
||||
core.doAction();
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.doAction();
|
||||
break;
|
||||
}
|
||||
case "insert":
|
||||
{
|
||||
if (core.isset(data.name)) {
|
||||
// ----- 公共事件
|
||||
var commonEvent = this.getCommonEvent(data.name);
|
||||
if (core.isset(commonEvent)) {
|
||||
core.insertAction(commonEvent);
|
||||
}
|
||||
}
|
||||
else {
|
||||
var toX=core.calValue(data.loc[0], prefix), toY=core.calValue(data.loc[1], prefix);
|
||||
var floorId = data.floorId || core.status.floorId;
|
||||
var event = core.floors[floorId].events[toX+","+toY];
|
||||
if (core.isset(event)) core.insertAction(event);
|
||||
if (core.isset(event)) {
|
||||
if (core.isset(event.data)) event = event.data;
|
||||
if (typeof event == 'string' || event instanceof Array || core.isset(event.type))
|
||||
core.insertAction(event);
|
||||
}
|
||||
}
|
||||
this.doAction();
|
||||
break;
|
||||
}
|
||||
case "playSound":
|
||||
if (!core.isReplaying())
|
||||
core.playSound(data.name);
|
||||
@ -947,6 +958,9 @@ events.prototype.doAction = function() {
|
||||
core.freeBgm(data.name);
|
||||
this.doAction();
|
||||
break;
|
||||
case "stopSound":
|
||||
core.stopSound();
|
||||
break;
|
||||
case "setVolume":
|
||||
data.value = core.clamp(parseInt(data.value)/100, 0, 1);
|
||||
core.setFlag("__volume__", data.value);
|
||||
@ -1200,7 +1214,7 @@ events.prototype.doAction = function() {
|
||||
core.timeout.sleepTimeout = setTimeout(function() {
|
||||
core.timeout.sleepTimeout = null;
|
||||
core.events.doAction();
|
||||
}, core.isReplaying()?20:data.time);
|
||||
}, core.isReplaying()?Math.min(data.time, 20):data.time);
|
||||
break;
|
||||
case "wait":
|
||||
if (core.isReplaying()) {
|
||||
@ -1309,6 +1323,13 @@ events.prototype.doAction = function() {
|
||||
events.prototype.insertAction = function (action, x, y, callback) {
|
||||
if (core.hasFlag("__statistics__")) return;
|
||||
|
||||
// ------ 判定commonEvent
|
||||
var commonEvent = this.getCommonEvent(action);
|
||||
if (core.isset(commonEvent) && commonEvent instanceof Array) {
|
||||
action = commonEvent;
|
||||
}
|
||||
if (!core.isset(action)) return;
|
||||
|
||||
if (core.status.event.id != 'action') {
|
||||
this.doEvents(action, x, y, callback);
|
||||
}
|
||||
@ -1335,6 +1356,12 @@ events.prototype.recoverEvents = function (data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
////// 获得一个公共事件 //////
|
||||
events.prototype.getCommonEvent = function (name) {
|
||||
if (!core.isset(name) || !(typeof name === 'string')) return null;
|
||||
return this.commonEvent[name] || null;
|
||||
}
|
||||
|
||||
////// 获得面前的物品(轻按) //////
|
||||
events.prototype.getNextItem = function() {
|
||||
if (!core.status.heroStop || !core.flags.enableGentleClick) return false;
|
||||
@ -1391,6 +1418,7 @@ events.prototype.openDoor = function (id, x, y, needKey, callback) {
|
||||
core.drawTip("你没有" + ((core.material.items[key]||{}).name||"钥匙"));
|
||||
else core.drawTip("无法开启此门");
|
||||
core.clearContinueAutomaticRoute();
|
||||
if (core.isset(callback)) callback();
|
||||
return;
|
||||
}
|
||||
core.autosave(true);
|
||||
@ -1441,6 +1469,7 @@ events.prototype.battle = function (id, x, y, force, callback) {
|
||||
if (!core.enemys.canBattle(id, x, y) && !force && !core.isset(core.status.event.id)) {
|
||||
core.drawTip("你打不过此怪物!");
|
||||
core.clearContinueAutomaticRoute();
|
||||
if (core.isset(callback)) callback();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1461,47 +1490,47 @@ events.prototype.battle = function (id, x, y, force, callback) {
|
||||
|
||||
////// 触发(x,y)点的事件 //////
|
||||
events.prototype.trigger = function (x, y) {
|
||||
|
||||
if (core.status.event.id == 'action') return;
|
||||
|
||||
core.status.isSkiing = false;
|
||||
var mapBlocks = core.status.thisMap.blocks;
|
||||
var noPass;
|
||||
for (var b = 0; b < mapBlocks.length; b++) {
|
||||
if (mapBlocks[b].x == x && mapBlocks[b].y == y && !mapBlocks[b].disable) { // 启用事件
|
||||
noPass = mapBlocks[b].event && mapBlocks[b].event.noPass;
|
||||
var block = core.getBlock(x, y);
|
||||
if (block != null) {
|
||||
block = block.block;
|
||||
if (core.isset(block.event) && core.isset(block.event.trigger)) {
|
||||
var noPass = block.event.noPass, trigger = block.event.trigger;
|
||||
if (noPass) {
|
||||
core.clearAutomaticRouteNode(x, y);
|
||||
}
|
||||
if (core.isset(mapBlocks[b].event) && core.isset(mapBlocks[b].event.trigger)) {
|
||||
var trigger = mapBlocks[b].event.trigger;
|
||||
|
||||
if (trigger == 'ski') core.status.isSkiing = true;
|
||||
|
||||
// 转换楼层能否穿透
|
||||
if (trigger=='changeFloor' && !noPass) {
|
||||
var canCross = core.flags.portalWithoutTrigger;
|
||||
if (core.isset(mapBlocks[b].event.data) && core.isset(mapBlocks[b].event.data.portalWithoutTrigger))
|
||||
canCross=mapBlocks[b].event.data.portalWithoutTrigger;
|
||||
if (core.isset(block.event.data) && core.isset(block.event.data.portalWithoutTrigger))
|
||||
canCross=block.event.data.portalWithoutTrigger;
|
||||
if (canCross) {
|
||||
if (core.isReplaying()) {
|
||||
if (core.status.replay.toReplay[0]=='no') {
|
||||
core.status.replay.toReplay.shift();
|
||||
core.status.route.push("no");
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (core.status.automaticRoute.autoHeroMove || core.status.automaticRoute.autoStep<core.status.automaticRoute.autoStepRoutes.length) {
|
||||
core.status.route.push("no");
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
core.status.automaticRoute.moveDirectly = false;
|
||||
core.material.events[trigger](mapBlocks[b], core, function (data) {
|
||||
|
||||
core.material.events[trigger](block, function () {
|
||||
if (trigger == 'openDoor' || trigger == 'changeFloor')
|
||||
core.replay();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
events.prototype.setFloorName = function (floorId) {
|
||||
floorId = floorId || core.status.floorId;
|
||||
@ -1779,7 +1808,7 @@ events.prototype.setVolume = function (value, time, callback) {
|
||||
if (core.isset(core.musicStatus.playingBgm)) {
|
||||
core.material.bgms[core.musicStatus.playingBgm].volume = value;
|
||||
}
|
||||
core.musicStatus.gainNode.gain.value = value;
|
||||
// core.musicStatus.gainNode.gain.value = value;
|
||||
}
|
||||
|
||||
if (!core.isset(time) || time<100) {
|
||||
@ -2037,24 +2066,16 @@ events.prototype.passNet = function (data) {
|
||||
// core.drawTip('经过血网,生命-'+core.values.lavaDamage);
|
||||
}
|
||||
if (data.event.id=='poisonNet') { // 毒网
|
||||
if (core.hasFlag('poison')) return;
|
||||
core.setFlag('poison', true);
|
||||
core.setFlag('debuff', 'poison');
|
||||
core.insertAction('毒衰咒处理');
|
||||
}
|
||||
if (data.event.id=='weakNet') { // 衰网
|
||||
if (core.hasFlag('weak')) return;
|
||||
core.setFlag('weak', true);
|
||||
if (core.values.weakValue>=1) { // >=1:直接扣数值
|
||||
core.status.hero.atk -= core.values.weakValue;
|
||||
core.status.hero.def -= core.values.weakValue;
|
||||
else if (data.event.id=='weakNet') { // 衰网
|
||||
core.setFlag('debuff', 'weak');
|
||||
core.insertAction('毒衰咒处理');
|
||||
}
|
||||
else { // <1:扣比例
|
||||
core.setFlag("equip_atk_buff", core.getFlag("equip_atk_buff", 1) - core.values.weakValue);
|
||||
core.setFlag("equip_def_buff", core.getFlag("equip_def_buff", 1) - core.values.weakValue);
|
||||
}
|
||||
}
|
||||
if (data.event.id=='curseNet') { // 咒网
|
||||
if (core.hasFlag('curse')) return;
|
||||
core.setFlag('curse', true);
|
||||
else if (data.event.id=='curseNet') { // 咒网
|
||||
core.setFlag('debuff', 'curse');
|
||||
core.insertAction('毒衰咒处理');
|
||||
}
|
||||
core.updateStatusBar();
|
||||
}
|
||||
|
||||
@ -88,8 +88,6 @@ loader.prototype.loadIcons = function () {
|
||||
core.statusBar.image[key].src = core.statusBar.icons[key].src;
|
||||
}
|
||||
}
|
||||
core.statusBar.image.keyboard.src =
|
||||
core.platform.extendKeyboard ? core.statusBar.icons.keyboard.src : core.statusBar.icons.shop.src;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
109
libs/maps.js
109
libs/maps.js
@ -364,16 +364,21 @@ maps.prototype.drawBlock = function (block, animate, dx, dy) {
|
||||
// none:空地
|
||||
if (block.event.id=='none') return;
|
||||
|
||||
var cls = block.event.cls;
|
||||
dx = dx || 0;
|
||||
dy = dy || 0;
|
||||
|
||||
// --- 在界面外的动画不绘制
|
||||
if ((animate||0)>1 && (block.event.animate||0)>1 &&
|
||||
(block.x * 32 + dx < core.bigmap.offsetX - 64 || block.x * 32 + dx > core.bigmap.offsetX + 416 + 32
|
||||
|| block.y * 32 + dy < core.bigmap.offsetY - 64 || block.y * 32 + dy > core.bigmap.offsetY + 416 + 32 + 16)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var blockInfo = this.__getBlockInfo(block);
|
||||
if (blockInfo == null) return;
|
||||
var image = blockInfo.image, x = blockInfo.bx, y = blockInfo.by, height = blockInfo.height;
|
||||
if (!blockInfo.isTileset) x = (animate||0)%(block.event.animate||1);
|
||||
|
||||
dx = dx || 0;
|
||||
dy = dy || 0;
|
||||
|
||||
if (core.isset(block.name)) {
|
||||
core.clearMap(block.name, block.x * 32, block.y * 32, 32, 32);
|
||||
if (block.name == 'bg') {
|
||||
@ -476,6 +481,61 @@ maps.prototype.generateGroundPattern = function (floorId) {
|
||||
// core.material.groundPattern = '#000000';
|
||||
}
|
||||
|
||||
maps.prototype.drawFloorImages = function (floorId, images, animate) {
|
||||
var redraw = core.isset(animate);
|
||||
if (!redraw) {
|
||||
core.status.floorAnimateObjs = core.clone(images);
|
||||
}
|
||||
|
||||
animate = animate || 0;
|
||||
images.forEach(function (t) {
|
||||
if (typeof t == 'string') t = [0,0,t];
|
||||
var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2], frame = core.clamp(parseInt(t[4]), 1, 8);
|
||||
if (redraw && frame == 1) return; // 不重绘
|
||||
|
||||
if (core.isset(dx) && core.isset(dy) &&
|
||||
!core.hasFlag("floorimg_"+floorId+"_"+dx+"_"+dy) &&
|
||||
core.isset(core.material.images.images[p])) {
|
||||
var image = core.material.images.images[p];
|
||||
var width = parseInt(image.width / frame), height = image.height;
|
||||
var offsetX = animate%frame*width;
|
||||
|
||||
if (!t[3]) {
|
||||
if (/.*\.gif/i.test(p) && main.mode=='play') {
|
||||
|
||||
if (redraw) return; // 忽略gif
|
||||
|
||||
core.dom.gif.innerHTML = "";
|
||||
var gif = new Image();
|
||||
gif.src = image.src;
|
||||
gif.style.position = 'absolute';
|
||||
gif.style.left = (dx*core.domStyle.scale)+"px";
|
||||
gif.style.top = (dy*core.domStyle.scale)+"px";
|
||||
gif.style.width = image.width*core.domStyle.scale+"px";
|
||||
gif.style.height = image.height*core.domStyle.scale+"px";
|
||||
core.dom.gif.appendChild(gif);
|
||||
}
|
||||
else {
|
||||
if (redraw) core.clearMap('bg', dx, dy, width, height);
|
||||
core.drawImage('bg', image, offsetX, 0, width, height, dx, dy, width, height);
|
||||
}
|
||||
}
|
||||
else if (t[3]==1) {
|
||||
if (redraw) core.clearMap('fg', dx, dy, width, height);
|
||||
core.drawImage('fg', image, offsetX, 0, width, height, dx, dy, width, height);
|
||||
}
|
||||
else if (t[3]==2) {
|
||||
if (redraw) {
|
||||
core.clearMap('bg', dx, dy + height - 32, width, 32);
|
||||
core.clearMap('fg', dx, dy, width, height-32);
|
||||
}
|
||||
core.drawImage('bg', image, offsetX, height-32, width, 32, dx, dy + height - 32, width, 32);
|
||||
core.drawImage('fg', image, offsetX, 0, width, height-32, dx, dy, width, height-32);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
////// 绘制某张地图 //////
|
||||
maps.prototype.drawMap = function (floorId, callback) {
|
||||
floorId = floorId || core.status.floorId;
|
||||
@ -506,41 +566,15 @@ maps.prototype.drawMap = function (floorId, callback) {
|
||||
images = [[0, 0, images]];
|
||||
}
|
||||
}
|
||||
images.forEach(function (t) {
|
||||
if (typeof t == 'string') t = [0,0,t];
|
||||
var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2];
|
||||
if (core.isset(dx) && core.isset(dy) &&
|
||||
!core.hasFlag("floorimg_"+floorId+"_"+dx+"_"+dy) &&
|
||||
core.isset(core.material.images.images[p])) {
|
||||
var image = core.material.images.images[p];
|
||||
if (!t[3]) {
|
||||
if (/.*\.gif/i.test(p) && main.mode=='play') {
|
||||
core.dom.gif.innerHTML = "";
|
||||
var gif = new Image();
|
||||
gif.src = image.src;
|
||||
gif.style.position = 'absolute';
|
||||
gif.style.left = (32*dx*core.domStyle.scale)+"px";
|
||||
gif.style.top = (32*dy*core.domStyle.scale)+"px";
|
||||
gif.style.width = image.width*core.domStyle.scale+"px";
|
||||
gif.style.height = image.height*core.domStyle.scale+"px";
|
||||
core.dom.gif.appendChild(gif);
|
||||
}
|
||||
else {
|
||||
core.drawImage('bg', image, 32*dx, 32*dy, image.width, image.height);
|
||||
}
|
||||
}
|
||||
else if (t[3]==1)
|
||||
core.drawImage('fg', image, 32*dx, 32*dy, image.width, image.height);
|
||||
else if (t[3]==2) {
|
||||
core.drawImage('fg', image, 0, 0, image.width, image.height-32,
|
||||
32*dx, 32*dy, image.width, image.height-32);
|
||||
core.drawImage('bg', image, 0, image.height-32, image.width, 32,
|
||||
32*dx, 32*dy + image.height - 32, image.width, 32);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// ----- 可以调整这三行的顺序来修改覆盖关系;同层画布上,后绘制的覆盖先绘制的
|
||||
// ----- ui.js的drawThumbnail函数也需要对应进行修改。
|
||||
|
||||
// 绘制楼层贴图
|
||||
core.maps.drawFloorImages(floorId, images);
|
||||
// 绘制背景层图块
|
||||
core.maps.drawBgFgMap(floorId, core.canvas.bg, "bg", true);
|
||||
// 绘制前景层图块
|
||||
core.maps.drawBgFgMap(floorId, core.canvas.fg, "fg", true);
|
||||
|
||||
}
|
||||
@ -1347,6 +1381,7 @@ maps.prototype.removeGlobalAnimate = function (x, y, all, name) {
|
||||
core.status.globalAnimateStatus = 0;
|
||||
core.status.globalAnimateObjs = [];
|
||||
core.status.autotileAnimateObjs = {"blocks": [], "map": null, "bgmap": null, "fgmap": null};
|
||||
core.status.floorAnimateObjs = [];
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
35
libs/ui.js
35
libs/ui.js
@ -563,6 +563,9 @@ ui.prototype.drawTextBox = function(content, showAll) {
|
||||
py=core.getHeroLoc('y');
|
||||
ydelta = core.material.icons.hero.height-32;
|
||||
}
|
||||
else if (ss[1] == 'null') {
|
||||
px = py = null;
|
||||
}
|
||||
else if (ss.length>=3) {
|
||||
px=parseInt(ss[1]);
|
||||
py=parseInt(ss[2]);
|
||||
@ -2420,6 +2423,7 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente
|
||||
tempCanvas.canvas.height = tempHeight;
|
||||
tempCanvas.clearRect(0, 0, tempWidth, tempHeight);
|
||||
|
||||
// -------- 1. 绘制地板
|
||||
var groundId = (core.status.maps||core.floors)[floorId].defaultGround || "ground";
|
||||
var blockIcon = core.material.icons.terrains[groundId];
|
||||
for (var i = 0; i < mw; i++) {
|
||||
@ -2428,7 +2432,6 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente
|
||||
}
|
||||
}
|
||||
|
||||
// background image
|
||||
var images = [];
|
||||
if (core.isset((core.status.maps||core.floors)[floorId].images)) {
|
||||
images = (core.status.maps||core.floors)[floorId].images;
|
||||
@ -2436,25 +2439,27 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente
|
||||
images = [[0, 0, images]];
|
||||
}
|
||||
}
|
||||
|
||||
// -------- 2. 绘制背景贴图
|
||||
images.forEach(function (t) {
|
||||
if (typeof t == 'string') t = [0,0,t];
|
||||
var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2];
|
||||
var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2], frame = core.clamp(parseInt(t[4]), 1, 8);
|
||||
if (core.isset(dx) && core.isset(dy) &&
|
||||
!core.hasFlag("floorimg_"+floorId+"_"+dx+"_"+dy) &&
|
||||
core.isset(core.material.images.images[p])) {
|
||||
var image = core.material.images.images[p];
|
||||
var width = image.width / frame, height = image.height;
|
||||
if (!t[3])
|
||||
tempCanvas.drawImage(image, 32 * dx, 32 * dy, image.width, image.height);
|
||||
tempCanvas.drawImage(image, 0, 0, width, height, dx, dy, width, height);
|
||||
else if (t[3]==2)
|
||||
tempCanvas.drawImage(image, 0, image.height-32, image.width, 32,
|
||||
32 * dx, 32 * dy + image.height - 32, image.width, 32);
|
||||
tempCanvas.drawImage(image, 0, height-32, width, 32, dx, dy + height - 32, width, 32);
|
||||
}
|
||||
})
|
||||
|
||||
// background map
|
||||
// -------- 3. 绘制背景图块
|
||||
core.maps.drawBgFgMap(floorId, tempCanvas, "bg");
|
||||
|
||||
// draw block
|
||||
// -------- 4. 绘制事件层
|
||||
var mapArray = core.maps.getMapArray(blocks,mw,mh);
|
||||
for (var b in blocks) {
|
||||
var block = blocks[b];
|
||||
@ -2481,7 +2486,7 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente
|
||||
}
|
||||
}
|
||||
}
|
||||
// draw hero
|
||||
// -------- 5. 绘制勇士
|
||||
if (core.isset(heroLoc)) {
|
||||
if (!core.isset(core.material.images.images[heroIcon]))
|
||||
heroIcon = "hero.png";
|
||||
@ -2490,25 +2495,25 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente
|
||||
tempCanvas.drawImage(core.material.images.images[heroIcon], icon.stop * 32, icon.loc * height, 32, height, 32*heroLoc.x, 32*heroLoc.y+32-height, 32, height);
|
||||
}
|
||||
|
||||
// draw fg
|
||||
// -------- 6. 绘制前景贴图
|
||||
images.forEach(function (t) {
|
||||
var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2];
|
||||
var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2], frame = core.clamp(parseInt(t[4]), 1, 8);
|
||||
if (core.isset(dx) && core.isset(dy) &&
|
||||
!core.hasFlag("floorimg_"+floorId+"_"+dx+"_"+dy) &&
|
||||
core.isset(core.material.images.images[p])) {
|
||||
var image = core.material.images.images[p];
|
||||
var width = image.width / frame, height = image.height;
|
||||
if (t[3]==1)
|
||||
tempCanvas.drawImage(image, 32*dx, 32*dy, image.width, image.height);
|
||||
tempCanvas.drawImage(image, 0, 0, width, height, dx, dy, width, height);
|
||||
else if (t[3]==2)
|
||||
tempCanvas.drawImage(image, 0, 0, image.width, image.height-32,
|
||||
32*dx, 32*dy, image.width, image.height-32);
|
||||
tempCanvas.drawImage(image, 0, 0, width, height-32, dx, dy, width, height-32);
|
||||
}
|
||||
})
|
||||
|
||||
// foreground map
|
||||
// -------- 7. 绘制前景图块
|
||||
core.maps.drawBgFgMap(floorId, tempCanvas, "fg");
|
||||
|
||||
// draw damage
|
||||
// -------- 8. 绘制显伤
|
||||
if (core.status.event.id=='viewMaps' && (core.status.event.data||{}).damage)
|
||||
core.control.updateDamage(floorId, tempCanvas);
|
||||
|
||||
|
||||
@ -62,18 +62,18 @@ utils.prototype.replaceText = function (text, need, times) {
|
||||
////// 计算表达式的值 //////
|
||||
utils.prototype.calValue = function (value, prefix, need, times) {
|
||||
if (!core.isset(value)) return value;
|
||||
if (typeof value == 'number') {
|
||||
return value;
|
||||
}
|
||||
if (value instanceof Function) {
|
||||
return value();
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
value=value.replace(/status:([\w\d_]+)/g, "core.getStatus('$1')");
|
||||
value=value.replace(/item:([\w\d_]+)/g, "core.itemCount('$1')");
|
||||
value=value.replace(/flag:([\w\d_]+)/g, "core.getFlag('$1', 0)");
|
||||
value=value.replace(/switch:([\w\d_]+)/g, "core.getFlag('"+(prefix||"global")+"@$1', 0)");
|
||||
return eval(value);
|
||||
}
|
||||
if (value instanceof Function) {
|
||||
return value();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
////// 字符串自动换行的分割 //////
|
||||
utils.prototype.splitLines = function(canvas, text, maxLength, font) {
|
||||
@ -116,6 +116,18 @@ utils.prototype.unshift = function (a,b) {
|
||||
return a;
|
||||
}
|
||||
|
||||
////// 向某个数组后插入另一个数组或元素 //////
|
||||
utils.prototype.push = function (a,b) {
|
||||
if (!(a instanceof Array) || !core.isset(b)) return;
|
||||
if (b instanceof Array) {
|
||||
core.clone(b).forEach(function (e) {
|
||||
a.push(e);
|
||||
});
|
||||
}
|
||||
else a.push(b);
|
||||
return a;
|
||||
}
|
||||
|
||||
////// 设置本地存储 //////
|
||||
utils.prototype.setLocalStorage = function(key, value) {
|
||||
try {
|
||||
|
||||
12
main.js
12
main.js
@ -75,7 +75,7 @@ function main() {
|
||||
'loader', 'control', 'utils', 'items', 'icons', 'maps', 'enemys', 'events', 'actions', 'data', 'ui', 'core'
|
||||
];
|
||||
this.pureData = [
|
||||
'data', 'enemys', 'icons', 'maps', 'items', 'functions'
|
||||
'data', 'enemys', 'icons', 'maps', 'items', 'functions', 'events'
|
||||
];
|
||||
this.materials = [
|
||||
'animates', 'enemys', 'hero', 'items', 'npcs', 'terrains', 'enemy48', 'npc48'
|
||||
@ -183,7 +183,7 @@ function main() {
|
||||
this.canvas = {};
|
||||
|
||||
this.__VERSION__ = "2.5.4";
|
||||
this.__VERSION_CODE__ = 20;
|
||||
this.__VERSION_CODE__ = 24;
|
||||
}
|
||||
|
||||
main.prototype.init = function (mode, callback) {
|
||||
@ -520,6 +520,14 @@ main.statusBar.image.shop.onclick = function (e) {
|
||||
main.core.openQuickShop(true);
|
||||
}
|
||||
|
||||
////// 点击金币时也可以开启虚拟键盘 //////
|
||||
main.statusBar.image.money.onclick = function (e) {
|
||||
e.stopPropagation();
|
||||
|
||||
if (main.core.isPlaying())
|
||||
main.core.openQuickShop(true);
|
||||
}
|
||||
|
||||
////// 点击状态栏中的存档按钮时 //////
|
||||
main.statusBar.image.save.onclick = function (e) {
|
||||
e.stopPropagation();
|
||||
|
||||
@ -354,7 +354,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
||||
"purify": 3,
|
||||
"hatred": 2,
|
||||
"moveSpeed": 100,
|
||||
"animateSpeed": 300,
|
||||
"animateSpeed": 400,
|
||||
"floorChangeTime": 800
|
||||
},
|
||||
"flags": {
|
||||
|
||||
167
project/events.js
Normal file
167
project/events.js
Normal file
@ -0,0 +1,167 @@
|
||||
var events_c12a15a8_c380_4b28_8144_256cba95f760 =
|
||||
{
|
||||
"commonEvent": {
|
||||
"加点事件": [
|
||||
{
|
||||
"type": "comment",
|
||||
"text": "flag:point表示当前应该的加点数值"
|
||||
},
|
||||
{
|
||||
"type": "choices",
|
||||
"choices": [
|
||||
{
|
||||
"text": "攻击+${1*flag:point}",
|
||||
"action": [
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "status:atk",
|
||||
"value": "status:atk+1*flag:point"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "防御+${2*flag:point}",
|
||||
"action": [
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "status:def",
|
||||
"value": "status:def+2*flag:point"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"text": "生命+${200*flag:point}",
|
||||
"action": [
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "status:hp",
|
||||
"value": "status:hp+200*flag:point"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "flag:point",
|
||||
"value": "null"
|
||||
}
|
||||
],
|
||||
"毒衰咒处理": [
|
||||
{
|
||||
"type": "comment",
|
||||
"text": "获得毒衰咒效果,flag:debuff为要获得的类型"
|
||||
},
|
||||
{
|
||||
"type": "switch",
|
||||
"condition": "flag:debuff",
|
||||
"caseList": [
|
||||
{
|
||||
"case": "'poison'",
|
||||
"action": [
|
||||
{
|
||||
"type": "comment",
|
||||
"text": "获得毒效果"
|
||||
},
|
||||
{
|
||||
"type": "if",
|
||||
"condition": "!flag:poison",
|
||||
"true": [
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "flag:poison",
|
||||
"value": "true"
|
||||
}
|
||||
],
|
||||
"false": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"case": "'weak'",
|
||||
"action": [
|
||||
{
|
||||
"type": "comment",
|
||||
"text": "获得衰效果"
|
||||
},
|
||||
{
|
||||
"type": "if",
|
||||
"condition": "!flag:weak",
|
||||
"true": [
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "flag:weak",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"type": "if",
|
||||
"condition": "core.values.weakValue>=1",
|
||||
"true": [
|
||||
{
|
||||
"type": "comment",
|
||||
"text": ">=1:直接扣数值"
|
||||
},
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "status:atk",
|
||||
"value": "status:atk-core.values.weakValue"
|
||||
},
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "status:def",
|
||||
"value": "status:def-core.values.weakValue"
|
||||
}
|
||||
],
|
||||
"false": [
|
||||
{
|
||||
"type": "comment",
|
||||
"text": "<1:扣比例"
|
||||
},
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "flag:equip_atk_buff",
|
||||
"value": "core.getFlag('equip_atk_buff',1)-core.values.weakValue"
|
||||
},
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "flag:equip_def_buff",
|
||||
"value": "core.getFlag('equip_def_buff',1)-core.values.weakValue"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"false": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"case": "'curse'",
|
||||
"action": [
|
||||
{
|
||||
"type": "comment",
|
||||
"text": "获得咒效果"
|
||||
},
|
||||
{
|
||||
"type": "if",
|
||||
"condition": "!flag:curse",
|
||||
"true": [
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "flag:curse",
|
||||
"value": "true"
|
||||
}
|
||||
],
|
||||
"false": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "setValue",
|
||||
"name": "flag:debuff",
|
||||
"value": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -11,7 +11,7 @@ main.floors.sample1=
|
||||
0,
|
||||
0,
|
||||
"bg.jpg",
|
||||
false
|
||||
0
|
||||
]
|
||||
],
|
||||
"weather": [
|
||||
|
||||
@ -168,21 +168,9 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
if (!core.flags.enableAddPoint || !core.isset(point) || point<=0) return [];
|
||||
|
||||
// 加点,返回一个choices事件
|
||||
return [
|
||||
{"type": "choices",
|
||||
"choices": [
|
||||
{"text": "攻击+"+(1*point), "action": [
|
||||
{"type": "setValue", "name": "status:atk", "value": "status:atk+"+(1*point)}
|
||||
]},
|
||||
{"text": "防御+"+(2*point), "action": [
|
||||
{"type": "setValue", "name": "status:def", "value": "status:def+"+(2*point)}
|
||||
]},
|
||||
{"text": "生命+"+(200*point), "action": [
|
||||
{"type": "setValue", "name": "status:hp", "value": "status:hp+"+(200*point)}
|
||||
]},
|
||||
]
|
||||
}
|
||||
];
|
||||
// ----- 从V2.5.4开始,移动到“公共事件-加点事件”中
|
||||
core.setFlag('point', point); // 设置flag:point
|
||||
return core.getCommonEvent('加点事件');
|
||||
},
|
||||
"afterBattle": function(enemyId,x,y,callback) {
|
||||
// 战斗结束后触发的事件
|
||||
@ -236,27 +224,24 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
core.removeBlock(x, y);
|
||||
}
|
||||
|
||||
// 毒衰咒的处理
|
||||
// 事件的处理
|
||||
var todo = [];
|
||||
|
||||
var special = enemy.special;
|
||||
// 中毒
|
||||
if (core.enemys.hasSpecial(special, 12) && !core.hasFlag('poison')) {
|
||||
core.setFlag('poison', true);
|
||||
if (core.enemys.hasSpecial(special, 12)) {
|
||||
core.push(todo, [{"type": "setValue", "name": "flag:debuff", "value": "'poison'"}]);
|
||||
core.push(todo, [{"type": "insert", "name": "毒衰咒处理"}]);
|
||||
}
|
||||
// 衰弱
|
||||
if (core.enemys.hasSpecial(special, 13) && !core.hasFlag('weak')) {
|
||||
core.setFlag('weak', true);
|
||||
if (core.values.weakValue>=1) { // >=1:直接扣数值
|
||||
core.status.hero.atk -= core.values.weakValue;
|
||||
core.status.hero.def -= core.values.weakValue;
|
||||
}
|
||||
else { // <1:扣比例
|
||||
core.setFlag("equip_atk_buff", core.getFlag("equip_atk_buff", 1) - core.values.weakValue);
|
||||
core.setFlag("equip_def_buff", core.getFlag("equip_def_buff", 1) - core.values.weakValue);
|
||||
}
|
||||
if (core.enemys.hasSpecial(special, 13)) {
|
||||
core.push(todo, [{"type": "setValue", "name": "flag:debuff", "value": "'weak'"}]);
|
||||
core.push(todo, [{"type": "insert", "name": "毒衰咒处理"}]);
|
||||
}
|
||||
// 诅咒
|
||||
if (core.enemys.hasSpecial(special, 14) && !core.hasFlag('curse')) {
|
||||
core.setFlag('curse', true);
|
||||
if (core.enemys.hasSpecial(special, 14)) {
|
||||
core.push(todo, [{"type": "setValue", "name": "flag:debuff", "value": "'curse'"}]);
|
||||
core.push(todo, [{"type": "insert", "name": "毒衰咒处理"}]);
|
||||
}
|
||||
// 仇恨属性:减半
|
||||
if (core.flags.hatredDecrease && core.enemys.hasSpecial(special, 17)) {
|
||||
@ -287,30 +272,24 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
core.setFlag('skill', 0);
|
||||
core.setFlag('skillName', '无');
|
||||
}
|
||||
|
||||
core.updateStatusBar();
|
||||
|
||||
|
||||
// 事件的处理
|
||||
var todo = [];
|
||||
// 如果该点存在,且有事件 -- V2.5.4 以后阻击怪也可以有战后事件了
|
||||
if (core.isset(x) && core.isset(y)) {
|
||||
var event = core.floors[core.status.floorId].afterBattle[x+","+y];
|
||||
if (core.isset(event)) {
|
||||
// 插入事件
|
||||
core.unshift(todo, event);
|
||||
}
|
||||
}
|
||||
// 如果有加点
|
||||
var point = core.material.enemys[enemyId].point;
|
||||
if (core.isset(point) && point>0) {
|
||||
core.unshift(todo, core.events.addPoint(core.material.enemys[enemyId]));
|
||||
if (core.flags.enableAddPoint && core.isset(point) && point>0) {
|
||||
core.push(todo, [{"type": "setValue", "name": "flag:point", "value": point}]);
|
||||
core.push(todo, [{"type": "insert", "name": "加点事件"}]);
|
||||
}
|
||||
|
||||
// 如果该点存在,且有事件 -- V2.5.4 以后阻击怪也可以有战后事件了
|
||||
if (core.isset(x) && core.isset(y)) {
|
||||
core.push(todo, core.floors[core.status.floorId].afterBattle[x+","+y]);
|
||||
}
|
||||
|
||||
// 在这里增加其他的自定义事件需求
|
||||
/*
|
||||
if (enemyId=='xxx') {
|
||||
core.unshift(todo, [
|
||||
core.push(todo, [
|
||||
{"type": "...", ...},
|
||||
]);
|
||||
}
|
||||
|
||||
25
更新说明.txt
25
更新说明.txt
@ -1,4 +1,23 @@
|
||||
HTML5魔塔样板V2.5.2
|
||||
HTML5魔塔样板V2.5.4
|
||||
|
||||
发布15x15的版本
|
||||
支持多重装备(一个装备可以装到多个孔上)
|
||||
工具栏按钮增添至8个,快捷商店和虚拟键盘同时显示
|
||||
点击状态栏的金币图标也可以打开快捷商店
|
||||
等待事件提供flag:px和flag:py在0~415之间
|
||||
事件:呼出存读档界面;呼出怪物手册
|
||||
事件:使用道具,暂停背景音乐,暂停所有音效
|
||||
type:trigger可以触发系统事件
|
||||
独立开关
|
||||
贴图也可以支持帧动画了
|
||||
图块内置颜色选择器
|
||||
标题界面增加音乐按钮
|
||||
等待事件可被Ctrl(长按)跳过
|
||||
部分Bug修复,大量细节优化,性能进一步得到提升
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
HTML5魔塔样板V2.5.3
|
||||
|
||||
标题界面事件化;现在可以用事件流来处理标题界面了
|
||||
动态canvas管理;无限图层,可以任意创建图层并使用
|
||||
@ -20,6 +39,8 @@ BGM缓存管理;新增事件:预加载BGM
|
||||
地图编辑器中选中点高亮;双击选中素材;WASD平移大地图
|
||||
修复所有Bug,部分代码重构,大量细节优化
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
HTML5魔塔样板V2.5.2
|
||||
|
||||
怪物和NPC的行走图和朝向问题(详见文档)
|
||||
@ -39,6 +60,8 @@ HTML5魔塔样板V2.5.2
|
||||
菜单栏中新增虚拟键盘的弹出
|
||||
修复所有已知Bug;部分细节优化
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
HTML5魔塔样板V2.5.1
|
||||
|
||||
新增事件type:insert,可以插入另一个地点的事件执行(公共事件)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user