Merge pull request #273 from ckcz123/v2.0

V2.0
This commit is contained in:
Zhang Chen 2018-12-17 16:24:28 +08:00 committed by GitHub
commit 5986d5f9fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 2504 additions and 1432 deletions

2
.gitignore vendored
View File

@ -1,7 +1,7 @@
.vscode
*ce5eec52_2fa1_447b_8dad_764e267a7fab*
.DS_Store
MTBuilder.app
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

View File

@ -5,22 +5,23 @@ grammar MotaAction;
//事件 事件编辑器入口之一
event_m
: '事件' BGNL? Newline '覆盖触发器' Bool '启用' Bool '通行状态' B_0_List '显伤' Bool BGNL? Newline action+ BEND
: '事件' BGNL? Newline '覆盖触发器' Bool '启用' Bool '通行状态' B_0_List '动画' Bool '显伤' Bool BGNL? Newline action+ BEND
/* event_m
tooltip : 编辑魔塔的事件
helpUrl : https://h5mota.com/games/template/docs/#/event
default : [false,null,null,null]
default : [false,null,null,null,null]
B_0_List_0=eval(B_0_List_0);
var code = {
'trigger': Bool_0?'action':null,
'enable': Bool_1,
'noPass': B_0_List_0,
'displayDamage': Bool_2,
'animate': Bool_2,
'displayDamage': Bool_3,
'data': 'data_asdfefw'
}
if (!Bool_0 && Bool_1 && (B_0_List_0===null) && Bool_2) code = 'data_asdfefw';
if (!Bool_0 && Bool_1 && (B_0_List_0===null) && Bool_2 && Bool_3) code = 'data_asdfefw';
code=JSON.stringify(code,null,2).split('"data_asdfefw"').join('[\n'+action_0+']\n');
return code;
*/;
@ -50,15 +51,16 @@ return code;
*/;
levelCase
: '需求' expression '称号' EvalString? BGNL? Newline action+
: '需求' expression '称号' EvalString? '是否扣除经验' Bool BGNL? Newline action+
/* levelCase
tooltip : 升级设定
helpUrl : https://h5mota.com/games/template/docs/#/event?id=%e7%bb%8f%e9%aa%8c%e5%8d%87%e7%ba%a7%ef%bc%88%e8%bf%9b%e9%98%b6%2f%e5%a2%83%e7%95%8c%e5%a1%94%ef%bc%89
default : [0,"",null]
default : [0,"",false,null]
colour : this.subColor
var code = '{"need": "'+expression_0+'", "title": "'+EvalString_0+'", "action": [\n'+action_0+']},\n';
Bool_0 = Bool_0?', "clear": true':'';
var code = '{"need": "'+expression_0+'", "title": "'+EvalString_0+'"'+Bool_0+', "action": [\n'+action_0+']},\n';
return code;
*/;
@ -222,6 +224,7 @@ action
| text_1_s
| comment_s
| autoText_s
| scrollText_s
| setText_s
| tip_s
| setValue_s
@ -259,13 +262,12 @@ action
| unfollow_s
| animate_s
| vibrate_s
| showImage_0_s
| showImage_1_s
| animateImage_0_s
| animateImage_1_s
| showImage_s
| hideImage_s
| showTextImage_s
| moveImage_s
| showGif_0_s
| showGif_1_s
| moveImage_0_s
| setFg_0_s
| setFg_1_s
| setWeather_s
@ -276,6 +278,8 @@ action
| playBgm_s
| pauseBgm_s
| resumeBgm_s
| loadBgm_s
| freeBgm_s
| playSound_s
| setVolume_s
| win_s
@ -365,6 +369,19 @@ var code = '{"type": "autoText", "text": "'+title+EvalString_1+EvalString_2+'",
return code;
*/;
scrollText_s
: '滚动剧情文本:' '时间' Int '不等待执行完毕' Bool? BGNL? EvalString Newline
/* scrollText_s
tooltip : scrollText滚动剧情文本将从下到上进行滚动显示。
helpUrl : https://h5mota.com/games/template/docs/#/event?id=scrollText%ef%bc%9a%e6%bb%9a%e5%8a%a8%e5%89%a7%e6%83%85%e6%96%87%e6%9c%ac
default : [5000,false,"时间是总时间可以使用setText事件来控制字体、颜色、大小、偏移量等"]
Bool_0 = Bool_0?', "async": true':'';
var code = '{"type": "scrollText", "text": "'+EvalString_0+'"'+Bool_0+', "time" :'+Int_0+'},\n';
return code;
*/;
setText_s
: '设置剧情文本的属性' '位置' SetTextPosition_List '偏移像素' EvalString? BGNL? '标题颜色' EvalString? '正文颜色' EvalString? '背景色' EvalString? '粗体' B_1_List BGNL? '标题字体大小' EvalString? '正文字体大小' EvalString? '打字间隔' EvalString? Newline
@ -509,7 +526,7 @@ if (EvalString_0 && EvalString_1) {
floorstr = ', "loc": ['+EvalString_0.join(',')+']';
}
IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"');
Int_0 = Int_0 ?(', "time": '+Int_0):'';
Int_0 = Int_0!=='' ?(', "time": '+Int_0):'';
Bool_0 = Bool_0 ?', "async": true':'';
var code = '{"type": "show"'+floorstr+IdString_0+''+Int_0+Bool_0+'},\n';
return code;
@ -542,7 +559,7 @@ if (EvalString_0 && EvalString_1) {
floorstr = ', "loc": ['+EvalString_0.join(',')+']';
}
IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"');
Int_0 = Int_0 ?(', "time": '+Int_0):'';
Int_0 = Int_0!=='' ?(', "time": '+Int_0):'';
Bool_0 = Bool_0 ?', "async": true':'';
var code = '{"type": "hide"'+floorstr+IdString_0+''+Int_0+Bool_0+'},\n';
return code;
@ -798,14 +815,16 @@ return code;
*/;
hideStatusBar_s
: '隐藏状态栏' Newline
: '隐藏状态栏' '不隐藏竖屏工具栏' Bool Newline
/* hideStatusBar_s
tooltip : hideStatusBar: 隐藏状态栏
helpUrl : https://h5mota.com/games/template/docs/#/event?id=hideStatusBar%ef%bc%9a%e9%9a%90%e8%97%8f%e7%8a%b6%e6%80%81%e6%a0%8f
colour : this.soundColor
var code = '{"type": "hideStatusBar"},\n';
default : [false]
Bool_0 = Bool_0?', "toolbox": true':'';
var code = '{"type": "hideStatusBar"'+Bool_0+'},\n';
return code;
*/;
@ -1005,58 +1024,50 @@ var code = '{"type": "animate", "name": "'+IdString_0+'"'+EvalString_0+async+'},
return code;
*/;
showImage_0_s
: '显示图片' EvalString '起点像素位置' 'x' PosString 'y' PosString Newline
showImage_s
: '显示图片' '图片编号' Int '图片' EvalString '起点像素位置' 'x' PosString 'y' PosString BGNL?
'放大率 : x' Int '% y' Int '% 不透明度' Number '时间' Int '不等待执行完毕' Bool Newline
/* showImage_0_s
/* showImage_s
tooltip : showImage显示图片
helpUrl : https://h5mota.com/games/template/docs/#/event?id=showimage%EF%BC%9A%E6%98%BE%E7%A4%BA%E5%9B%BE%E7%89%87
default : ["bg.jpg","0","0"]
helpUrl : https://h5mota.com/games/template/docs/#/event?id=showImage%ef%bc%9a%e6%98%be%e7%a4%ba%e5%9b%be%e7%89%87
default : [1,"bg.jpg","0","0",100,100,1,0,false]
colour : this.printColor
var code = '{"type": "showImage", "name": "'+EvalString_0+'", "loc": ['+PosString_0+','+PosString_1+']},\n';
if(Int_0<=0 || Int_0>50) throw new Error('图片编号在1~50之间');
var async = Bool_0?', "async": true':'';
var code = '{"type": "showImage", "code": '+Int_0+', "image": "'+EvalString_0+'", "loc": ['+PosString_0+','+PosString_1+'], "dw": '+Int_1+', "dh": '+Int_2+', "opacity": '+Number_0+', "time": '+Int_3+async+'},\n';
return code;
*/;
showImage_1_s
: '清除所有图片' Newline
showTextImage_s
: '显示图片化文本' '文本内容' EvalString BGNL?
'图片编号' Int '起点像素位置' 'x' PosString 'y' PosString '不透明度' Number '时间' Int '不等待执行完毕' Bool Newline
/* showImage_1_s
tooltip : showImage清除所有显示图片
helpUrl : https://h5mota.com/games/template/docs/#/event?id=showimage%EF%BC%9A%E6%98%BE%E7%A4%BA%E5%9B%BE%E7%89%87
/* showTextImage_s
tooltip : showTextImage显示图片化文本
helpUrl : https://h5mota.com/games/template/docs/#/event?id=showTextImage%ef%bc%9a%e6%98%be%e7%a4%ba%e6%96%87%e6%9c%ac%e5%8c%96%e5%9b%be%e7%89%87
colour : this.printColor
var code = '{"type": "showImage"},\n';
default : ["可以使用setText事件来控制字体、颜色、大小、偏移量等",1,"0","0",1,0,false]
if(Int_0<=0 || Int_0>50) throw new Error('图片编号在1~50之间');
var async = Bool_0?', "async": true':'';
var code = '{"type": "showTextImage", "code": '+Int_0+', "text": "'+EvalString_0+'", "loc": ['+PosString_0+','+PosString_1+'], "opacity": '+Number_0+', "time": '+Int_1+async+'},\n';
return code;
*/;
animateImage_0_s
: '图片淡入' EvalString '起点像素位置' 'x' PosString 'y' PosString '动画时间' Int '保留图片' Bool '不等待执行完毕' Bool Newline
hideImage_s
: '清除图片' '图片编号' Int '时间' Int '不等待执行完毕' Bool Newline
/* animateImage_0_s
tooltip : animageImage图片淡入
helpUrl : https://h5mota.com/games/template/docs/#/event?id=animateimage%EF%BC%9A%E5%9B%BE%E7%89%87%E6%B7%A1%E5%85%A5%E6%B7%A1%E5%87%BA
default : ["bg.jpg","0","0",500,true,false]
/* hideImage_s
tooltip : hideImage清除图片
helpUrl : https://h5mota.com/games/template/docs/#/event?id=hideImage%ef%bc%9a%e6%b8%85%e9%99%a4%e5%9b%be%e7%89%87
colour : this.printColor
var keep = Bool_0?', "keep": true':'';
var async = Bool_1?', "async": true':'';
var code = '{"type": "animateImage", "action": "show", "name": "'+EvalString_0+'", "loc": ['+PosString_0+','+PosString_1+'], "time": '+Int_0+keep+async+'},\n';
return code;
*/;
animateImage_1_s
: '图片淡出' EvalString '起点像素位置' 'x' PosString 'y' PosString '动画时间' Int '清除图片' Bool '不等待执行完毕' Bool Newline
/* animateImage_1_s
tooltip : animageImage图片淡出
helpUrl : https://h5mota.com/games/template/docs/#/event?id=animateimage%EF%BC%9A%E5%9B%BE%E7%89%87%E6%B7%A1%E5%85%A5%E6%B7%A1%E5%87%BA
default : ["bg.jpg","0","0",500,true,false]
colour : this.printColor
var keep = Bool_0?', "keep": true':'';
var async = Bool_1?', "async": true':'';
var code = '{"type": "animateImage", "action": "hide", "name": "'+EvalString_0+'", "loc": ['+PosString_0+','+PosString_1+'], "time": '+Int_0+keep+async+'},\n';
default : [1,0,false]
if(Int_0<=0 || Int_0>50) throw new Error('图片编号在1~50之间');
var async = Bool_0?', "async": true':'';
var code = '{"type": "hideImage", "code": '+Int_0+', "time": '+Int_1+async+'},\n';
return code;
*/;
@ -1085,19 +1096,23 @@ var code = '{"type": "showGif"},\n';
return code;
*/;
moveImage_0_s
: '图片移动' EvalString '起点像素位置' 'x' PosString 'y' PosString BGNL
'终点像素位置' 'x' PosString 'y' PosString '移动时间' Int '保留图片' Bool '不等待执行完毕' Bool Newline
moveImage_s
: '图片移动' '图片编号' Int '终点像素位置' 'x' PosString? 'y' PosString? BGNL?
'不透明度' EvalString? '移动时间' Int '不等待执行完毕' Bool Newline
/* moveImage_0_s
/* moveImage_s
tooltip : moveImage图片移动
helpUrl : https://h5mota.com/games/template/docs/#/event?id=moveimage%EF%BC%9A%E5%9B%BE%E7%89%87%E7%A7%BB%E5%8A%A8
default : ["bg.jpg","0","0","0","0",500,true,false]
helpUrl : https://h5mota.com/games/template/docs/#/event?id=moveImage%ef%bc%9a%e5%9b%be%e7%89%87%e7%a7%bb%e5%8a%a8
default : [1,'','','',500,false]
colour : this.printColor
var keep = Bool_0?', "keep": true':'';
var async = Bool_1?', "async": true':'';
var code = '{"type": "moveImage", "name": "'+EvalString_0+'", "from": ['+PosString_0+','+PosString_1+'], "to": ['+PosString_2+','+PosString_3+'], "time": '+Int_0+keep+async+'},\n';
if(Int_0<=0 || Int_0>50) throw new Error('图片编号在1~50之间');
var toloc = '';
if (PosString_0 && PosString_1)
toloc = ', "to": ['+PosString_0+','+PosString_1+']';
EvalString_0 = (EvalString_0!=='') ? (', "opacity": '+EvalString_0):'';
var async = Bool_0?', "async": true':'';
var code = '{"type": "moveImage", "code": '+Int_0+toloc+EvalString_0+',"time": '+Int_1+async+'},\n';
return code;
*/;
@ -1119,7 +1134,7 @@ Number_0 = limit(Number_0,0,255);
Number_1 = limit(Number_1,0,255);
Number_2 = limit(Number_2,0,255);
Number_3 = limit(Number_3,0,1);
Int_0 = Int_0 ?(', "time": '+Int_0):'';
Int_0 = Int_0!=='' ?(', "time": '+Int_0):'';
var async = Bool_0?', "async": true':'';
var code = '{"type": "setFg", "color": ['+Number_0+','+Number_1+','+Number_2+','+Number_3+']'+Int_0 +async+'},\n';
return code;
@ -1134,7 +1149,7 @@ tooltip : setFg: 恢复画面色调,动画时间可不填
helpUrl : https://h5mota.com/games/template/docs/#/event?id=setfg%EF%BC%9A%E6%9B%B4%E6%94%B9%E7%94%BB%E9%9D%A2%E8%89%B2%E8%B0%83
default : [500,false]
colour : this.soundColor
Int_0 = Int_0 ?(', "time": '+Int_0):'';
Int_0 = Int_0!=='' ?(', "time": '+Int_0):'';
var async = Bool_0?', "async": true':'';
var code = '{"type": "setFg"'+Int_0 +async+'},\n';
return code;
@ -1168,7 +1183,7 @@ var floorstr = '';
if (PosString_0 && PosString_1) {
floorstr = ', "loc": ['+PosString_0+','+PosString_1+']';
}
Int_0 = Int_0 ?(', "time": '+Int_0):'';
Int_0 = Int_0!=='' ?(', "time": '+Int_0):'';
Bool_0 = Bool_0?', "keep": true':'';
Bool_1 = Bool_1?', "async": true':'';
var code = '{"type": "move"'+floorstr+Int_0+Bool_0+Bool_1+', "steps": '+JSON.stringify(StepString_0)+'},\n';
@ -1184,7 +1199,7 @@ tooltip : moveHero移动勇士,用这种方式移动勇士的过程中将无
helpUrl : https://h5mota.com/games/template/docs/#/event?id=movehero%EF%BC%9A%E7%A7%BB%E5%8A%A8%E5%8B%87%E5%A3%AB
default : [500,false,"上右3下2左上左2"]
colour : this.dataColor
Int_0 = Int_0 ?(', "time": '+Int_0):'';
Int_0 = Int_0!=='' ?(', "time": '+Int_0):'';
Bool_0 = Bool_0?', "async": true':'';
var code = '{"type": "moveHero"'+Int_0+Bool_0+', "steps": '+JSON.stringify(StepString_0)+'},\n';
return code;
@ -1206,7 +1221,7 @@ if (PosString_0 && PosString_1) {
if (PosString_2 && PosString_3) {
floorstr += ', "to": ['+PosString_2+','+PosString_3+']';
}
Int_0 = Int_0 ?(', "time": '+Int_0):'';
Int_0 = Int_0!=='' ?(', "time": '+Int_0):'';
Bool_0 = Bool_0?', "keep": true':'';
Bool_1 = Bool_1?', "async": true':'';
var code = '{"type": "jump"'+floorstr+''+Int_0+Bool_0+Bool_1+'},\n';
@ -1226,7 +1241,7 @@ var floorstr = '';
if (PosString_0 && PosString_1) {
floorstr = ', "loc": ['+PosString_0+','+PosString_1+']';
}
Int_0 = Int_0 ?(', "time": '+Int_0):'';
Int_0 = Int_0!=='' ?(', "time": '+Int_0):'';
Bool_0 = Bool_0?', "async": true':'';
var code = '{"type": "jumpHero"'+floorstr+Int_0+Bool_0+'},\n';
return code;
@ -1269,6 +1284,32 @@ var code = '{"type": "resumeBgm"},\n';
return code;
*/;
loadBgm_s
: '预加载背景音乐' EvalString Newline
/* loadBgm_s
tooltip : loadBgm: 预加载某个背景音乐,之后可以直接播放
helpUrl : https://h5mota.com/games/template/docs/#/event?id=loadBgm%ef%bc%9a%e9%a2%84%e5%8a%a0%e8%bd%bd%e4%b8%80%e4%b8%aa%e8%83%8c%e6%99%af%e9%9f%b3%e4%b9%90
default : ["bgm.mp3"]
colour : this.soundColor
var code = '{"type": "loadBgm", "name": "'+EvalString_0+'"},\n';
return code;
*/;
freeBgm_s
: '释放背景音乐的缓存' EvalString Newline
/* freeBgm_s
tooltip : freeBgm: 释放背景音乐的缓存
helpUrl : https://h5mota.com/games/template/docs/#/event?id=freeBgm%ef%bc%9a%e9%87%8a%e6%94%be%e4%b8%80%e4%b8%aa%e8%83%8c%e6%99%af%e9%9f%b3%e4%b9%90%e7%9a%84%e7%bc%93%e5%ad%98
default : ["bgm.mp3"]
colour : this.soundColor
var code = '{"type": "freeBgm", "name": "'+EvalString_0+'"},\n';
return code;
*/;
playSound_s
: '播放音效' EvalString Newline
@ -1291,7 +1332,7 @@ tooltip : setVolume: 设置音量
helpUrl : https://h5mota.com/games/template/docs/#/event?id=setvolume%EF%BC%9A%E8%AE%BE%E7%BD%AE%E9%9F%B3%E9%87%8F
default : [90, 500, false]
colour : this.soundColor
Int_1 = Int_1?(', "time": '+Int_1):""
Int_1 = Int_1!==''?(', "time": '+Int_1):""
var async = Bool_0?', "async": true':'';
var code = '{"type": "setVolume", "value": '+Int_0+Int_1+async+'},\n';
return code;
@ -1490,15 +1531,16 @@ return code;
function_s
: '自定义JS脚本' BGNL? Newline RawEvalString Newline BEND Newline
: '自定义JS脚本' '不自动执行下一个事件' Bool BGNL? Newline RawEvalString Newline BEND Newline
/* function_s
tooltip : 可双击多行编辑请勿使用异步代码。常见API参见文档附录。
helpUrl : https://h5mota.com/games/template/docs/#/event?id=function%EF%BC%9A%E8%87%AA%E5%AE%9A%E4%B9%89js%E8%84%9A%E6%9C%AC
default : ["alert(core.getStatus(\"atk\"));"]
default : [false,"alert(core.getStatus(\"atk\"));"]
colour : this.dataColor
var code = '{"type": "function", "function": "function(){\\n'+JSON.stringify(RawEvalString_0).slice(1,-1).split('\\\\n').join('\\n')+'\\n}"},\n';
Bool_0 = Bool_0?', "async": true':'';
var code = '{"type": "function"'+Bool_0+', "function": "function(){\\n'+JSON.stringify(RawEvalString_0).slice(1,-1).split('\\\\n').join('\\n')+'\\n}"},\n';
return code;
*/;
@ -1650,8 +1692,8 @@ Arithmetic_List
;
Weather_List
: '无'|'雨'|'雪'
/*Weather_List ['','rain','snow']*/;
: '无'|'雨'|'雪'|'雾'
/*Weather_List ['','rain','snow','fog']*/;
B_0_List
: '不改变'|'不可通行'|'可以通行'
@ -1666,16 +1708,16 @@ Bg_Fg_List
/*Bg_Fg_List ['bg','fg']*/;
Floor_Meta_List
: '楼层中文名'|'状态栏名称'|'能否使用楼传'|'能否打开快捷商店'|'是否不可浏览地图'|'默认地面ID'|'楼层贴图'|'宝石血瓶效果'|'上楼点坐标'|'下楼点坐标'|'背景音乐'|'画面色调'|'天气和强度'|'是否地下层'
/*Floor_Meta_List ['title','name','canFlyTo', 'canUseQuickShop', 'cannotViewMap', 'defaultGround', 'images', 'item_ratio', 'upFloor', 'downFloor', 'bgm', 'color', 'weather', 'underGround']*/;
: '楼层中文名'|'状态栏名称'|'能否使用楼传'|'能否打开快捷商店'|'是否不可浏览地图'|'是否不可瞬间移动'|'默认地面ID'|'楼层贴图'|'宝石血瓶效果'|'上楼点坐标'|'下楼点坐标'|'背景音乐'|'画面色调'|'天气和强度'|'是否地下层'
/*Floor_Meta_List ['title','name','canFlyTo', 'canUseQuickShop', 'cannotViewMap', 'cannotMoveDirectly', 'defaultGround', 'images', 'item_ratio', 'upFloor', 'downFloor', 'bgm', 'color', 'weather', 'underGround']*/;
Global_Attribute_List
: '全局字体'|'横屏左侧状态栏背景'|'竖屏上方状态栏背景'|'竖屏下方道具栏背景'|'边框颜色'|'状态栏文字色'|'难度显示文字色'|'楼层转换背景'|'楼层转换文字色'
/*Global_Attribute_List ['font','statusLeftBackground','statusTopBackground', 'toolsBackground', 'borderColor', 'statusBarColor', 'hardLabelColor', 'floorChangingBackground', 'floorChangingTextColor']*/;
Global_Value_List
: '血网伤害'|'中毒伤害'|'衰弱效果'|'红宝石效果'|'蓝宝石效果'|'绿宝石效果'|'红血瓶效果'|'蓝血瓶效果'|'黄血瓶效果'|'绿血瓶效果'|'破甲比例'|'反击比例'|'净化比例'|'仇恨增加值'|'行走速度'|'动画时间'
/*Global_Value_List ['lavaDamage','poisonDamage','weakValue', 'redJewel', 'blueJewel', 'greenJewel', 'redPotion', 'bluePotion', 'yellowPotion', 'greenPotion', 'breakArmor', 'counterAttack', 'purify', 'hatred', 'moveSpeed', 'animateSpeed']*/;
: '血网伤害'|'中毒伤害'|'衰弱效果'|'红宝石效果'|'蓝宝石效果'|'绿宝石效果'|'红血瓶效果'|'蓝血瓶效果'|'黄血瓶效果'|'绿血瓶效果'|'破甲比例'|'反击比例'|'净化比例'|'仇恨增加值'|'行走速度'|'动画时间'|'楼层切换时间'
/*Global_Value_List ['lavaDamage','poisonDamage','weakValue', 'redJewel', 'blueJewel', 'greenJewel', 'redPotion', 'bluePotion', 'yellowPotion', 'greenPotion', 'breakArmor', 'counterAttack', 'purify', 'hatred', 'moveSpeed', 'animateSpeed', 'floorChangeTime']*/;
Bool: 'TRUE'
| 'FALSE'
@ -1787,7 +1829,7 @@ ActionParser.prototype.parse = function (obj,type) {
if(typeof(obj)===typeof('')) obj={'data':[obj]};
if(obj instanceof Array) obj={'data':obj};
return MotaActionBlocks['event_m'].xmlText([
obj.trigger==='action',obj.enable,obj.noPass,obj.displayDamage,this.parseList(obj.data)
obj.trigger==='action',obj.enable,obj.noPass,obj.animate,obj.displayDamage,this.parseList(obj.data)
]);
case 'changeFloor':
@ -1817,7 +1859,7 @@ ActionParser.prototype.parse = function (obj,type) {
var text_choices = null;
for(var ii=obj.length-1,choice;choice=obj[ii];ii--) {
text_choices=MotaActionBlocks['levelCase'].xmlText([
MotaActionBlocks['evalString_e'].xmlText([choice.need]),choice.title,this.parseList(choice.action),text_choices]);
MotaActionBlocks['evalString_e'].xmlText([choice.need]),choice.title,choice.clear||false,this.parseList(choice.action),text_choices]);
}
return MotaActionBlocks['level_m'].xmlText([text_choices]);
@ -1901,12 +1943,15 @@ ActionParser.prototype.parseAction = function() {
this.EvalString(data.text),this.next]);
break;
case "autoText": // 自动剧情文本
data.time=this.isset(data.time)?data.time:MotaActionBlocks['autoText_s'].fieldDefault[3];
this.next = MotaActionBlocks['autoText_s'].xmlText([
'','','',data.time,this.EvalString(data.text),this.next]);
break;
case "scrollText":
this.next = MotaActionBlocks['scrollText_s'].xmlText([
data.time, data.async||false, this.EvalString(data.text), this.next]);
break;
case "comment": // 注释
this.next = MotaActionBlocks['comment_s'].xmlText([data.text,this.next]);
this.next = MotaActionBlocks['comment_s'].xmlText([this.EvalString(data.text),this.next]);
break;
case "setText": // 设置剧情文本的属性
var setTextfunc = function(a){return a?JSON.stringify(a).slice(1,-1):null;}
@ -1915,7 +1960,7 @@ ActionParser.prototype.parseAction = function() {
if (!/^\w+\.png$/.test(data.background))
data.background=setTextfunc(data.background);
this.next = MotaActionBlocks['setText_s'].xmlText([
data.position,data.offset,data.title,data.text,data.background,data.bold,data.titlefont,data.textfont,data.time,this.next]);
data.position,data.offset,data.title,data.text,data.background,data.bold,data.titlefont,data.textfont,data.time||0,this.next]);
break;
case "tip":
this.next = MotaActionBlocks['tip_s'].xmlText([
@ -2057,22 +2102,23 @@ ActionParser.prototype.parseAction = function() {
this.next = MotaActionBlocks['vibrate_s'].xmlText([data.time||0, data.async||false, this.next]);
break;
case "showImage": // 显示图片
if(this.isset(data.name)){
this.next = MotaActionBlocks['showImage_0_s'].xmlText([
data.name,data.loc[0],data.loc[1],this.next]);
} else {
this.next = MotaActionBlocks['showImage_1_s'].xmlText([
this.next]);
}
data.loc=data.loc||['','']
this.next = MotaActionBlocks['showImage_s'].xmlText([
data.code,data.image,data.loc[0],data.loc[1],data.dw,data.dh,data.opacity,data.time||0,data.async||false,this.next]);
break;
case "animateImage": // 显示图片
if(data.action == 'show'){
this.next = MotaActionBlocks['animateImage_0_s'].xmlText([
data.name,data.loc[0],data.loc[1],data.time,data.keep||false,data.async||false,this.next]);
} else if (data.action == 'hide') {
this.next = MotaActionBlocks['animateImage_1_s'].xmlText([
data.name,data.loc[0],data.loc[1],data.time,data.keep||false,data.async||false,this.next]);
}
case "hideImage": // 清除图片
this.next = MotaActionBlocks['hideImage_s'].xmlText([
data.code,data.time||0,data.async||false,this.next]);
break;
case "showTextImage": // 显示图片化文本
data.loc=data.loc||['','']
this.next = MotaActionBlocks['showTextImage_s'].xmlText([
this.EvalString(data.text),data.code,data.loc[0],data.loc[1],data.opacity,data.time||0,data.async||false,this.next]);
break;
case "moveImage": // 移动图片
data.to=data.to||['','']
this.next = MotaActionBlocks['moveImage_s'].xmlText([
data.code, data.to[0], data.to[1], data.opacity, data.time||0, data.async||false, this.next]);
break;
case "showGif": // 显示动图
if(this.isset(data.name)){
@ -2083,11 +2129,6 @@ ActionParser.prototype.parseAction = function() {
this.next]);
}
break;
case "moveImage": // 移动图片
this.next = MotaActionBlocks['moveImage_0_s'].xmlText([
data.name, data.from[0], data.from[1], data.to[0], data.to[1], data.time, data.keep||false, data.async||false, this.next
]);
break;
case "setFg": // 颜色渐变
if(this.isset(data.color)){
var alpha = data.color[3];
@ -2144,9 +2185,17 @@ ActionParser.prototype.parseAction = function() {
this.next = MotaActionBlocks['resumeBgm_s'].xmlText([
this.next]);
break
case "loadBgm":
this.next = MotaActionBlocks['loadBgm_s'].xmlText([
data.name,this.next]);
break
case "freeBgm":
this.next = MotaActionBlocks['freeBgm_s'].xmlText([
data.name,this.next]);
break
case "setVolume":
this.next = MotaActionBlocks['setVolume_s'].xmlText([
data.value, data.time, data.async||false, this.next]);
data.value, data.time||0, data.async||false, this.next]);
break
case "setValue":
this.next = MotaActionBlocks['setValue_s'].xmlText([
@ -2225,7 +2274,7 @@ ActionParser.prototype.parseAction = function() {
var func = data["function"];
func=func.split('{').slice(1).join('{').split('}').slice(0,-1).join('}').trim().split('\n').join('\\n');
this.next = MotaActionBlocks['function_s'].xmlText([
func,this.next]);
data.async||false,func,this.next]);
break;
case "update":
this.next = MotaActionBlocks['update_s'].xmlText([
@ -2237,7 +2286,7 @@ ActionParser.prototype.parseAction = function() {
break;
case "hideStatusBar":
this.next = MotaActionBlocks['hideStatusBar_s'].xmlText([
this.next]);
data.toolbox||false,this.next]);
break;
case "updateEnemys":
this.next = MotaActionBlocks['updateEnemys_s'].xmlText([
@ -2245,7 +2294,7 @@ ActionParser.prototype.parseAction = function() {
break;
case "sleep": // 等待多少毫秒
this.next = MotaActionBlocks['sleep_s'].xmlText([
data.time,this.next]);
data.time||0,this.next]);
break;
case "wait": // 等待用户操作
this.next = MotaActionBlocks['wait_s'].xmlText([
@ -2335,7 +2384,7 @@ MotaActionFunctions.IdString_pre = function(IdString){
MotaActionFunctions.PosString_pre = function(PosString){
if (!PosString || /^-?\d+$/.test(PosString)) return PosString;
if (!(/^flag:[0-9a-zA-Z_][0-9a-zA-Z_\-:]*$/.test(PosString)))throw new Error(PosString+'中包含了0-9 a-z A-Z _ - :之外的字符,或者是没有以flag: 开头');
if (!(/^flag:[0-9a-zA-Z_][0-9a-zA-Z_:]*$/.test(PosString)))throw new Error(PosString+'中包含了0-9 a-z A-Z _ :之外的字符,或者是没有以flag: 开头');
return '"'+PosString+'"';
}

View File

@ -261,7 +261,7 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_leaf": true,
"_type": "textarea",
"_range": "thiseval==null||(thiseval instanceof Array)",
"_data": "该图块的不可入方向\n可以在这里定义不能从哪个方向访问该图块,可以达到悬崖之类的效果\n例如 [\"down\", \"right\"] 代表不能从下或右访问此图块\n此值对背景层、事件层、前景层上的图块均有效"
"_data": "该图块的不可入方向\n可以在这里定义不能朝哪个方向进入该图块,可以达到悬崖之类的效果\n例如 [\"down\"] 代表不能从该图块的上方点朝向下进入此图块\n此值对背景层、事件层、前景层上的图块均有效"
},
"faceIds": {
"_leaf": true,
@ -324,6 +324,12 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_bool": "bool",
"_data": "该层是否不允许被浏览地图看到;如果勾上则浏览地图会跳过该层"
},
"cannotMoveDirectly": {
"_leaf": true,
"_type": "checkbox",
"_bool": "bool",
"_data": "该层是否不允许瞬间移动;如果勾上则不可在此层进行瞬移"
},
"firstArrive": {
"_leaf": true,
"_type": "event",
@ -334,7 +340,7 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_leaf": true,
"_type": "event",
"_event": "eachArrive",
"_data": "每次到该楼层触发的事件,可以双击进入事件编辑器;该事件会比firstArrive先执行。"
"_data": "每次到该楼层触发的事件,可以双击进入事件编辑器;该事件会在firstArrive执行后再执行。"
},
"parallelDo": {
"_leaf": true,
@ -376,7 +382,7 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"weather": {
"_leaf": true,
"_type": "textarea",
"_data": "该层的默认天气。本项可忽略表示晴天,如果写则第一项为\"rain\"或\"snow\"代表雨雪第二项为1-10之间的数代表强度。\n如[\"rain\", 8]代表8级雨天。"
"_data": "该层的默认天气。本项可忽略表示晴天,如果写则第一项为\"rain\"\"snow\"或\"fog\"代表雨雪雾第二项为1-10之间的数代表强度。\n如[\"rain\", 8]代表8级雨天。"
},
"bgm": {
"_leaf": true,

View File

@ -392,3 +392,21 @@ table.row td {
[v-cloak] {
display: none !important;
}
#searchBlock {
width: 100px;
background-color: #E9EBF2;
border-radius: 10px;
outline: none;
padding-left: 20px;
height: 14px;
}
.searchLogo {
width: 15px;
height: 15px;
position: absolute;
left: 6px;
top: 6px;
background-image:url('data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGJhc2VQcm9maWxlPSJmdWxsIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxuczpldj0iaHR0cDovL3d3dy53My5vcmcvMjAwMS94bWwtZXZlbnRzIj4KPGc%2BCgk8cG9seWdvbiBmaWxsPSIjNjY2IiBwb2ludHM9IjkuMjA3LDYuMTI2IDcuNzkzLDcuNTQxIDExLjc5MywxMS41NDEgMTMuMjA3LDEwLjEyNiIgLz4KCTxwYXRoIGZpbGw9IiM2NjYiIGQ9Ik01LjkxNywyYzEuNjA4LDAsMi45MTcsMS4zMDgsMi45MTcsMi45MTdTNy41MjUsNy44MzMsNS45MTcsNy44MzNTMyw2LjUyNSwzLDQuOTE3UzQuMzA4LDIsNS45MTcsMgoJCSBNNS45MTcsMEMzLjIwMSwwLDEsMi4yMDEsMSw0LjkxN3MyLjIwMSw0LjkxNyw0LjkxNyw0LjkxN3M0LjkxNy0yLjIwMSw0LjkxNy00LjkxN0MxMC44MzMsMi4yMDEsOC42MzIsMCw1LjkxNywwTDUuOTE3LDB6IiAvPgo8L2c%2BCjwvc3ZnPgo%3D');
}

View File

@ -388,7 +388,12 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"animateSpeed": {
"_leaf": true,
"_type": "textarea",
"_data": "动画时间一般300比较合适"
"_data": "全局动画时间即怪物振动频率一般300比较合适"
},
"floorChangeTime": {
"_leaf": true,
"_type": "textarea",
"_data": "默认楼层切换时间"
}
}
},
@ -522,20 +527,6 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_bool": "bool",
"_data": "状态栏的装备按钮。若此项为true则将状态栏中的楼层转换器按钮换为装备栏按钮"
},
"equipPercentage": {
"_leaf": true,
"_type": "checkbox",
"_bool": "bool",
"_data": "装备增加百分比属性。如果此项为true则装备属性全部按照百分比进行计算比如\"atk\": 20意味着攻击增加20%。\n如果多个装备百分比增加同一个属性的按加算处理。即一个10%一个20%总共是30%而不是32%"
},
/*
"enableDeleteItem": {
"_leaf": true,
"_type": "checkbox",
"_bool": "bool",
"_data": "是否允许删除(丢弃)道具"
},
*/
"enableAddPoint": {
"_leaf": true,
"_type": "checkbox",
@ -566,6 +557,12 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_bool": "bool",
"_data": "是否循环计算临界如果此项为true则使用循环法而不是回合数计算法来算临界"
},
"loopStep": {
"_leaf": true,
"_type": "textbox",
"_range": "thiseval==null || thiseval>0",
"_data": "循环计算临界时,每次攻击增加量为原始攻击的多少分之一。\n例如5000就代表循环中每次攻击增加量是原始攻击的1/5000向上取整。\n默认值5000。"
},
"startUsingCanvas": {
"_leaf": true,
"_type": "checkbox",
@ -578,6 +575,18 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_bool": "bool",
"_data": "点击“开始游戏”后是否立刻开始游戏而不显示难度选择界面"
},
"statusCanvas": {
"_leaf": true,
"_type": "checkbox",
"_bool": "bool",
"_data": "是否状态栏canvas化即手动自定义绘制状态栏。\n如果此项开启则可在脚本编辑的drawStatusBar中自定义绘制菜单栏。"
},
"statusCanvasRowsOnMobile": {
"_leaf": true,
"_type": "textarea",
"_range": "thiseval==null || (thiseval>0 && thiseval<=4)",
"_data": "竖屏模式下顶端状态栏canvas化后的行数。\n此项将决定竖屏的状态栏高度如果设置则不小于1且不大于4。\n仅在statusCanvas开启时才有效"
},
"canOpenBattleAnimate": {
"_leaf": true,
"_type": "checkbox",
@ -655,6 +664,12 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_type": "checkbox",
"_bool": "bool",
"_data": "是否在经过领域/夹击/路障等伤害后禁用快捷商店。"
},
"checkConsole": {
"_leaf": true,
"_type": "checkbox",
"_bool": "bool",
"_data": "是否检查控制台的开启情况。"
}
}
}

View File

@ -197,7 +197,12 @@ editor.prototype.fetchMapFromCore = function(){
var mapArray = core.maps.save(core.status.maps, core.status.floorId);
editor.map = mapArray.map(function (v) {
return v.map(function (v) {
return editor.ids[[editor.indexs[parseInt(v)][0]]]
var x = parseInt(v), y = editor.indexs[x];
if (!core.isset(y)) {
printe("素材数字"+x+"未定义。是不是忘了注册或者接档时没有覆盖icons.js和maps.js");
y = [0];
}
return editor.ids[y[0]]
})
});
editor.currentFloorId = core.status.floorId;
@ -210,7 +215,12 @@ editor.prototype.fetchMapFromCore = function(){
}
editor[name]=mapArray.map(function (v) {
return v.map(function (v) {
return editor.ids[[editor.indexs[parseInt(v)][0]]]
var x = parseInt(v), y = editor.indexs[x];
if (!core.isset(y)) {
printe("素材数字"+x+"未定义。是不是忘了注册或者接档时没有覆盖icons.js和maps.js");
y = [0];
}
return editor.ids[y[0]]
})
});
}
@ -225,6 +235,7 @@ editor.prototype.changeFloor = function (floorId, callback) {
});
editor.currentFloorData[name]=mapArray;
}
editor.preMapData = null;
core.changeFloor(floorId, null, {"x": 0, "y": 0, "direction": "up"}, null, function () {
core.bigmap.offsetX=0;
core.bigmap.offsetY=0;
@ -275,12 +286,27 @@ editor.prototype.drawEventBlock = function () {
}
}
editor.prototype.drawPosSelection = function () {
this.drawEventBlock();
var fg=document.getElementById('efg').getContext('2d');
fg.strokeStyle = 'rgba(255,255,255,0.7)';
fg.lineWidth = 4;
fg.strokeRect(32*editor.pos.x - core.bigmap.offsetX + 4, 32*editor.pos.y - core.bigmap.offsetY + 4, 24, 24);
}
editor.prototype.updateMap = function () {
var evs = {};
if (editor.currentFloorData && editor.currentFloorData.events) {
for (var loc in editor.currentFloorData.events) {
if ((editor.currentFloorData.events[loc]||{}).animate == false)
evs[loc] = {"animate": false};
}
}
var blocks = main.editor.mapIntoBlocks(editor.map.map(function (v) {
return v.map(function (v) {
return v.idnum || v || 0
})
}), {'events': {}, 'changeFloor': {}}, editor.currentFloorId);
}), {'events': evs, 'changeFloor': {}}, editor.currentFloorId);
core.status.thisMap.blocks = blocks;
main.editor.updateMap();
@ -327,7 +353,7 @@ editor.prototype.moveViewport=function(x,y){
core.bigmap.offsetY = core.clamp(core.bigmap.offsetY+32*y, 0, 32*core.bigmap.height-416);
core.control.updateViewport();
editor.buildMark();
editor.drawEventBlock();
editor.drawPosSelection();
}
/////////// 通用 ///////////
@ -631,6 +657,15 @@ editor.prototype.listen = function () {
eui.oncontextmenu=function(e){e.preventDefault()}
eui.ondblclick = function(e) {
// 双击地图可以选中素材
var loc = eToLoc(e);
var pos = locToPos(loc,true);
var thisevent = editor.map[pos.y][pos.x];
editor.setSelectBoxFromInfo(thisevent);
return;
}
eui.onmousedown = function (e) {
if (e.button==2){
var loc = eToLoc(e);
@ -701,7 +736,7 @@ editor.prototype.listen = function () {
holdingPath = 0;
e.stopPropagation();
if (stepPostfix && stepPostfix.length) {
preMapData = JSON.parse(JSON.stringify({map:editor.map,fgmap:editor.fgmap,bgmap:editor.bgmap}));
editor.preMapData = JSON.parse(JSON.stringify({map:editor.map,fgmap:editor.fgmap,bgmap:editor.bgmap}));
if(editor.brushMod!=='line'){
var x0=stepPostfix[0].x;
var y0=stepPostfix[0].y;
@ -795,7 +830,7 @@ editor.prototype.listen = function () {
}
}
var preMapData = {};
editor.preMapData = null;
var currDrawData = {
pos: [],
info: {}
@ -809,18 +844,18 @@ editor.prototype.listen = function () {
if (e.altKey && [48, 49, 50, 51, 52, 53, 54, 55, 56, 57].indexOf(e.keyCode) !== -1)
e.preventDefault();
//Ctrl+z 撤销上一步undo
if (e.keyCode == 90 && e.ctrlKey && preMapData && currDrawData.pos.length && selectBox.isSelected) {
editor.map = JSON.parse(JSON.stringify(preMapData.map));
editor.fgmap = JSON.parse(JSON.stringify(preMapData.fgmap));
editor.bgmap = JSON.parse(JSON.stringify(preMapData.bgmap));
if (e.keyCode == 90 && e.ctrlKey && editor.preMapData && currDrawData.pos.length && selectBox.isSelected) {
editor.map = JSON.parse(JSON.stringify(editor.preMapData.map));
editor.fgmap = JSON.parse(JSON.stringify(editor.preMapData.fgmap));
editor.bgmap = JSON.parse(JSON.stringify(editor.preMapData.bgmap));
editor.updateMap();
reDo = JSON.parse(JSON.stringify(currDrawData));
currDrawData = {pos: [], info: {}};
preMapData = null;
editor.preMapData = null;
}
//Ctrl+y 重做一步redo
if (e.keyCode == 89 && e.ctrlKey && reDo && reDo.pos.length && selectBox.isSelected) {
preMapData = JSON.parse(JSON.stringify({map:editor.map,fgmap:editor.fgmap,bgmap:editor.bgmap}));
editor.preMapData = JSON.parse(JSON.stringify({map:editor.map,fgmap:editor.fgmap,bgmap:editor.bgmap}));
for (var j = 0; j < reDo.pos.length; j++)
editor.map[reDo.pos[j].y][reDo.pos[j].x] = JSON.parse(JSON.stringify(reDo.info));
@ -863,6 +898,15 @@ editor.prototype.listen = function () {
printf('已保存该快捷图块, ctrl + '+(e.keyCode-48)+' 使用.')
core.setLocalStorage('shortcut',shortcut);
}
// wasd平移大地图
if (e.keyCode==87)
editor.moveViewport(0,-1)
else if (e.keyCode==65)
editor.moveViewport(-1,0)
else if (e.keyCode==83)
editor.moveViewport(0,1);
else if (e.keyCode==68)
editor.moveViewport(1,0);
}
var dataSelection = document.getElementById('dataSelection');
@ -991,7 +1035,7 @@ editor.prototype.listen = function () {
copyLoc.onmousedown = function(e){
editor.hideMidMenu();
e.stopPropagation();
preMapData = null;
editor.preMapData = null;
reDo = null;
editor_mode.onmode('');
var now = editor.pos;
@ -1016,7 +1060,7 @@ editor.prototype.listen = function () {
throw(err)
}
;printf('复制事件成功');
editor.drawEventBlock();
editor.drawPosSelection();
});
}
@ -1024,7 +1068,7 @@ editor.prototype.listen = function () {
moveLoc.onmousedown = function(e){
editor.hideMidMenu();
e.stopPropagation();
preMapData = null;
editor.preMapData = null;
reDo = null;
var thisevent = editor.map[editor.pos.y][editor.pos.x];
if(thisevent==0){
@ -1054,7 +1098,7 @@ editor.prototype.listen = function () {
fields.forEach(function(v){
var temp_atsfcytaf=editor.currentFloorData[v][now.x+','+now.y];
editor.currentFloorData[v][now.x+','+now.y]=editor.currentFloorData[v][last.x+','+last.y];
editor.currentFloorData[v][last.x+','+last.y]=temp_atsfcytaf
editor.currentFloorData[v][last.x+','+last.y]=temp_atsfcytaf;
})
editor.file.saveFloorFile(function (err) {
if (err) {
@ -1062,7 +1106,7 @@ editor.prototype.listen = function () {
throw(err)
}
;printf('两位置的事件已互换');
editor.drawEventBlock();
editor.drawPosSelection();
});
}
@ -1070,7 +1114,7 @@ editor.prototype.listen = function () {
clearLoc.onmousedown = function(e){
editor.hideMidMenu();
e.stopPropagation();
preMapData = null;
editor.preMapData = null;
reDo = null;
editor.info = 0;
editor_mode.onmode('');
@ -1078,7 +1122,7 @@ editor.prototype.listen = function () {
editor.map[now.y][now.x]=editor.info;
editor.updateMap();
fields.forEach(function(v){
editor.currentFloorData[v][now.x+','+now.y]=null;
delete editor.currentFloorData[v][now.x+','+now.y];
})
editor.file.saveFloorFile(function (err) {
if (err) {
@ -1086,7 +1130,7 @@ editor.prototype.listen = function () {
throw(err)
}
;printf('清空此点及事件成功');
editor.drawEventBlock();
editor.drawPosSelection();
});
}

View File

@ -4,12 +4,13 @@ editor_blockly = function () {
initscript = String.raw`
(function(){
var getCategory = function(name){
var getCategory = function(name,custom){
for(var node of document.getElementById('toolbox').children) {
if(node.getAttribute('name')==name) return node;
}
var node = document.createElement('category');
node.setAttribute('name',name);
if(custom)node.setAttribute('custom',custom);
document.getElementById('toolbox').appendChild(node);
return node;
}
@ -60,14 +61,14 @@ editor_blockly = function () {
MotaActionBlocks['text_1_s'].xmlText(),
MotaActionBlocks['comment_s'].xmlText(),
MotaActionBlocks['autoText_s'].xmlText(),
MotaActionBlocks['scrollText_s'].xmlText(),
MotaActionBlocks['setText_s'].xmlText(),
MotaActionBlocks['showImage_0_s'].xmlText(),
MotaActionBlocks['animateImage_0_s'].xmlText(),
MotaActionBlocks['animateImage_1_s'].xmlText(),
MotaActionBlocks['showImage_1_s'].xmlText(),
MotaActionBlocks['showImage_s'].xmlText(),
MotaActionBlocks['hideImage_s'].xmlText(),
MotaActionBlocks['showTextImage_s'].xmlText(),
MotaActionBlocks['moveImage_s'].xmlText(),
MotaActionBlocks['showGif_0_s'].xmlText(),
MotaActionBlocks['showGif_1_s'].xmlText(),
MotaActionBlocks['moveImage_0_s'].xmlText(),
MotaActionBlocks['tip_s'].xmlText(),
MotaActionBlocks['win_s'].xmlText(),
MotaActionBlocks['lose_s'].xmlText(),
@ -143,6 +144,8 @@ editor_blockly = function () {
MotaActionBlocks['playBgm_s'].xmlText(),
MotaActionBlocks['pauseBgm_s'].xmlText(),
MotaActionBlocks['resumeBgm_s'].xmlText(),
MotaActionBlocks['loadBgm_s'].xmlText(),
MotaActionBlocks['freeBgm_s'].xmlText(),
MotaActionBlocks['playSound_s'].xmlText(),
MotaActionBlocks['setVolume_s'].xmlText(),
],
@ -242,15 +245,19 @@ editor_blockly = function () {
}
]
},'event'),
],
'最近使用事件':[
'<label text="此处只是占位符,实际定义在editor_blockly.searchBlockCategoryCallback中"></label>',
]
}
var toolboxgap = '<sep gap="5"></sep>'
//xml_text = MotaActionFunctions.actionParser.parse(obj,type||'event')
//MotaActionBlocks['idString_e'].xmlText()
for (var name in toolboxObj){
getCategory(name).innerHTML = toolboxObj[name].join(toolboxgap);
var custom = null;
if(name=='最近使用事件')custom='searchBlockCategory';
getCategory(name,custom).innerHTML = toolboxObj[name].join(toolboxgap);
}
var blocklyArea = document.getElementById('blocklyArea');
@ -268,6 +275,23 @@ var workspace = Blockly.inject(blocklyDiv,{
},
trashcan: false,
});
editor_blockly.searchBlockCategoryCallback = function(workspace) {
var xmlList = [];
var labels = editor_blockly.searchBlock();
for (var i = 0; i < labels.length; i++) {
var blockText = '<xml>' +
MotaActionBlocks[labels[i]].xmlText() +
'</xml>';
var block = Blockly.Xml.textToDom(blockText).firstChild;
block.setAttribute("gap", 5);
xmlList.push(block);
}
return xmlList;
};
workspace.registerToolboxCategoryCallback(
'searchBlockCategory', editor_blockly.searchBlockCategoryCallback);
var onresize = function(e) {
blocklyDiv.style.width = blocklyArea.offsetWidth + 'px';
@ -288,8 +312,11 @@ document.getElementById('blocklyDiv').onmousewheel = function(e){
workspace.setScale(workspace.scale);
}
var doubleClickCheck=[[0,'abc']];
function omitedcheckUpdateFunction(event) {
var doubleClickCheck=[[0,'abc']];
function omitedcheckUpdateFunction(event) {
if(event.type==='create'){
editor_blockly.addIntoLastUsedType(event.blockId);
}
if(event.type==='ui'){
var newClick = [new Date().getTime(),event.blockId];
var lastClick = doubleClickCheck.shift();
@ -407,7 +434,7 @@ document.getElementById('blocklyDiv').onmousewheel = function(e){
MotaActionFunctions.parse(
eval('obj=' + codeAreaHL.getValue().replace(/[<>&]/g, function (c) {
return {'<': '&lt;', '>': '&gt;', '&': '&amp;'}[c];
})),
}).replace(/\\r/g, '\\\\r').replace(/\\f/g, '\\\\f')),
document.getElementById('entryType').value
);
}
@ -422,7 +449,7 @@ document.getElementById('blocklyDiv').onmousewheel = function(e){
var type = args.type;
if (!type) return false;
editor_blockly.id = id_;
codeAreaHL.setValue(input.value.replace(/\\r/g,'\\\\r').replace(/\\f/,'\\\\f'));
codeAreaHL.setValue(input.value);
document.getElementById('entryType').value = type;
editor_blockly.parse();
editor_blockly.show();
@ -492,8 +519,10 @@ document.getElementById('blocklyDiv').onmousewheel = function(e){
'text_0_s': 'EvalString_0',
'text_1_s': 'EvalString_2',
'autoText_s': 'EvalString_2',
'scrollText_s': 'EvalString_0',
'comment_s': 'EvalString_0',
'choices_s': 'EvalString_0',
'showTextImage_s': 'EvalString_0',
'function_s': 'RawEvalString_0',
'shopsub': 'EvalString_3',
}
@ -509,6 +538,97 @@ document.getElementById('blocklyDiv').onmousewheel = function(e){
}
}
editor_blockly.lastUsedType=[
'text_0_s',
'comment_s',
'show_s',
'hide_s',
'setValue_s',
'if_s',
'battle_s',
'openDoor_s',
'choices_s',
'setText_s',
'exit_s',
'revisit_s',
'sleep_s',
'setBlock_s'
]; // 最常用的15个图块
editor_blockly.lastUsedTypeNum=15;
editor_blockly.addIntoLastUsedType=function(blockId) {
var b = editor_blockly.workspace.getBlockById(blockId);
if(!b)return;
var blockType = b.type;
if(!blockType || blockType.indexOf("_s")!==blockType.length-2 || blockType==='pass_s')return;
editor_blockly.lastUsedType = editor_blockly.lastUsedType.filter(function (v) {return v!==blockType;});
if (editor_blockly.lastUsedType.length >= editor_blockly.lastUsedTypeNum)
editor_blockly.lastUsedType.pop();
editor_blockly.lastUsedType.unshift(blockType);
document.getElementById("searchBlock").value='';
}
// Index from 1 - 9
editor_blockly.openToolbox = function(index) {
// var element = document.getElementById(':'+index);
// if (element == null || element.getAttribute("aria-selected")=="true") return;
// element.click();
editor_blockly.workspace.toolbox_.tree_.setSelectedItem(editor_blockly.workspace.toolbox_.tree_.children_[index-1]);
}
editor_blockly.reopenToolbox = function(index) {
// var element = document.getElementById(':'+index);
// if (element == null) return;
// if (element.getAttribute("aria-selected")=="true") element.click();
// element.click();
editor_blockly.workspace.toolbox_.tree_.setSelectedItem(editor_blockly.workspace.toolbox_.tree_.children_[index-1]);
editor_blockly.workspace.getFlyout_().show(editor_blockly.workspace.toolbox_.tree_.children_[index-1].blocks);
}
editor_blockly.closeToolbox = function() {
/*
for (var i=1; i<=10; i++) {
var element = document.getElementById(':'+i);
if (element && element.getAttribute("aria-selected")=="true") {
element.click();
return;
}
}
*/
editor_blockly.workspace.toolbox_.clearSelection();
}
var searchInput = document.getElementById("searchBlock");
searchInput.onfocus = function () {
editor_blockly.reopenToolbox(9);
}
searchInput.oninput = function () {
editor_blockly.reopenToolbox(9);
}
editor_blockly.searchBlock = function (value) {
if (value == null) value = searchInput.value;
value = value.toLowerCase();
if (value == '') return editor_blockly.lastUsedType;
var results = [];
for (var name in MotaActionBlocks) {
if (typeof name !== 'string' || name.indexOf("_s") !== name.length-2) continue;
var block = MotaActionBlocks[name];
if(block && block.json) {
if ((block.json.type||"").toLowerCase().indexOf(value)>=0
|| (block.json.message0||"").toLowerCase().indexOf(value)>=0
|| (block.json.tooltip||"").toLowerCase().indexOf(value)>=0) {
results.push(name);
if (results.length>=editor_blockly.lastUsedTypeNum)
break;
}
}
}
return results.length == 0 ? editor_blockly.lastUsedType : results;
}
return editor_blockly;
}
//editor_blockly=editor_blockly();

View File

@ -147,6 +147,7 @@ editor_file = function (editor, callback) {
canFlyTo: saveStatus?currData.canFlyTo:true,
canUseQuickShop: saveStatus?currData.canUseQuickShop:true,
cannotViewMap: saveStatus?currData.cannotViewMap:false,
cannotMoveDirectly: saveStatus?currData.cannotMoveDirectly:false,
images: [],
item_ratio: saveStatus?currData.item_ratio:1,
defaultGround: saveStatus?currData.defaultGround:"ground",
@ -901,7 +902,11 @@ editor_file = function (editor, callback) {
}
if (file == 'floors') {
actionList.forEach(function (value) {
eval("editor.currentFloorData" + value[1] + '=' + JSON.stringify(value[2]));
// 检测null/undefined
if (core.isset(value[2]))
eval("editor.currentFloorData" + value[1] + '=' + JSON.stringify(value[2]));
else
eval("delete editor.currentFloorData"+value[1]);
});
editor_file.saveFloorFile(callback);
return;

View File

@ -206,7 +206,7 @@ editor_mode = function (editor) {
throw(objs_.slice(-1)[0])
}
;printf('修改成功');
editor.drawEventBlock();
editor.drawPosSelection();
});
break;
case 'enemyitem':
@ -286,6 +286,8 @@ editor_mode = function (editor) {
editor_mode.dom[name].style = 'z-index:-1;opacity: 0;';
}
editor_mode.dom[mode].style = '';
// clear
editor.drawEventBlock();
if (editor_mode[mode]) editor_mode[mode]();
document.getElementById('editModeSelect').value = mode;
var tips = tip_in_showMode;
@ -307,7 +309,7 @@ editor_mode = function (editor) {
var tableinfo = editor_mode.objToTable_(objs[0], objs[1]);
document.getElementById('table_3d846fc4_7644_44d1_aa04_433d266a73df').innerHTML = tableinfo.HTML;
tableinfo.listen(tableinfo.guids);
editor.drawPosSelection();
if (Boolean(callback)) callback();
}
@ -585,15 +587,16 @@ editor_mode = function (editor) {
tempCanvas.imageSmoothingEnabled = false;
tempCanvas.drawImage(image, 0, 0);
var imgData = tempCanvas.getImageData(0, 0, image.width, image.height);
var trans = 0, white = 0;
var trans = 0, white = 0, black=0;
for (var i=0;i<image.width;i++) {
for (var j=0;j<image.height;j++) {
var pixel = getPixel(imgData, i, j);
if (pixel[3]==0) trans++;
if (pixel[0]==255 && pixel[1]==255 && pixel[2]==255 && pixel[3]==255) white++;
if (pixel[0]==0 && pixel[1]==0 && pixel[2]==0 && pixel[3]==255) black++;
}
}
if (white>trans*10 && confirm("看起来这张图片是以为底色,是否自动调整为透明底色?")) {
if (white>black && white>trans*10 && confirm("看起来这张图片是以白为底色,是否自动调整为透明底色?")) {
for (var i=0;i<image.width;i++) {
for (var j=0;j<image.height;j++) {
var pixel = getPixel(imgData, i, j);
@ -606,6 +609,19 @@ editor_mode = function (editor) {
tempCanvas.putImageData(imgData, 0, 0);
changed = true;
}
if (black>white && black>trans*10 && confirm("看起来这张图片是以纯黑为底色,是否自动调整为透明底色?")) {
for (var i=0;i<image.width;i++) {
for (var j=0;j<image.height;j++) {
var pixel = getPixel(imgData, i, j);
if (pixel[0]==0 && pixel[1]==0 && pixel[2]==0 && pixel[3]==255) {
setPixel(imgData, i, j, [0,0,0,0]);
}
}
}
tempCanvas.clearRect(0, 0, image.width, image.height);
tempCanvas.putImageData(imgData, 0, 0);
changed = true;
}
// Step 2: 检测长宽比
var ysize = selectAppend.value.indexOf('48') === -1 ? 32 : 48;
@ -649,10 +665,6 @@ editor_mode = function (editor) {
callback(image);
}
image.src = content;
if (image.complete) {
callback(image);
return;
}
}
catch (e) {
printe(e);

View File

@ -162,6 +162,12 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_type": "textarea",
"_lint": true,
"_data": "阻激夹域的伤害值计算"
},
"moveOneStep": {
"_leaf": true,
"_type": "textarea",
"_lint": true,
"_data": "勇士每走一步的操作"
}
}
},
@ -169,6 +175,12 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_leaf": false,
"_type": "object",
"_data": {
"drawStatusBar": {
"_leaf": true,
"_type": "textarea",
"_lint": true,
"_data": "自定义绘制状态栏。\n当状态栏canvas化开启时可以在这里对状态栏进行自定义绘制。\n仅当statusCanvas开启时有效。"
},
"drawStatistics": {
"_leaf": true,
"_type": "textarea",

View File

@ -1,6 +1,6 @@
# V2.0版本介绍
?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} *
目前样板已经更新到V2.0版本以上本章将对V2.0的一些内容进行介绍。

View File

@ -1,6 +1,6 @@
# 附录: API列表
?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} *
**这里只列出所有可能会被造塔者用到的常用API更多的有关内容请在代码内进行查询。**
@ -135,11 +135,15 @@ core.changeFloor('MT5', null, {'x': 3, 'y': 6}, 0) 无动画切换到MT5层的(3
core.resetMap()
重置当前楼层地图。
重置当前楼层地图和楼层属性
当我们修改某一层地图后,进游戏读档,会发现修改的内容并没有被更新上去。
这是因为H5的存档是会存下来每一个楼层的地图的读档会从档里面获得地图信息。
此时,如果我们在某一层地图执行 core.resetMap() ,则可以立刻从剧本中读取并重置当前楼层地图。
已经被修改过的内容也会相应出现。
此函数参数有三种形式:
- 不加任何参数表示重置当前层core.resetMap()
- 加上一个floorId表示重置某一层core.resetMap("MT1")
- 使用一个数组表示重置若干层core.resetMap(["MT1", "MT2", "MT3"])
R
@ -180,12 +184,6 @@ core.trigger(x, y) [异步]
触发某个地点的事件。
core.clearMap(mapName)
清空某个画布图层。
mapName可为'bg', 'event', 'hero', 'event2', 'fg', 'damage', 'animate', 'weather', 'ui', 'data', 'all'之一。
如果mapName为'all',则为清空所有画布;否则只清空对应的画布。
core.drawBlock(block)
重绘某个图块。block应为core.status.thisMap.blocks中的一项。
@ -469,6 +467,86 @@ core.maps.removeBlockByIds(floorId, ids)
ui.js主要用来进行UI窗口的绘制比如对话框、怪物手册、楼传器、存读档界面等等。
core.ui.getContextByName(name)
根据画布名找到一个画布的context支持系统画布和自定义画布。如果不存在画布返回null。
core.clearMap(name)
清空某个画布图层。
name为画布名可以是系统画布之一也可以是任意自定义动态创建的画布名。
如果name也可以是'all'若为all则为清空除色调层外的所有系统画布。
core.ui.fillText(name, text, x, y, style, font)
在某个画布上绘制一段文字。
name为画布名可以是系统画布之一也可以是任意自定义动态创建的画布名。下同
text为要绘制的文本x,y为要绘制的坐标style可选为绘制的样式font可选为绘制的字体。
core.ui.fillBoldText(canvas, text, style, x, y, font)
在某个画布上绘制一个描黑边的文字。
canvas为要绘制的画布的contexttext为文本style为颜色样式x,y坐标font可选为要绘制的字体。
core.ui.fillRect(name, x, y, width, height, style)
绘制一个矩形。style可选为绘制样式。
core.ui.strokeRect(name, x, y, width, height, style)
绘制一个矩形的边框。
core.ui.drawLine(name, x1, y1, x2, y2, style, lineWidth)
绘制一条线。lineWidth可选为线宽。
core.ui.drawArrow(name, x1, y1, x2, y2, style, lineWidth)
绘制一个箭头。
core.ui.setFont(name, font) / core.ui.setLineWidth(name, lineWidth)
设置一个画布的字体/线宽。
core.ui.setAlpha(name, font) / core.ui.setOpacity(name, font)
设置一个画布的绘制不透明度和画布本身的不透明度。
两者区别如下:
- setAlpha是设置"接下来绘制的内容的不透明度"不会对已经绘制的内容产生影响。比如setAlpha('ui', 0.5)则会在接下来的绘制中使用0.5的不透明度。
- setOpacity是设置"画布本身的不透明度"已经绘制的内容也会产生影响。比如我已经在UI层绘制了一段文字再setOpacity则也会看起来变得透明。
尽量不要对系统画布使用setOpacity因为会对已经绘制的内容产生影响自定义创建的画布则不受此限制。
core.ui.setFillStyle(name, style) / core.ui.setStrokeStype(name, style)
设置一个画布的填充样式/描边样式。
core.ui.createCanvas(name, x, y, width, height, zIndex)
动态创建一个画布。name为要创建的画布名如果已存在则会直接取用当前存在的。
x,y为创建的画布相对窗口左上角的像素坐标width,height为创建的长宽。
zIndex为创建的纵向高度关系到画布之间的覆盖z值高的将覆盖z值低的系统画布的z值可在个性化中查看。
创建一个画布后,可以通过 core.dymCanvas[name] 进行调用。
core.ui.findCanvas(name)
寻找一个自定义画布的索引;如果存在该画布则返回对应的索引,不存在画布则返回-1。
core.ui.relocateCanvas(name, x, y)
重新定位一个自定义画布。
core.ui.resizeCanvas(name, x, y)
重新设置一个自定义画布的大小。
core.ui.deleteCanvas(name)
删除一个自定义画布。
core.ui.deleteAllCanvas()
清空所有的自定义画布。
core.ui.drawThumbnail(floorId, canvas, blocks, x, y, size, heroLoc, heroIcon)
绘制一个缩略图,比如楼传器界面,存读档界面等情况。
floorId为目标楼层IDcanvas为要绘制到的图层blocks为要绘制的所有图块。
@ -500,7 +578,7 @@ core.utils.decodeBase64(str)
Base64解密字符串
core.utils.formatBigNumber(x)
core.utils.formatBigNumber(x, onMap)
大数据的格式化

View File

@ -1,6 +1,6 @@
# 元件说明
?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} *
在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。
@ -47,8 +47,9 @@
如果要将一个道具设置为装备,首先需要将其`cls`设为`equips`。
然后在图块属性的`equip`一项中设置装备的具体属性。该项写法如下:
``` js
{"type": 0, "atk": 0, "def": 0, "mdef"0, "animate": "hand"}
{"type": 0, "atk": 0, "def": 0, "mdef"0, "animate": "hand", "percentage": true}
```
type为该装备的类型必填和上面装备栏一一对应。例如0就是武器2就是首饰等等。
@ -57,35 +58,22 @@ atk/def/mdef为该装备分别增加的攻防魔防数值支持负数
animate为该装备的攻击动画仅对type为0时有效。具体可参见[动画和天气系统](#动画和天气系统)。
percentage为该装备是否按比例增加属性。
下面是几个写法例子。
``` js
{"type": 0, "atk": 10} // 装备类型是武器,效果是攻击+10使用默认的攻击动画
{"type": 0, "atk": 40, "animate": "sword"} // 装备类型为武器,效果是攻击+10攻击动画是sword
{"type": 1, "def": 40} // 装备类型是防具,效果是防御+40
{"type": 1, "def": 40, "percentage": true} // 装备类型是防具效果是防御提升40%
{"type": 1, "def": 100, "mdef": 100} // 装备类型是防具,效果是防御和魔防各+100
{"type": 3, "atk": -20, "def": 50, "mdef": 50} // 装备类型是魔杖,效果是攻击-20防御和魔防各+50
```
### 装备按比例增加属性
从V2.4.2开始,装备可以选择按照比例来增加属性。
在全塔属性中有个`equipPercentage`开关如果将其打开则会所有值都按照比例计算。也就是类似Buff一样
例如,上面的例子就变成了:
``` js
{"type": 0, "atk": 10} // 装备类型是武器效果是攻击提升10%,使用默认的攻击动画
{"type": 0, "atk": 40, "animate": "sword"} // 装备类型为武器效果是攻击提升40%攻击动画是sword
{"type": 1, "def": 40} // 装备类型是防具效果是防御提升40%
{"type": 1, "def": 100, "mdef": 100} // 装备类型是防具效果是防御和魔防各提升100%
{"type": 3, "atk": -20, "def": 50, "mdef": 50} // 装备类型是魔杖效果是攻击下降20%防御和魔防各提升50%
{"type": 2, "atk": -20, "def": 50, "mdef": 50, "percentage": true} // 装备类型是魔杖效果是攻击下降20%防御和魔防各提升50%
```
所有取值全部向下取整。
值得注意的是:多装备增加同一属性使用加法计算;也就是比如武器增加30%攻击防具增加10%攻击最终合起来增加的是40%而不是43%的属性。
值得注意的是如果多个装备同时按比例增加属性使用加法计算。比如武器增加30%攻击防具增加10%攻击最终合起来增加的是40%而不是43%的属性。
### 检测是否存在装备
@ -330,7 +318,7 @@ floorId指定的是目标楼层的唯一标识符ID
另外一点是V2.5.2以后,对话框`\b`可以根据文字长度来自动控制文本框宽度,其基本控制原理如下:
- 如果用户存在手动换行`\n`,则选取**最长的一段话**作为文本框宽度。
- 如果用户不存在手动换行,则会将文本框宽度调整为**尽量刚好达到三行**的最佳宽度。
- 如果用户不存在手动换行,则会将文本框宽度调整为X行半的最佳宽度。
- 文本框宽度存在上下界,最终宽度一定会控制在该范围内。
该自动调整仅对`\b`的对话框效果有效。非对话框仍然会绘制整个界面的宽度。
@ -373,7 +361,7 @@ floorId指定的是目标楼层的唯一标识符ID
在每层楼的剧本文件里存在一个weather选项表示该层楼的默认天气。
``` js
// 该层的默认天气。本项可忽略表示晴天,如果写则第一项为"rain"或"snow"代表雨雪第二项为1-10之间的数代表强度。
// 该层的默认天气。本项可忽略表示晴天,如果写则第一项为"rain""snow"或"fog"代表雨雪雾第二项为1-10之间的数代表强度。
"weather": ["snow",5]
```
@ -414,6 +402,14 @@ floorId指定的是目标楼层的唯一标识符ID
!> iOS平台以及部分浏览器不支持获得当前网络状态此时即使在使用Wifi也必须要用户点击“音乐开关”才能播放音乐。
从V2.5.3开始,可以使用`loadBgm`事件来预加载一个bgm这样到播放时无需等待直接播放。
同时BGM将使用LRU算法增加缓存机制。默认最多缓存4个BGM在core.js的musicStatus.cachedBgmCount控制
系统会自动释放最久未使用的BGM。
也可以使用`freeBgm`事件来手动释放一个无需再用的bgm。
## 录像
HTML5魔塔一大亮点就是存在录像系统可以很方便进行录像回放。

View File

@ -1,6 +1,6 @@
# 事件
?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} *
本章内将对样板所支持的事件进行介绍。
@ -316,15 +316,35 @@ time为可选项代表该自动文本的时间。可以不指定不指定
!> 由于用户无法跳过自动剧情文本,因此对于大段剧情文本请自行添加“是否跳过剧情”的提示,否则可能会非常不友好。
### scrollText滚动剧情文本
使用`{"type": "scrollText"}`可以使用滚动剧情文本,即将一段文字从屏幕最下方滚动到屏幕最上方。
``` js
"x,y": [ // 实际执行的事件列表
{"type": "scrollText", "text": "第一排\n第二牌\n\n空行后的一排", "time": 5000, "async": true},
]
```
text为正文文本内容。可以使用`${ }`来计算表达式的值,且使用`\n`手动换行。系统不会对滚动剧情文本进行自动换行。
time为可选项代表总的滚动时间。默认为5000毫秒。
async可选如果为true则会异步执行即不等待当前事件执行完毕立刻执行下一个事件
可以使用下面的[设置剧情文本的属性](event#setText设置剧情文本的属性)来对文字颜色、文字大小、粗体、距离左边的偏移量进行设置。
!> 滚动剧情文本会绘制在UI层和对话框冲突如果是异步处理请注意不要和对话框混用。
### setText设置剧情文本的属性
使用`{"type": "setText"}`可以设置剧情文本的各项属性。
``` js
"x,y": [ // 实际执行的事件列表
{"type": "setText", "title": [255,0,0], "text": [255,255,0], "background": [0,0,255,0.3]},
{"type": "setText", "position": "up", "bold": true, "titlefont": 26, "textfont": 17, "time": 70},
"这段话将显示在上方标题为红色正文为黄色粗体背景为透明度0.3的蓝色标题26px正文17px70毫秒速度打字机效果",
{"type": "setText", "title": [255,0,0], "text": [255,255,0], "background": [0,0,255,0.3], "time": 70},
{"type": "setText", "position": "up", "offset": 15, "bold": true, "titlefont": 26, "textfont": 17},
"这段话将显示在上方距离顶端15像素标题为红色正文为黄色粗体背景为透明度0.3的蓝色标题26px正文17px70毫秒速度打字机效果",
{"type": "setText", "background": "winskin.png"} // 还可以一张使用WindowSkin作为皮肤。
]
```
@ -339,6 +359,8 @@ V2.5.2以后background也可以为一个WindowSkin的文件名。详见[剧
position为可选项表示设置文字显示位置。只能为upcenter和down三者。 默认值: `center`
offset为可选项如果设置则为代表距离如果显示位置是上/下的话,距离顶端/底端的像素值。也作为滚动剧情文本时距离左边的像素值。
bold为可选项如果设置则为true或false表示正文是否使用粗体。 默认值:`false`
titlefont为可选项表示标题字体大小px为单位。默认值`22`
@ -419,7 +441,7 @@ value是一个表达式将通过这个表达式计算出的结果赋值给nam
]
```
name为必填项代表要修改的楼层属性。其和楼层属性中一一对应目前只能为`"title", "name", "canFlyTo", "canUseQuickShop", "cannotViewMap", "color", "weather",
name为必填项代表要修改的楼层属性。其和楼层属性中一一对应目前只能为`"title", "name", "canFlyTo", "canUseQuickShop", "cannotViewMap", "cannotMoveDirectly", "color", "weather",
"defaultGround", "images", "item_ratio", "upFloor", "bgm", "downFloor", "underGround"`。
floorId为可选项代表要修改的楼层ID可以省略代表当前楼层。
@ -728,7 +750,7 @@ name是可选的代表目标行走图的文件名。
使用`{"type": "hideStatusBar"}`可以隐藏状态栏。读档或重新开始游戏时,状态栏会重新显示。
隐藏状态栏的状态下,将无法点击工具栏里面的按钮(如存读档怪物手册等)。建议仅在事件中使用,事件结束前显示
可以添加`"toolbox": true`来不隐藏竖屏模式下的工具栏
### showStatusBar显示状态栏
@ -901,7 +923,7 @@ async可选如果为true则会异步执行即不等待当前事件执行
]
```
name为动画名**请确保动画在main.js中的this.animates中被定义过。**
name为动画名**请确保动画在全塔属性中的animates中被定义过。**
loc为动画的位置可以是`[x,y]`表示在(x,y)点显示,也可以是字符串`"hero"`表示在勇士点显示。
@ -917,48 +939,66 @@ loc可忽略如果忽略则显示为事件当前点。
``` js
"x,y": [ // 实际执行的事件列表
{"type": "showImage", "name": "bg.jpg", "loc": [231,297]}, // 在(231,297)显示bg.jpg
{"type": "showImage", "name": "1.png", "loc": [109,167]}, // 在(109,167)显示1.png
{"type": "showImage"} // 如果不指定name则清除所有图片。
{"type": "showImage", "code": 1, "image": "bg.jpg", "loc": [231,297], "dw": 100, "dy" : 100, "opacity": 1, "time" : 0}, // 在(231,297)显示bg.jpg
{"type": "showImage", "code": 12, "image": "1.png", "loc": [209,267], "dw": 100, "dy" : 100, "opacity": 0.5, "time" : 1000}, // 在(209,267)渐变显示1.png渐变时间为1000毫秒完成时不透明度为0.5,这张图片将遮盖上一张
{"type": "showImage", "code": 8, "image": "hero.png", "loc": [349,367], "dw": 50, "dy" : 50, "opacity": 1, "time" : 500, "async": true}, // 在(209,267)渐变显示hero.png大小为原图片的一半渐变时间为500毫秒异步执行这张图片将被上一张遮盖
]
```
name为图片名。**请确保图片在data.js中的images中被定义过。**
code为图片编号如果两张图片重叠编号较大会覆盖编号较小的。该值需要在1~50之间。
image为图片名。**请确保图片在全塔属性中的images中被定义过。**
loc为图片左上角坐标以像素为单位进行计算。
如果不指定name则清除所有显示的图片
dw和dh为图片的横向、纵向放大率默认值为100即不进行缩放
调用show/hide/move/animate等几个事件同样会清除所有显示的图片
opacity为图片不透明度在0~1之间默认值为1即不透明
### animateImage图片淡入淡出
我们还可以使用 `{"type": "animateImage"}` 来造成显示图片的淡入淡出效果。
``` js
"x,y": [ // 实际执行的事件列表
{"type": "animateImage", "action": "show", "name": "bg.jpg", "loc": [231,297], "time": 500, "keep": true}, // 在(231,297)淡入bg.jpg动画时间500ms
{"type": "animateImage", "action": "hide", "name": "1.png", "loc": [109,167], "time": 300, "async": true}, // 在(109,167)淡出1.png动画时间300ms异步执行
]
```
action为淡入还是淡出`show`为淡入,`hide`会淡出。
name为图片名。**请确保图片在data.js中的images中被定义过。**
loc为图片左上角坐标以像素为单位进行计算。
time为淡入淡出的时间如果是0则忽略此项。
keep可选如果为true则在淡入图片后立刻调用showImage以保留图片在淡出图片前先清除再动画。
time为渐变时间默认值为0即不渐变直接显示。
async可选如果为true则会异步执行即不等待当前事件执行完毕立刻执行下一个事件
如果多张图片的淡入淡出可以采用以下方式(仅供参考):
### showTextImage显示文本化图片
假设我现在已经有了`1.jpg`显示在屏幕上:
- 淡入显示`2.png`:调用`animateImage`淡入图片,然后立刻调用`showImage`显示图片。
- 淡出`1.png`:清除所有图片,`showImage`显示`2.png`,然后调用`animateImage`淡出`1.jpg`
我们可以使用 `{"type": "showTextImage"}` 以图片的方式显示文本。
``` js
"x,y": [ // 实际执行的事件列表
{"type": "showTextImage", "code": 1, "text": "第一排\n第二排\n\n空行后的一排", "loc": [231,297], "opacity": 1, "time" : 0}, // 在(231,297)显示"第一排\n第二排\n\n空行后的一排"
]
```
code为图片编号如果两张图片重叠编号较大会覆盖编号较小的。该值需要在1~50之间。
text为要显示的文本。默认行宽为416。
loc为图片左上角坐标以像素为单位进行计算。
opacity为图片不透明度在0~1之间默认值为1即不透明。
time为渐变时间默认值为0即不渐变直接显示。
async可选如果为true则会异步执行即不等待当前事件执行完毕立刻执行下一个事件
文本通过图片的方式显示后,即视为一张正常图片,可以被清除或者移动。
### hideImage清除图片
我们可以使用 `{"type": "hideImage"}` 来清除一张图片。
``` js
"x,y": [ // 实际执行的事件列表
{"type": "hideImage", "code": 1, "time" : 0}, // 使1号图片消失
{"type": "hideImage", "code": 12, "time" : 1000}, // 使12号图片渐变消失时间为1000毫秒
]
```
time为渐变时间默认值为0即不渐变直接消除。
code为显示图片时输入的图片编号。
async可选如果为true则会异步执行即不等待当前事件执行完毕立刻执行下一个事件
### showGif显示动图
@ -971,7 +1011,7 @@ async可选如果为true则会异步执行即不等待当前事件执行
]
```
name为图片名。**请确保图片在data.js中的images中被定义过。**
name为图片名。**请确保图片在全塔属性中的images中被定义过。**
loc为动图左上角坐标以像素为单位进行计算。
@ -979,24 +1019,24 @@ loc为动图左上角坐标以像素为单位进行计算。
### moveImage图片移动
我们可以使用 `{"type": "moveImage"}` 来造成图片移动效果。
我们可以使用 `{"type": "moveImage"}` 来造成图片移动,淡入淡出等效果。
``` js
"x,y": [ // 实际执行的事件列表
{"type": "moveImage", "name": "bg.jpg", "from": [231,297], "to": [22,333], "time": 500, "keep": true, "async": true},
{"type": "moveImage", "code": 1, "to": [22,333], "opacity": 1, "time": 1000}, // 将1号图片移动到(22,333)动画时间为1000ms
{"type": "moveImage", "code": 12, "opacity": 0.5, "time": 500}, // 将二号图片的透明度变为0.5动画时间500ms
{"type": "moveImage", "code": 1, "to": [109,167], "opacity": 0, "time": 300, "async": true}, // 将1号图片移动到(109,167)透明度设为0不可见动画时间300ms异步执行
]
```
name为图片名。**请确保图片在data.js中的images中被定义过。**
code为图片编号。该值需要在1~50之间。
from为起点图片左上角坐标,以像素为单位进行计算。
to为终点图片左上角坐标,以像素为单位进行计算,不填写则视为当前图片位置
to为终点图片左上角坐标以像素为单位进行计算
opacity为完成时图片不透明度移动过程中逐渐变化。在0~1之间
time为总移动的时间。
keep可选如果为true则在移动结束后立刻调用showImage以保留图片。
async可选如果为true则会异步执行即不等待当前事件执行完毕立刻执行下一个事件
### setFg更改画面色调
@ -1035,6 +1075,8 @@ async可选如果为true则会异步执行即不等待当前事件执行
name为天气选项。目前只支持`rain`和`snow`,即雨天和雪天。
从V2.5.3开始,也支持雾天`fog`。
level为天气的强度等级在1-10之间。1级为最弱10级为最强。
如果想改回晴天则直接不加任何参数。
@ -1175,6 +1217,20 @@ async可选如果为true则会异步执行即不等待当前事件执行
使用`{"type": "resumeBgm"}`可以恢复背景音乐的播放。
### loadBgm预加载一个背景音乐
使用loadBgm可以预加载一个背景音乐。
使用方法:`{"type": "loadBgm", "name": "bgm.mp3"}`
有关BGM播放的详细说明参见[背景音乐](element#背景音乐)
### freeBgm释放一个背景音乐的缓存
使用freeBgm可以预加载一个背景音乐。
使用方法:`{"type": "freeBgm", "name": "bgm.mp3"}`
### playSound播放音效
使用playSound可以立刻播放一个音效。
@ -1610,6 +1666,8 @@ core.insertAction([
// 请勿直接调用 core.changeFloor(toFloor, ...),这个代码是异步的,会导致事件处理和录像出问题!
```
!> 从V2.5.3开始,提供了一个"不自动执行下一个事件"的选项(`"async": true`)。如果设置了此项,那么在该部分代码执行完毕后,不会立刻执行下一个事件。你需要在脚本中手动调用`core.events.doAction()`来执行下一个事件。可以通过此项来实现一些异步的代码,即在异步函数的回调中再执行下一个事件。使用此选项请谨慎,最好向开发者寻求咨询。
## 同一个点的多事件处理
我们可以发现,就目前而且,每个点的事件是和该点进行绑定,并以该点坐标作为唯一索引来查询。
@ -1825,8 +1883,8 @@ if (core.getFlag("door",0)==2) {
{"text": "攻击+4", "effect": "status:atk+=4"},
{"text": "防御+4", "effect": "status:def+=4"},
{"text": "魔防+10", "effect": "status:mdef+=10"}
// effect只能对status和item进行操作不能修改flag值
// 必须是X+=Y的形式其中Y可以是一个表达式以status:xxx或item:xxx为参数
// effect可以对statusitem和flag进行操作
// 必须是X+=Y的形式其中Y可以是一个表达式以status:xxx, item:xxx或flag:xxx为参数
// 其他effect样例
// "item:yellowKey+=1" 黄钥匙+1
// "item:pickaxe+=3" 破墙镐+3
@ -1868,7 +1926,7 @@ if (core.getFlag("door",0)==2) {
- text 为商店所说的话。可以用${need}表示需要的数值。
- choices 为商店的各个选项是一个list每一项是一个选项
- text为显示文字。请注意这里不支持 ${} 的表达式计算。
- effect 为该选项的效果effect只能对status或items进行操作且必须是 `status:xxx+=yyy``item:xxx+=yyy`的形式。即中间必须是+=符号。
- effect 为该选项的效果effect必须是 `status:xxx+=yyy`, `item:xxx+=yyy`或`flag:xxx+=yyy`的形式。即中间必须是+=符号。
- 如有多个effect例如升级全属性提升使用分号分开参见经验商店的写法。
像这样定义了全局商店后,即可在快捷栏中看到。
@ -2142,6 +2200,7 @@ if (core.getFlag("door",0)==2) {
core.waitHeroToStop(function() {
core.removeGlobalAnimate(0,0,true);
core.clearMap('all'); core.clearMap('curtain'); // 清空全地图
core.deleteAllCanvas();
core.drawText([
"\t[恭喜通关]你的分数是${status:hp}。"
], function () {

View File

@ -1,6 +1,6 @@
# HTML5 魔塔样板说明文档
?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} *
众所周知魔塔的趋势是向移动端发展贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中NekoRPG有着比较大的局限性游戏感较差更是完全没法在iOS上运行。而一些APP的魔塔虽然可用但是必须要下载安装对于Android和iOS还必须开发不同的版本非常麻烦。

View File

@ -1,6 +1,6 @@
# 个性化
?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} *
有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。
@ -8,21 +8,44 @@
HTML5魔塔是使用画布canvas来绘制存在若干个图层它们之间有一个覆盖关系后面的图层将覆盖前面的图层。
所有图层从低往高依次如下:
所有图层从低往高依次如下:(加[B]的代表该层是大地图z-index代表该层的纵向高度
- bg背景层绘制背景图层素材bgmap和背景贴图
- event事件层所有事件道具、墙壁、NPC、怪物等都绘制在这一层进行处理
- hero勇士层主要用来绘制勇士
- event2事件2层本层主要用来绘制48x32的图片素材的上半部分避免和勇士错位
- fg前景层绘制前景图层素材fgmap和前景贴图
- damage显伤层主要用来绘制怪物显伤和领域显伤
- animate动画层主要用来绘制动画。showImage事件绘制的图片也是在这一层。
- weather天气层主要用来绘制天气雨/雪)
- route路线层主要用来绘制勇士的行走路线图也用来绘制图块的淡入/淡出效果,图块的移动等。
- curtain色调层用来控制当前楼层的画面色调
- image图片层主要用来绘制显示图片该层之所以在curtain层上是为了可以在全黑时贴大头像图
- uiUI层用来绘制一切UI窗口如剧情文本、怪物手册、楼传器、系统菜单等等
- data数据层用来绘制一些顶层的或更新比较快的数据如左上角的提示战斗界面中数据的变化等等。
- bg**[B]**背景层绘制背景图层素材bgmap和背景贴图 (z-index: 10)
- event**[B]**事件层所有事件道具、墙壁、NPC、怪物等都绘制在这一层进行处理 (z-index: 30)
- hero勇士层主要用来绘制勇士 (z-index: 40)
- event2**[B]**事件2层本层主要用来绘制48x32的图片素材的上半部分避免和勇士错位 (z-index: 50)
- fg**[B]**前景层绘制前景图层素材fgmap和前景贴图 (z-index: 60)
- damage**[B]**:显伤层;主要用来绘制怪物显伤和领域显伤 (z-index: 65)
- animate动画层主要用来绘制动画。 (z-index: 70)
- weather天气层主要用来绘制天气雨/雪/雾) (z-index: 80)
- route**[B]**:路线层;主要用来绘制勇士的行走路线图。 (z-index: 95)
- curtain色调层用来控制当前楼层的画面色调 (z-index: 100)
- uiUI层用来绘制一切UI窗口如剧情文本、怪物手册、楼传器、系统菜单等等 (z-index: 160)
- data数据层用来绘制一些顶层的或更新比较快的数据如左上角的提示战斗界面中数据的变化等等。 (z-index: 170)
### 动态创建canvas
从V2.5.3开始可以在H5样板中任意动态创建canvas并进行使用。
使用`core.createCanvas(name, x, y, w, h, z)`来动态创建一个画布。
其中name为动态canvas名称x,y,w,h为创建的画布相对窗口左上角的像素坐标和长宽z为画布的纵向高度。
例如:`core.createCanvas('test', 10, 20, 100, 200, 74)` 创建了一个名为test的画布其左上角相对窗口的像素坐标为(10,20)宽100高200纵向高度74在动画层和天气层之间
可以通过 `core.dymCanvas[name]` 来获得该画布的context例如 `core.dymCanvas.test` 就是我们上面创建的画布的context然后进行操作。
也可以简单的使用`core.fillText()`, `core.fillRect()`, `core.strokeRect()`等等对画布进行任意绘制。
``` js
core.fillText('test', '这是一段文字', 10, 30, '#FF0000', '16px Verdana'); // 绘制一段文本
```
使用 `core.deleteCanvas(name)` 删除一个动态创建的画布,例如 `core.deleteCanvas('test')`
`core.deleteAllCanvas()`可以删除所有动态创建的画布,`core.relocateCanvas(name, x, y)`和`core.resizeCanvas(name, x, y)`可以对画布的位置和大小进行改变。
更多详细API请参见[API列表](api)。
## 自定义素材
@ -351,10 +374,11 @@ function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) {
``` js
// 写在获得道具后事件
[
{"type": "setValue", "name": "no_zone", "value": "true"}, // 免疫领域
{"type": "setValue", "name": "no_snipe", "value": "true"}, // 免疫阻击
{"type": "setValue", "name": "no_laser", "value": "true"}, // 免疫激光
{"type": "setValue", "name": "no_betweenAttack", "value": "true"}, // 免疫夹击
// 设置不同的flag可以分别无视对应的阻激夹域效果
{"type": "setValue", "name": "flag:no_zone", "value": "true"}, // 免疫领域
{"type": "setValue", "name": "flag:no_snipe", "value": "true"}, // 免疫阻击
{"type": "setValue", "name": "flag:no_laser", "value": "true"}, // 免疫激光
{"type": "setValue", "name": "flag:no_betweenAttack", "value": "true"}, // 免疫夹击
]
```
4. 如果有更高的需求,例如想让吸血效果变成一半,则还是在上面这些地方进行对应的修改即可。
@ -620,7 +644,7 @@ this.statusBar = {
},
'icons': {
// ...其他略
'speed': 24, // 图标的定义这里对应的是icons.png中的索引
'speed': 37, // 图标的定义这里对应的是icons.png中的索引
},
// ...其他略
'speed': document.getElementById('speed'), // 显示内容(数据)的定义
@ -778,6 +802,65 @@ if (core.flags.enableSkill) {
通过上述这几种方式我们就能成功的让H5支持技能啦
## 成就系统
我们还可以给HTML5魔塔增加成就系统。注意到成就是和游戏相关因此需要使用getLocalStorage而不是getFlag判定。
可将下面的代码粘贴到脚本编辑 - 插件编写中。
``` js
// 所有成就项的定义
this.achievements = [
// 每行一个分别定义flag、名称、描述、是否存在提示、成就点数
{"flag": "a1", "name": "成就1", "text": "成就1的达成描述", "hint": false, "point": 1},
// 可以继续往后新增其他的。
];
// 达成成就;如 core.plugin.achieve("a1") 即达成a1对应的成就
this.achieve = function (flag) {
// 获得已达成的成就如果跟存档而不是跟游戏则改成getFlag
var achieved = core.getLocalStorage("achievements", []);
var point = core.getLocalStorage("achievePoint", 0);
// 已经获得该成就
if (achieved.indexOf(flag)>=0) return;
// 尝试达成成就;找到对应的成就项
this.achievements.forEach(function (one) {
if (one.flag == flag) {
// 执行达成成就的操作;也可以自行在上面加上达成成就后的事件
core.insertAction("\t[达成成就:"+one.name+"]"+one.text);
point += one.point || 0;
}
});
achieved.push(flag);
// 存入localStorage中如果跟存档走则使用setFlag
core.setLocalStorage("achievements", achieved);
core.setLocalStorage("achievePoint", point);
}
// 获得所有成就说明这里简单使用两个insertAction你也可以修改成自己的实现
// 简单一点的可以使用insertAction+剧情文本稍微复杂一点的可以使用图片化文本等更复杂的可以自绘UI。
this.getAchievements = function () {
var achieved = core.getLocalStorage("achievements", []);
var yes = [], no = [];
// 对所有成就进行遍历
this.achievements.forEach(function (one) {
// 检测是否达成
if (achieved.indexOf(one.flag)>=0) {
yes.push(one.name+""+one.text);
}
else {
no.push(one.name+""+(one.hint?one.text:"达成条件请自行探索"));
}
});
core.insertAction([
"\t[已达成的成就]"+(yes.length==0?"暂无":yes.join("\n")),
"\t[尚未达成的成就]"+(no.length==0?"暂无":no.join("\n"))
]);
}
```
## 多角色的支持
其实,我们的样板还能支持多角色的制作。比如《黑·白·间》之类的塔也是完全可以刻的。
@ -786,7 +869,7 @@ if (core.flags.enableSkill) {
1. 每个角色弄一张行走图。相关信息参见[自定义事件setHeroIcon](event#setHeroIcon更改角色行走图)。
2. [覆盖楼传事件](#覆盖楼传事件),这样可以通过点工具栏的楼层传送按钮来切换角色。当然你也完全可以自己写一个道具,或[自定义快捷键](#自定义快捷键)来进行绑定。
3. 将下述代码直接贴入脚本编辑 - 插件编写中。(写在`var _useEquipment = ...`之前。)
3. 将下述代码直接贴入脚本编辑 - 插件编写中。
``` js
// 所有需要保存的内容;这些保存的内容不会多角色共用,在切换时会进行恢复。
// 你也可以自行新增或删除,比如不共用金币则可以加上"money"的初始化,不共用道具则可以加上"items"的初始化,
@ -854,38 +937,31 @@ if (core.flags.enableSkill) {
3. 在脚本编辑 - setInitData中加上`core.plugin.initHeros()`来初始化新勇士。(写在`core.events.afterLoadData()`后,反大括号之前。)
4. 如果需要切换角色包括事件、道具或者快捷键等可以直接调用自定义JS脚本`core.plugin.changeHero();`进行切换。也可以指定参数调用`core.plugin.changeHero(1)`来切换到某个具体的勇士上。
## 根据难度分歧来自定义地图
## 系统使用的flag变量
遗憾的是所有地图数据必须在剧本的map中指定换句话说我们无法在游戏进行中动态修改地图比如为简单难度增加一个血瓶
众所周知自定义flag变量都可以任意定义并取用未定义直接取用的flag默认值为0
幸运的是,我们可以采用如下方式进行难度分歧,为用户简单难度下增加额外的血瓶或宝石。
下面是一些可能会被系统设置或取用的flag变量
``` js
"firstArrive": [ // 第一次到该楼层触发的事件
{"type": "if", "condition": "flag:hard!=3", // 判断是否困难难度
"true": [ // 不为困难,则为普通或简单难度
{"type": "show", "loc": [3,6]} // 显示血瓶
{"type": "if", "condition": "flag:hard==1", // 判断是否是简单难度
"true": [
{"type": "show", "loc": [3,7]} // 简单难度则显示宝石
],
"false": [] // 普通难度则只显示血瓶
},
],
"false": [] // 困难难度,不进行任何操作
},
],
"events": {
"3,6": {"enable": false} // 比如[3,6]点是一个血瓶,初始不可见
"3,7": {"enable": false} // 比如[3,7]点是一个宝石,初始不可见
}
```
如上所示,我们在地图上设置一个额外的血瓶和宝石,并初始时设为禁用状态。
当第一次到达该楼层时,进行一次判断;如果不为困难难度,则将血瓶显示出来;再判断是否为简单难度,如果是则再把宝石显示出来。
通过对`flag:hard`进行判断的方式,我们也可以达成“对于不同的难度有着不同的地图效果”。
- **`flag:hard`**: 当前的难度标志此flag变量在setInitData中被定义可以直接取用来判定当前难度分歧。上传成绩时将根据此flag来对不同难度进行排序。
- **`flag:posion`**, **`flag:weak`**, **`flag:curse`**: 中毒、衰弱、诅咒状态。
- **`flag:no_zone`**, **`flag:no_snipe`**, **`flag:no_laser`**, **`flag:no_betweenAttack`**: 是否分别免疫领域、阻击、激光、夹击效果。
- **`flag:hatred`**: 当前的仇恨数值。
- **`flag:commonTimes`**: 全局商店共用次数时的访问次数。
- **`flag:input`**: 接受用户输入的事件后,存放用户输入的结果。
- **`flag:type`**, **`flag:keycode`**, **`flag:x`**, **`flag:y`**: 等待用户操作后用户的操作类型按键keycode或点击坐标。
- **`flag:skill`**, **`flag:skillName`**: 开启的技能编号和技能名。
- **`flag:heroIcon`**: 当前的勇士行走图名称。
- **`flag:saveEquips`**: 快速换装时保存的套装。
- **`flag:__visited__`**: 当前访问过的楼层。
- **`flag:equip_atk_buff`**, **`flag:equip_def_buff`**, **`flag:equip_mdef_buff`**: 当前攻防魔防的实际计算比例加成。
- **`flag:forceSave`**: 是否允许事件中强制自动存档。如果将此项置为true并调用core.autosave()即可在事件中强制自动存档,读档时会自动执行该楼层的`eachArrive`事件。
- **`flag:__color__`**, **`flag:__weather__`**, **`flag:__volume__`**: 当前的画面色调、天气和音量。
- **`flag:textAttribute`**, **`flag:globalAttribute`**: 当前的剧情文本属性,当前的全局属性。
- **`flag:cannotMoveDirectly`**, **`flag:clickMove`**: 当前是否不允许瞬间移动,当前用户是否开启了单击瞬移。
- **`flag:hideStatusBar`**, **`flag:showToolbox`**: 是否隐藏状态栏,是否显示工具栏。
- **`flag:debug`**, **`flag:consoleOpened`**: 当前是否开启了调试模式,是否开启了控制台。
- **`flag:__seed__`**, **`flag:__rand__`**: 伪随机数生成种子和当前的状态
==========================================================================================

View File

@ -1,6 +1,6 @@
# 快速上手
?> 目前版本**v2.5.2**,上次更新时间:* {docsify-updated} *
?> 目前版本**v2.5.3**,上次更新时间:* {docsify-updated} *
在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔!

View File

@ -179,6 +179,11 @@
<button onclick="editor_blockly.confirm()">确认</button>
<button onclick="editor_blockly.parse()">解析</button>
<button onclick="editor_blockly.cancel()">取消</button>
<!-- 手机端放不下,因此不显示搜索框 -->
<div style="display: none">
<div class="searchLogo"></div>
<input type="text" id="searchBlock" placeholder="搜索图块"/>
</div>
<xml id="toolbox" style="display:none">
</xml>
</h3>
@ -353,7 +358,7 @@
<img id="img-hpmax">
<p class='statusLabel statusText' id='hpmax'></p>
</div>
<div class="status">
<div class="status" id='hpCol'>
<img id="img-hp">
<p class='statusLabel statusText' id='hp'></p>
</div>
@ -361,11 +366,11 @@
<img id="img-mana">
<p class='statusLabel statusText' id='mana'></p>
</div>
<div class="status">
<div class="status" id='atkCol'>
<img id="img-atk">
<p class='statusLabel statusText' id='atk'></p>
</div>
<div class="status">
<div class="status" id='defCol'>
<img id="img-def">
<p class='statusLabel statusText' id='def'></p>
</div>
@ -377,7 +382,7 @@
<img id="img-money">
<p class='statusLabel statusText' id='money'></p>
</div>
<div class="status" id="expCol">
<div class="status" id="experienceCol">
<img id="img-experience">
<p class='statusLabel statusText' id='experience'></p>
</div>
@ -404,6 +409,9 @@
<span class='statusLabel' id='weak' style="color: #FECCD0;"></span>
<span class='statusLabel' id='curse' style="color: #C2F4E7;"></span>
</div>
<!-- 状态栏canvas化 -->
<canvas id="statusCanvas"></canvas>
</div>
<div id="toolBar" class="clearfix">
<img class="tools" id='img-book'>
@ -435,7 +443,6 @@
<canvas class='gameCanvas' id='weather' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='route' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='curtain' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='image' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='ui' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='data' width='416' height='416'>此浏览器不支持HTML5</canvas>
</div>

View File

@ -178,6 +178,10 @@
<button onclick="editor_blockly.confirm()">确认</button>
<button onclick="editor_blockly.parse()">解析</button>
<button onclick="editor_blockly.cancel()">取消</button>
<div style="position: relative; display: inline-block; margin-left: 10px">
<div class="searchLogo"></div>
<input type="text" id="searchBlock" placeholder="搜索图块"/>
</div>
<xml id="toolbox" style="display:none">
</xml>
</h3>
@ -339,7 +343,7 @@
<img id="img-hpmax">
<p class='statusLabel statusText' id='hpmax'></p>
</div>
<div class="status">
<div class="status" id='hpCol'>
<img id="img-hp">
<p class='statusLabel statusText' id='hp'></p>
</div>
@ -347,11 +351,11 @@
<img id="img-mana">
<p class='statusLabel statusText' id='mana'></p>
</div>
<div class="status">
<div class="status" id='atkCol'>
<img id="img-atk">
<p class='statusLabel statusText' id='atk'></p>
</div>
<div class="status">
<div class="status" id='defCol'>
<img id="img-def">
<p class='statusLabel statusText' id='def'></p>
</div>
@ -363,7 +367,7 @@
<img id="img-money">
<p class='statusLabel statusText' id='money'></p>
</div>
<div class="status" id="expCol">
<div class="status" id="experienceCol">
<img id="img-experience">
<p class='statusLabel statusText' id='experience'></p>
</div>
@ -390,6 +394,9 @@
<span class='statusLabel' id='weak' style="color: #FECCD0;"></span>
<span class='statusLabel' id='curse' style="color: #C2F4E7;"></span>
</div>
<!-- 状态栏canvas化 -->
<canvas id="statusCanvas"></canvas>
</div>
<div id="toolBar" class="clearfix">
<img class="tools" id='img-book'>
@ -421,7 +428,6 @@
<canvas class='gameCanvas' id='weather' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='route' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='curtain' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='image' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='ui' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='data' width='416' height='416'>此浏览器不支持HTML5</canvas>
</div>

View File

@ -58,7 +58,7 @@
<img id="img-hpmax">
<p class='statusLabel statusText' id='hpmax'></p>
</div>
<div class="status">
<div class="status" id='hpCol'>
<img id="img-hp">
<p class='statusLabel statusText' id='hp'></p>
</div>
@ -66,11 +66,11 @@
<img id="img-mana">
<p class='statusLabel statusText' id='mana'></p>
</div>
<div class="status">
<div class="status" id='atkCol'>
<img id="img-atk">
<p class='statusLabel statusText' id='atk'></p>
</div>
<div class="status">
<div class="status" id='defCol'>
<img id="img-def">
<p class='statusLabel statusText' id='def'></p>
</div>
@ -82,7 +82,7 @@
<img id="img-money">
<p class='statusLabel statusText' id='money'></p>
</div>
<div class="status" id="expCol">
<div class="status" id="experienceCol">
<img id="img-experience">
<p class='statusLabel statusText' id='experience'></p>
</div>
@ -109,6 +109,9 @@
<span class='statusLabel' id='weak' style="color: #FECCD0;"></span>
<span class='statusLabel' id='curse' style="color: #C2F4E7;"></span>
</div>
<!-- 状态栏canvas化 -->
<canvas id="statusCanvas" style="position: absolute; left: 0; top: 0;"></canvas>
</div>
<div id="toolBar" class="clearfix">
<img class="tools" id='img-book'>
@ -140,7 +143,6 @@
<canvas class='gameCanvas' id='weather' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='route' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='curtain' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='image' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='ui' width='416' height='416'></canvas>
<canvas class='gameCanvas' id='data' width='416' height='416'>此浏览器不支持HTML5</canvas>
</div>

View File

@ -192,8 +192,8 @@ actions.prototype.keyDown = function(keyCode) {
}
////// 根据放开键的code来执行一系列操作 //////
actions.prototype.keyUp = function(keyCode, altKey) {
if (core.isset(core.status.replay)&&core.status.replay.replaying
actions.prototype.keyUp = function(keyCode, altKey, fromReplay) {
if (!fromReplay && core.isset(core.status.replay)&&core.status.replay.replaying
&&core.status.event.id!='save'&&(core.status.event.id||"").indexOf('book')!=0&&core.status.event.id!='viewMaps') return;
if (core.status.lockControl) {
@ -432,16 +432,13 @@ actions.prototype.getClickLoc = function (x, y) {
var size = 32;
size = size * core.domStyle.scale;
switch (core.domStyle.screenMode) {// 这里的3是指statusBar和游戏画布之间的白线宽度
case 'vertical':
statusBar.x = 0;
statusBar.y = core.dom.statusBar.offsetHeight + 3;
break;
case 'horizontal':
case 'bigScreen':
statusBar.x = core.dom.statusBar.offsetWidth + 3;
statusBar.y = 0;
break;
if (core.domStyle.isVertical) {
statusBar.x = 0;
statusBar.y = core.dom.statusBar.offsetHeight + 3;
}
else {
statusBar.x = core.dom.statusBar.offsetWidth + 3;
statusBar.y = 0;
}
var left = core.dom.gameGroup.offsetLeft + statusBar.x;
@ -658,6 +655,13 @@ actions.prototype.longClick = function (x, y, fromEvent) {
core.doAction();
return true;
}
// 长按楼传器的箭头可以快速翻页
if (core.status.event.id=='fly') {
if ((x==10 || x==11) && (y==5 || y==9)) {
this.clickFly(x, y);
return true;
}
}
}
else if (!fromEvent) {
core.waitHeroToStop(function () {
@ -780,12 +784,6 @@ actions.prototype.clickAction = function (x,y) {
////// 自定义事件时,按下某个键的操作 //////
actions.prototype.keyDownAction = function (keycode) {
// 视为无效
var startTime = core.status.event.data.startTime||0;
if (startTime>0 && new Date().getTime()-startTime<250)
return;
core.status.event.data.startTime = 0;
if (core.status.event.data.type=='choices') {
var data = core.status.event.data.current;
var choices = data.choices;
@ -1082,13 +1080,13 @@ actions.prototype.clickShop = function(x,y) {
core.status.event.selection=y-topIndex;
var money = core.getStatus('money'), experience = core.getStatus('experience');
var times = shop.times, need = eval(shop.need);
var times = shop.times, need = core.calValue(shop.need, null, times);
var use = shop.use;
var use_text = use=='money'?"金币":"经验";
var choice = choices[y-topIndex];
if (core.isset(choice.need))
need = eval(choice.need);
need = core.calValue(choice.need, null, times);
if (need > eval(use)) {
core.drawTip("你的"+use_text+"不足");
@ -1103,7 +1101,7 @@ actions.prototype.clickShop = function(x,y) {
// 更新属性
choice.effect.split(";").forEach(function (t) {
core.doEffect(t);
core.doEffect(t, need, times);
});
core.updateStatusBar();
shop.times++;
@ -1830,19 +1828,6 @@ actions.prototype.clickSwitchs = function (x,y) {
core.ui.drawSwitchs();
break;
case 8:
if (core.platform.isPC)
window.open("editor.html", "_blank");
else if (confirm("即将离开本塔,跳转至本塔工程页面,确认?")) {
window.location.href = "editor-mobile.html";
}
break;
case 9:
if (core.platform.isPC)
window.open(core.firstData.name+".zip");
else
window.location.href = core.firstData.name+".zip";
break;
case 10:
core.status.event.selection=0;
core.ui.drawSettings();
break;
@ -1902,9 +1887,11 @@ actions.prototype.clickSettings = function (x,y) {
core.ui.drawKeyBoard();
break;
case 2:
core.clearLastEvent();
core.ui.drawMaps();
break;
case 3:
core.clearLastEvent();
core.ui.drawPaint();
break;
case 4:
@ -2249,14 +2236,14 @@ actions.prototype.clickStorageRemove = function (x, y) {
core.ui.closePanel();
core.drawText("\t[操作成功]你的所有存档已被清空。");
core.status.saveIndex = 1;
core.setLocalStorage('saveIndex2', 1);
core.removeLocalStorage('saveIndex');
});
}
else {
localStorage.clear();
core.drawText("\t[操作成功]你的所有存档已被清空。");
core.status.saveIndex = 1;
core.setLocalStorage('saveIndex2', 1);
core.removeLocalStorage('saveIndex');
}
break;
case 1:
@ -2270,7 +2257,7 @@ actions.prototype.clickStorageRemove = function (x, y) {
core.ui.closePanel();
core.drawText("\t[操作成功]当前塔的存档已被清空。");
core.status.saveIndex = 1;
core.setLocalStorage('saveIndex2', 1);
core.removeLocalStorage('saveIndex');
});
}
else {
@ -2281,7 +2268,7 @@ actions.prototype.clickStorageRemove = function (x, y) {
core.removeLocalStorage("autoSave");
core.drawText("\t[操作成功]当前塔的存档已被清空。");
core.status.saveIndex = 1;
core.setLocalStorage('saveIndex2', 1);
core.removeLocalStorage('saveIndex');
}
break;
case 2:
@ -2423,6 +2410,13 @@ actions.prototype.clickGameInfo = function (x, y) {
core.ui.drawStatistics();
break;
case 1:
if (core.platform.isPC)
window.open("editor.html", "_blank");
else if (confirm("即将离开本塔,跳转至本塔工程页面,确认?")) {
window.location.href = "editor-mobile.html";
}
break;
case 2:
if (core.platform.isPC) {
window.open("/score.php?name="+core.firstData.name+"&num=10", "_blank");
}
@ -2432,13 +2426,19 @@ actions.prototype.clickGameInfo = function (x, y) {
}
}
break;
case 2:
case 3:
core.ui.drawHelp();
break;
case 3:
case 4:
core.ui.drawAbout();
break;
case 4:
case 5:
if (core.platform.isPC)
window.open(core.firstData.name+".zip");
else
window.location.href = core.firstData.name+".zip";
break;
case 6:
core.status.event.selection=5;
core.ui.drawSettings();
break;

View File

@ -57,8 +57,10 @@ control.prototype.setRequestAnimationFrame = function () {
core.animateFrame.globalTime = core.animateFrame.globalTime||timestamp;
core.animateFrame.boxTime = core.animateFrame.boxTime||timestamp;
core.animateFrame.selectorTime = core.animateFrame.selectorTime||timestamp;
core.animateFrame.animateTime = core.animateFrame.animateTime||timestamp;
core.animateFrame.moveTime = core.animateFrame.moveTime||timestamp;
core.animateFrame.lastLegTime = core.animateFrame.lastLegTime||timestamp;
core.animateFrame.weather.time = core.animateFrame.weather.time||timestamp;
// move time
@ -109,28 +111,49 @@ control.prototype.setRequestAnimationFrame = function () {
core.animateFrame.boxTime = timestamp;
}
// selectorTime
if (timestamp-core.animateFrame.selectorTime>20 && core.isset(core.dymCanvas.selector)) {
var opacity = parseFloat(core.dymCanvas.selector.canvas.style.opacity);
if (core.animateFrame.selectorUp)
opacity += 0.02;
else
opacity -= 0.02;
if (opacity > 0.95 || opacity < 0.55)
core.animateFrame.selectorUp = !core.animateFrame.selectorUp;
core.setOpacity("selector", opacity);
core.animateFrame.selectorTime = timestamp;
}
// Animate
if (timestamp-core.animateFrame.animateTime>50 && core.isset(core.status.animateObjs) && core.status.animateObjs.length>0) {
core.clearMap('animate');
core.status.animateObjs = core.status.animateObjs.filter(function (obj) {
return obj.index < obj.animate.frames.length;
})
});
core.status.animateObjs.forEach(function (obj) {
core.maps.drawAnimateFrame(obj.animate, obj.centerX, obj.centerY, obj.index++);
})
});
core.animateFrame.animateTime = timestamp;
}
// Hero move
if (timestamp-core.animateFrame.moveTime>16 && core.isset(core.status.heroMoving) && core.status.heroMoving>0) {
if (core.isPlaying() && core.status.heroMoving>0) {
var x=core.getHeroLoc('x'), y=core.getHeroLoc('y'), direction = core.getHeroLoc('direction');
// 200ms换腿
if (timestamp - core.animateFrame.moveTime > (core.values.moveSpeed||100)) {
core.animateFrame.leftLeg = !core.animateFrame.leftLeg;
core.animateFrame.moveTime = timestamp;
}
core.drawHero(direction, x, y, core.animateFrame.leftLeg?'leftFoot':'rightFoot', 4*core.status.heroMoving);
/*
if (core.status.heroMoving<=4) {
core.drawHero(direction, x, y, 'leftFoot', 4*core.status.heroMoving);
}
else if (core.status.heroMoving<=8) {
core.drawHero(direction, x, y, 'rightFoot', 4*core.status.heroMoving);
}
core.animateFrame.moveTime = timestamp;
*/
}
// weather
@ -203,6 +226,37 @@ control.prototype.setRequestAnimationFrame = function () {
core.canvas.weather.fill();
}
else if (core.animateFrame.weather.type == 'fog' && core.animateFrame.weather.level > 0) {
core.clearMap('weather');
if (core.animateFrame.weather.fog) {
var w = 416, h = 416;
core.setAlpha('weather', 0.5);
core.animateFrame.weather.nodes.forEach(function (p) {
core.canvas.weather.drawImage(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);
}
}
core.animateFrame.weather.time = timestamp;
@ -234,6 +288,10 @@ control.prototype.showStartAnimate = function (noAnimate, callback) {
core.clearStatus();
core.clearMap('all');
core.clearMap('curtain');
core.deleteAllCanvas();
// 重置音量
core.events.setVolume(1, 0);
if (core.flags.startUsingCanvas) {
core.dom.startTop.style.display = 'none';
@ -298,6 +356,7 @@ control.prototype.clearStatus = function() {
}
core.status = {};
core.clearStatusBar();
core.deleteAllCanvas();
core.status.played = false;
core.events.setHeroIcon('hero.png', true);
}
@ -314,9 +373,6 @@ control.prototype.resetStatus = function(hero, hard, floorId, route, maps, value
// 清除游戏数据
core.clearStatus();
// 显示状态栏
core.control.triggerStatusBar("show");
// 初始化status
core.status = core.clone(core.initStatus);
// 初始化maps
@ -336,6 +392,8 @@ control.prototype.resetStatus = function(hero, hard, floorId, route, maps, value
'currTime': 0,
'hp': 0,
"battle": 0,
'money': 0,
'experience': 0,
'battleDamage': 0,
'poisonDamage': 0,
'extraDamage': 0,
@ -350,13 +408,15 @@ control.prototype.resetStatus = function(hero, hard, floorId, route, maps, value
if (core.isset(route))
core.status.route = route;
// 保存的Index
core.status.saveIndex = core.getLocalStorage('saveIndex2', 1);
core.status.saveIndex = core.getLocalStorage('saveIndex', 1);
if (core.isset(values))
core.values = core.clone(values);
else core.values = core.clone(core.data.values);
core.events.initGame();
this.updateGlobalAttribute(Object.keys(core.status.globalAttribute));
this.triggerStatusBar(core.getFlag('hideStatusBar', false)?'hide':'show', core.getFlag("showToolbox"));
core.status.played = true;
}
@ -983,19 +1043,7 @@ control.prototype.jumpHero = function (ex, ey, time, callback) {
////// 每移动一格后执行的事件 //////
control.prototype.moveOneStep = function() {
core.status.hero.steps++;
// 中毒状态
if (core.hasFlag('poison')) {
core.status.hero.statistics.poisonDamage += core.values.poisonDamage;
core.status.hero.hp -= core.values.poisonDamage;
if (core.status.hero.hp<=0) {
core.status.hero.hp=0;
core.updateStatusBar();
core.events.lose();
return;
}
core.updateStatusBar();
}
return this.controldata.moveOneStep();
}
////// 停止勇士的一切行动等待勇士行动结束后再执行callback //////
@ -1294,142 +1342,20 @@ control.prototype.checkBlock = function () {
////// 阻击事件(动画效果) //////
control.prototype.snipe = function (snipes) {
var scan = {
'up': {'x': 0, 'y': -1},
'left': {'x': -1, 'y': 0},
'down': {'x': 0, 'y': 1},
'right': {'x': 1, 'y': 0}
};
snipes.forEach(function (snipe) {
var x=snipe.x, y=snipe.y, direction = snipe.direction;
snipe.nx = x+scan[snipe.direction].x;
snipe.ny = y+scan[snipe.direction].y;
core.removeGlobalAnimate(x, y);
var block = core.getBlock(x,y).block;
var cls = block.event.cls;
var height = block.event.height || 32;
snipe.animate = block.event.animate || 1;
snipe.blockIcon = core.material.icons[cls][block.event.id];
snipe.blockImage = core.material.images[cls];
snipe.height = height;
var damage = core.enemys.getDamage(block.event.id, x, y);
var color = '#000000';
if (damage == null) {
damage = "???";
color = '#FF0000';
}
else {
if (damage <= 0) color = '#00FF00';
else if (damage < core.status.hero.hp / 3) color = '#FFFFFF';
else if (damage < core.status.hero.hp * 2 / 3) color = '#FFFF00';
else if (damage < core.status.hero.hp) color = '#FF7F00';
else color = '#FF0000';
damage = core.formatBigNumber(damage);
if (core.enemys.hasSpecial(core.material.enemys[block.event.id], 19))
damage += "+";
if (core.enemys.hasSpecial(core.material.enemys[block.event.id], 21))
damage += "-";
if (core.enemys.hasSpecial(core.material.enemys[block.event.id], 11))
damage += "^";
}
snipe.damage = damage;
snipe.color = color;
snipe.block = core.clone(block);
})
var finishSnipe = function () {
snipes.forEach(function (t) {
core.removeBlock(t.x, t.y);
var nBlock = core.clone(t.block);
nBlock.x = t.nx; nBlock.y = t.ny;
core.status.thisMap.blocks.push(nBlock);
core.drawBlock(nBlock);
core.addGlobalAnimate(nBlock);
});
core.syncGlobalAnimate();
core.updateStatusBar();
return;
}
if (core.status.replay.replaying) {
finishSnipe();
}
else {
core.waitHeroToStop(function() {
core.lockControl();
var time = 500, step = 0;
var animateCurrent = 0;
var animateTime = 0;
core.canvas.damage.textAlign = 'left';
var animate=window.setInterval(function() {
step++;
animateTime += time / 16;
if (animateTime >= core.values.animateSpeed) {
animateCurrent++;
animateTime = 0;
}
snipes.forEach(function (snipe) {
var x=snipe.x, y=snipe.y, direction = snipe.direction;
var dx = scan[direction].x*2*step, dy = scan[direction].y*2*step;
var nowX = 32*x+dx, nowY = 32*y+dy;
// 清空上一次
core.clearMap('damage', nowX-2*scan[direction].x, nowY-2*scan[direction].y, 32, 32);
core.canvas.event.clearRect(nowX-2*scan[direction].x, nowY-2*scan[direction].y, 32, 32);
core.canvas.event2.clearRect(nowX-2*scan[direction].x, nowY-2*scan[direction].y-32, 32, 32)
core.drawBlock(snipe.block, animateCurrent, dx, dy);
if (core.hasItem('book')) {
// drawDamage
core.setFillStyle('damage', '#000000');
core.canvas.damage.fillText(snipe.damage, nowX + 2, nowY + 30);
core.canvas.damage.fillText(snipe.damage, nowX, nowY + 30);
core.canvas.damage.fillText(snipe.damage, nowX + 2, nowY + 32);
core.canvas.damage.fillText(snipe.damage, nowX, nowY + 32);
core.setFillStyle('damage', snipe.color);
core.canvas.damage.fillText(snipe.damage, nowX + 1, nowY + 31);
}
})
if (step==16) { // 移动完毕
clearInterval(animate);
finishSnipe();
// 不存在自定义事件
if (core.status.event.id==null)
core.unLockControl();
}
}, time/16);
});
}
// 阻击改成moveBlock事件完成
var actions = [];
snipes.forEach(function (t) {
actions.push({"type": "move", "loc": [t.x, t.y], "steps": [t.direction], "time": 500, "keep": true, "async": true});
});
actions.push({"type": "waitAsync"});
core.insertAction(actions);
}
////// 更改天气效果 //////
control.prototype.setWeather = function (type, level) {
// 非雨雪
if (type!='rain' && type!='snow') {
if (type!='rain' && type!='snow' && type!='fog') {
core.clearMap('weather')
core.animateFrame.weather.type = null;
core.animateFrame.weather.level = 0;
@ -1476,6 +1402,18 @@ control.prototype.setWeather = function (type, level) {
})
}
}
else if (type=='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
})
}
}
}
}
////// 更改画面色调 //////
@ -1503,26 +1441,26 @@ control.prototype.setFg = function(color, time, callback) {
return;
}
var step=0;
// core.status.replay.animate=true;
var per_time = 10, step=0, steps = parseInt(time / per_time);
var changeAnimate = setInterval(function() {
step++;
var nowA = fromColor[3]+(color[3]-fromColor[3])*step/25;
var nowR = parseInt(fromColor[0]+(color[0]-fromColor[0])*step/25);
var nowG = parseInt(fromColor[1]+(color[1]-fromColor[1])*step/25);
var nowB = parseInt(fromColor[2]+(color[2]-fromColor[2])*step/25);
var nowA = fromColor[3]+(color[3]-fromColor[3])*step/steps;
var nowR = parseInt(fromColor[0]+(color[0]-fromColor[0])*step/steps);
var nowG = parseInt(fromColor[1]+(color[1]-fromColor[1])*step/steps);
var nowB = parseInt(fromColor[2]+(color[2]-fromColor[2])*step/steps);
core.clearMap('curtain');
core.fillRect('curtain', 0, 0, 416, 416, core.arrayToRGBA([nowR,nowG,nowB,nowA]));
if (step>=25) {
if (step>=steps) {
delete core.animateFrame.asyncId[changeAnimate];
clearInterval(changeAnimate);
core.status.curtainColor = color;
// core.status.replay.animate=false;
if (core.isset(callback)) callback();
}
}, time/25/core.status.replay.speed);
}, per_time);
core.animateFrame.asyncId[changeAnimate] = true;
}
@ -1557,51 +1495,18 @@ control.prototype.updateDamage = function (floorId, canvas) {
var id = mapBlocks[b].event.id;
if (core.flags.displayEnemyDamage) {
var damage = core.enemys.getDamage(id, x, y);
var color = '#000000';
if (damage == null) {
damage = "???";
color = '#FF0000';
}
else {
if (damage <= 0) color = '#00FF00';
else if (damage < hero_hp / 3) color = '#FFFFFF';
else if (damage < hero_hp * 2 / 3) color = '#FFFF00';
else if (damage < hero_hp) color = '#FF7F00';
else color = '#FF0000';
damage = core.formatBigNumber(damage);
if (core.enemys.hasSpecial(core.material.enemys[id], 19))
damage += "+";
if (core.enemys.hasSpecial(core.material.enemys[id], 21))
damage += "-";
if (core.enemys.hasSpecial(core.material.enemys[id], 11))
damage += "^";
}
canvas.fillStyle = '#000000';
canvas.fillText(damage, 32 * x + 2, 32 * (y + 1) - 2);
canvas.fillText(damage, 32 * x, 32 * (y + 1) - 2);
canvas.fillText(damage, 32 * x + 2, 32 * (y + 1));
canvas.fillText(damage, 32 * x, 32 * (y + 1));
canvas.fillStyle = color;
canvas.fillText(damage, 32 * x + 1, 32 * (y + 1) - 1);
var damageString = core.enemys.getDamageString(id, x, y);
var damage = damageString.damage, color = damageString.color;
core.fillBoldText(canvas, damage, color, 32*x+1, 32*(y+1)-1);
}
// 临界显伤
if (core.flags.displayCritical) {
var critical = core.enemys.nextCriticals(id);
if (critical.length>0) critical=critical[0];
critical = core.formatBigNumber(critical[0]);
critical = core.formatBigNumber(critical[0], true);
if (critical == '???') critical = '?';
canvas.fillStyle = '#000000';
canvas.fillText(critical, 32 * x + 2, 32 * (y + 1) - 2 - 10);
canvas.fillText(critical, 32 * x, 32 * (y + 1) - 2 - 10);
canvas.fillText(critical, 32 * x + 2, 32 * (y + 1) - 10);
canvas.fillText(critical, 32 * x, 32 * (y + 1) - 10);
canvas.fillStyle = '#FFFFFF';
canvas.fillText(critical, 32 * x + 1, 32 * (y + 1) - 1 - 10);
core.fillBoldText(canvas, critical, '#FFFFFF', 32*x+1, 32*(y+1)-11);
}
}
@ -1625,15 +1530,8 @@ control.prototype.updateDamage = function (floorId, canvas) {
for (var y=0;y<core.bigmap.height;y++) {
var damage = core.status.checkBlock.damage[x+core.bigmap.width*y];
if (damage>0) {
damage = core.formatBigNumber(damage);
canvas.fillStyle = '#000000';
canvas.fillText(damage, 32 * x + 17, 32 * (y + 1) - 13);
canvas.fillText(damage, 32 * x + 15, 32 * (y + 1) - 15);
canvas.fillText(damage, 32 * x + 17, 32 * (y + 1) - 15);
canvas.fillText(damage, 32 * x + 15, 32 * (y + 1) - 13);
canvas.fillStyle = '#FF7F00';
canvas.fillText(damage, 32 * x + 16, 32 * (y + 1) - 14);
damage = core.formatBigNumber(damage, true);
core.fillBoldText(canvas, damage, "#FF7F00", 32*x+16, 32*(y+1)-14);
}
}
}
@ -1648,11 +1546,11 @@ control.prototype.updateDamage = function (floorId, canvas) {
}
////// 执行一个表达式的effect操作 //////
control.prototype.doEffect = function (effect) {
control.prototype.doEffect = function (effect, need, times) {
effect.split(";").forEach(function (expression) {
var arr = expression.split("+=");
if (arr.length!=2) return;
var name=arr[0], value=core.calValue(arr[1]);
var name=arr[0], value=core.calValue(arr[1], need, times);
if (name.indexOf("status:")==0) {
var status=name.substring(7);
core.setStatus(status, core.getStatus(status)+value);
@ -1661,6 +1559,10 @@ control.prototype.doEffect = function (effect) {
var itemId=name.substring(5);
core.setItem(itemId, core.itemCount(itemId)+value);
}
else if (name.indexOf("flag:")==0) {
var flag=name.substring(5);
core.setFlag(flag, core.getFlag(flag, 0)+value);
}
});
}
@ -2078,7 +1980,7 @@ control.prototype.replay = function () {
}
}
else if (action.indexOf('key:')==0) {
core.actions.keyUp(parseInt(action.substring(4)), true);
core.actions.keyUp(parseInt(action.substring(4)), false, true);
core.replay();
return;
}
@ -2199,7 +2101,7 @@ control.prototype.save = function(need) {
control.prototype.load = function (need) {
if (core.isset(core.status.replay)&&core.status.replay.replaying) return;
var saveIndex = core.getLocalStorage('saveIndex2', 1);
var saveIndex = core.getLocalStorage('saveIndex', 1);
var page=parseInt((saveIndex-1)/5), offset=saveIndex-5*page;
// 游戏开始前读档
@ -2226,17 +2128,23 @@ control.prototype.openSettings = function (need) {
////// 自动存档 //////
control.prototype.autosave = function (removeLast) {
if (core.status.event.id!=null)
return;
var addLast = true;
if (core.status.event.id!=null) {
// 检查是否是强制自动存档
if (core.status.event.id=='action' && core.hasFlag("forceSave")) addLast = false;
else return;
}
var x=null;
if (removeLast)
x=core.status.route.pop();
// 加入当前方向
core.status.route.push("turn:"+core.getHeroLoc('direction'));
core.setLocalForage("autoSave", core.saveData())
core.status.route.pop();
if (addLast)
core.status.route.push("turn:"+core.getHeroLoc('direction'));
core.setLocalForage("autoSave", core.saveData());
if (addLast)
core.status.route.pop();
if (removeLast && core.isset(x))
core.status.route.push(x);
core.removeFlag("forceSave");
}
////// 实际进行存读档事件 //////
@ -2251,7 +2159,7 @@ control.prototype.doSL = function (id, type) {
core.drawTip('存档成功!');
if (id!="autoSave") {
core.status.saveIndex=id;
core.setLocalStorage('saveIndex2', core.status.saveIndex);
core.setLocalStorage('saveIndex', core.status.saveIndex);
}
}, function(err) {
console.info(err);
@ -2288,7 +2196,7 @@ control.prototype.doSL = function (id, type) {
core.drawTip("读档成功");
if (id!="autoSave") {
core.status.saveIndex=id;
core.setLocalStorage('saveIndex2', core.status.saveIndex);
core.setLocalStorage('saveIndex', core.status.saveIndex);
}
});
}, function(err) {
@ -2484,6 +2392,9 @@ control.prototype.loadData = function (data, callback) {
core.control.updateGlobalAttribute(Object.keys(toAttribute));
}
// 重置音量
core.events.setVolume(core.getFlag("__volume__", 1), 0);
// load icons
var icon = core.getFlag("heroIcon", "hero.png");
if (core.isset(core.material.images.images[icon])) {
@ -2602,6 +2513,8 @@ control.prototype.playBgm = function (bgm) {
}
try {
// 缓存BGM
core.loader.loadBgm(bgm);
// 如果当前正在播放且和本BGM相同直接忽略
if (core.musicStatus.playingBgm == bgm && core.musicStatus.isPlaying) {
return;
@ -2634,7 +2547,7 @@ control.prototype.pauseBgm = function () {
core.musicStatus.isPlaying = false;
}
catch (e) {
console.log("无法暂停BGM "+bgm);
console.log("无法暂停BGM");
console.log(e);
}
}
@ -2662,7 +2575,7 @@ control.prototype.resumeBgm = function () {
}
}
catch (e) {
console.log("无法恢复BGM "+bgm);
console.log("无法恢复BGM");
console.log(e);
}
}
@ -2774,16 +2687,28 @@ control.prototype.updateStatusBar = function () {
}
}
control.prototype.triggerStatusBar = function (name) {
control.prototype.triggerStatusBar = function (name, showToolbox) {
if (name!='hide') name='show';
// 如果是隐藏 -> 显示工具栏,则先显示
if (name == 'hide' && showToolbox && !core.domStyle.showStatusBar && !core.hasFlag("showToolbox")) {
this.triggerStatusBar("show");
this.triggerStatusBar("hide", showToolbox);
return;
}
var statusItems = core.dom.status;
var toolItems = core.dom.tools;
core.domStyle.showStatusBar = name == 'show';
core.setFlag('hideStatusBar', core.domStyle.showStatusBar?null:true);
core.setFlag('showToolbox', showToolbox?true:null);
if (!core.domStyle.showStatusBar) {
for (var i = 0; i < statusItems.length; ++i)
statusItems[i].style.opacity = 0;
for (var i = 0; i < toolItems.length; ++i)
toolItems[i].style.display = 'none';
if (!core.domStyle.isVertical || !showToolbox) {
for (var i = 0; i < toolItems.length; ++i)
toolItems[i].style.display = 'none';
}
}
else {
for (var i = 0; i < statusItems.length; ++i)
@ -2825,31 +2750,30 @@ control.prototype.updateGlobalAttribute = function (name) {
if (!core.isset(attribute)) return;
switch (name) {
case 'statusLeftBackground':
if (core.domStyle.screenMode == 'horizontal' || core.domStyle.screenMode == 'bigScreen') {
if (!core.domStyle.isVertical) {
core.dom.statusBar.style.background = attribute[name];
}
break;
case 'statusTopBackground':
if (core.domStyle.screenMode == 'vertical') {
if (core.domStyle.isVertical) {
core.dom.statusBar.style.background = attribute[name];
}
break;
case 'toolsBackground':
if (core.domStyle.screenMode == 'vertical') {
if (core.domStyle.isVertical) {
core.dom.toolBar.style.background = attribute[name];
}
break;
case 'borderColor':
{
var border = '3px ' + attribute[name] + ' solid';
var isVertical = core.domStyle.screenMode == 'vertical';
core.dom.statusBar.style.borderTop = border;
core.dom.statusBar.style.borderLeft = border;
core.dom.statusBar.style.borderRight = isVertical?'':border;
core.dom.statusBar.style.borderRight = core.domStyle.isVertical?border:'';
core.dom.gameDraw.style.border = border;
core.dom.toolBar.style.borderBottom = border;
core.dom.toolBar.style.borderLeft = border;
core.dom.toolBar.style.borderRight = isVertical?'':border;
core.dom.toolBar.style.borderRight = core.domStyle.isVertical?border:'';
break;
}
case 'statusBarColor':
@ -2873,10 +2797,19 @@ control.prototype.updateGlobalAttribute = function (name) {
////// 改变工具栏为按钮1-7 //////
control.prototype.setToolbarButton = function (useButton) {
if (!core.domStyle.showStatusBar) return;
if (!core.domStyle.showStatusBar) {
// 隐藏状态栏时检查竖屏
if (!core.domStyle.isVertical) {
for (var i = 0; i < core.dom.tools.length; ++i)
core.dom.tools[i].style.display = 'none';
return;
}
if (!core.hasFlag('showToolbox')) return;
else core.dom.tools.hard.style.display = 'block';
}
if (!core.isset(useButton)) useButton = core.domStyle.toolbarBtn;
if (core.domStyle.screenMode != 'vertical') useButton = false;
if (!core.domStyle.isVertical) useButton = false;
core.domStyle.toolbarBtn = useButton;
if (useButton) {
@ -2894,7 +2827,37 @@ control.prototype.setToolbarButton = function (useButton) {
["book","fly","toolbox","shop","save","load","settings"].forEach(function (t) {
core.statusBar.image[t].style.display = 'block';
});
core.statusBar.image.shop.style.display = core.domStyle.screenMode != 'vertical' ? "none":"block";
core.statusBar.image.shop.style.display = core.domStyle.isVertical ? "block":"none";
}
}
control.prototype.needDraw = function(id) {
if (!core.isset(id)) {
var toDraw = [], status = core.dom.status;
for (var i = 0; i<status.length; ++i) {
var dom = core.dom.status[i], idCol = dom.id;
if (idCol.indexOf("Col")!=idCol.length-3) continue;
var id = idCol.substring(0, idCol.length-3);
if (!this.needDraw(id)) continue;
toDraw.push(id);
}
return toDraw;
}
switch (id) {
case 'floor': return core.flags.enableFloor;
case 'name': return core.flags.enableName;
case 'lv': return core.flags.enableLv;
case 'hpmax': return core.flags.enableHPMax;
case 'mana': return core.flags.enableMana;
case 'mdef': return core.flags.enableMDef;
case 'money': return core.flags.enableMoney;
case 'experience': return core.flags.enableExperience && !core.flags.levelUpLeftMode;
case 'up': return core.flags.enableLevelUp;
case 'skill': return core.flags.enableSkill;
case 'key': return core.flags.enableKeys;
case 'pzf': return core.flags.enablePZF;
case 'debuff': return core.flags.enableDebuff;
default: return true;
}
}
@ -2927,25 +2890,16 @@ control.prototype.resize = function(clientWidth, clientHeight) {
statusWidth, statusHeight, statusMaxWidth,statusLabelsLH,
toolBarWidth, toolBarHeight, toolBarTop, toolBarBorder,
toolsWidth, toolsHeight,toolsMargin,toolsPMaxwidth,
fontSize, toolbarFontSize, margin, statusBackground, toolsBackground;
fontSize, toolbarFontSize, margin, statusBackground, toolsBackground,
statusCanvasWidth, statusCanvasHeight;
var count = core.dom.statusBar.children.length;
if (!core.flags.enableFloor) count--;
if (!core.flags.enableLv) count--;
if (!core.flags.enableHPMax) count--;
if (!core.flags.enableMDef) count--;
if (!core.flags.enableMoney) count--;
if (!core.flags.enableExperience) count--;
if (!core.flags.enableLevelUp) count--;
if (core.flags.levelUpLeftMode) count--;
if (!core.flags.enableDebuff) count--;
if (!core.flags.enableKeys) count--;
if (!core.flags.enablePZF) count--;
if (!core.flags.enableName) count--;
if (!core.flags.enableMana) count--;
if (!core.flags.enableSkill) count--;
var toDraw = this.needDraw();
var count = toDraw.length;
var statusCanvas = core.flags.statusCanvas, statusCanvasRows = core.flags.statusCanvasRowsOnMobile || 3;
if (count>12) alert("当前状态栏数目("+count+")大于12请调整到不超过12以避免手机端出现显示问题。");
if (!statusCanvas && count>12) alert("当前状态栏数目("+count+")大于12请调整到不超过12以避免手机端出现显示问题。");
var col = Math.ceil(count / 3);
if (statusCanvas) col = statusCanvasRows;
var statusLineHeight = BASE_LINEHEIGHT * 9 / count;
var statusLineFontSize = DEFAULT_FONT_SIZE;
@ -2977,11 +2931,9 @@ control.prototype.resize = function(clientWidth, clientHeight) {
var tempWidth = DEFAULT_CANVAS_WIDTH * scale;
if(!isHorizontal){ //竖屏
core.domStyle.screenMode = 'vertical';
core.domStyle.isVertical = true;
//显示快捷商店图标
shopDisplay = 'block';
//判断应该显示几行
// var col = core.flags.enableMDef || core.flags.enableExperience || core.flags.enableDebuff ? 3 : 2;
var col = parseInt((count-1)/3)+1;
var tempTopBarH = scale * (BASE_LINEHEIGHT * col + SPACE * 2) + 6;
var tempBotBarH = scale * (BASE_LINEHEIGHT + SPACE * 4) + 6;
@ -2989,6 +2941,8 @@ control.prototype.resize = function(clientWidth, clientHeight) {
gameGroupHeight = tempWidth + tempTopBarH + tempBotBarH;
gameGroupWidth = tempWidth
statusCanvasWidth = canvasWidth;
statusCanvasHeight = tempTopBarH;
canvasTop = tempTopBarH;
// canvasLeft = 0;
toolBarWidth = statusBarWidth = canvasWidth;
@ -3014,6 +2968,7 @@ control.prototype.resize = function(clientWidth, clientHeight) {
toolbarFontSize = DEFAULT_FONT_SIZE * scale;
}else { //横屏
core.domStyle.screenMode = 'horizontal';
core.domStyle.isVertical = false;
shopDisplay = 'none';
gameGroupWidth = tempWidth + DEFAULT_BAR_WIDTH * scale;
gameGroupHeight = tempWidth;
@ -3022,6 +2977,8 @@ control.prototype.resize = function(clientWidth, clientHeight) {
toolBarWidth = statusBarWidth = DEFAULT_BAR_WIDTH * scale;
statusBarHeight = gameGroupHeight - SPACE;
statusBarBorder = '3px '+borderColor+' solid';
statusCanvasWidth = toolBarWidth + SPACE;
statusCanvasHeight = statusBarHeight;
statusBackground = (core.status.globalAttribute||core.initStatus.globalAttribute).statusLeftBackground;
statusHeight = scale*statusLineHeight * .8;
@ -3044,6 +3001,7 @@ control.prototype.resize = function(clientWidth, clientHeight) {
}else { //大屏设备 pc端
core.domStyle.scale = 1;
core.domStyle.screenMode = 'bigScreen';
core.domStyle.isVertical = false;
shopDisplay = 'none';
gameGroupWidth = DEFAULT_CANVAS_WIDTH + DEFAULT_BAR_WIDTH;
@ -3056,6 +3014,8 @@ control.prototype.resize = function(clientWidth, clientHeight) {
// statusBarHeight = statusLineHeight * count + SPACE * 2; //一共有9行
statusBackground = (core.status.globalAttribute||core.initStatus.globalAttribute).statusLeftBackground;
statusBarHeight = gameGroupHeight - SPACE;
statusCanvasWidth = toolBarWidth + SPACE;
statusCanvasHeight = statusBarHeight;
statusHeight = statusLineHeight * .8;
statusLabelsLH = .8 * statusLineHeight;
@ -3091,6 +3051,14 @@ control.prototype.resize = function(clientWidth, clientHeight) {
height: (canvasWidth - SPACE*2) + unit,
}
},
{
id: 'statusCanvas',
rules: {
width: (statusCanvasWidth - SPACE*2) + unit,
height: (statusCanvasHeight - SPACE) + unit,
display: statusCanvas?'block':'none'
}
},
{
id: 'gif',
rules: {
@ -3105,15 +3073,6 @@ control.prototype.resize = function(clientWidth, clientHeight) {
height:(canvasWidth - SPACE*2) + unit,
}
},
/*
{
id: 'curtain',
rules: {
width: (canvasWidth - SPACE*2) + unit,
height:(canvasWidth - SPACE*2) + unit,
}
},
*/
{
id: 'gameDraw',
rules: {
@ -3157,7 +3116,8 @@ control.prototype.resize = function(clientWidth, clientHeight) {
width: '100%',
maxWidth: statusMaxWidth + unit,
height: statusHeight + unit,
margin: margin/2 + unit
margin: margin/2 + unit,
display: !statusCanvas?'block':'none'
}
},
{
@ -3203,84 +3163,6 @@ control.prototype.resize = function(clientWidth, clientHeight) {
display: shopDisplay && core.domStyle.showStatusBar
}
},
{
id: 'floorCol',
rules: {
display: core.flags.enableFloor ? 'block': 'none'
}
},
{
id: 'nameCol',
rules: {
display: core.flags.enableName ? 'block': 'none'
}
},
{
id: 'lvCol',
rules: {
display: core.flags.enableLv ? 'block': 'none'
}
},
{
id: 'hpmaxCol',
rules: {
display: core.flags.enableHPMax ? 'block': 'none'
}
},
{
id: 'manaCol',
rules: {
display: core.flags.enableMana ? 'block': 'none'
}
},
{
id: 'mdefCol',
rules: {
display: core.flags.enableMDef ? 'block': 'none'
}
},
{
id: 'moneyCol',
rules: {
display: core.flags.enableMoney ? 'block': 'none'
}
},
{
id: 'expCol',
rules: {
display: core.flags.enableExperience && !core.flags.levelUpLeftMode ? 'block': 'none'
}
},
{
id: 'upCol',
rules: {
display: core.flags.enableLevelUp ? 'block': 'none'
}
},
{
id: 'skillCol',
rules: {
display: core.flags.enableSkill ? 'block': 'none'
}
},
{
id: 'keyCol',
rules: {
display: !core.isset(core.flags.enableKeys)||core.flags.enableKeys?'block':'none'
}
},
{
id: 'pzfCol',
rules: {
display: core.flags.enablePZF?'block':'none'
}
},
{
'id': 'debuffCol',
rules: {
display: core.flags.enableDebuff ? 'block': 'none'
}
},
{
id: 'hard',
rules: {
@ -3289,8 +3171,29 @@ control.prototype.resize = function(clientWidth, clientHeight) {
}
},
]
for (var i = 0; i < core.dom.status.length; ++i) {
var id = core.dom.status[i].id;
core.domStyle.styles.push({
id: id,
rules: {
display: toDraw.indexOf(id.substring(0, id.length-3))>=0 && !statusCanvas ? "block": "none"
}
});
}
core.domRenderer();
this.setToolbarButton();
if (core.domStyle.isVertical) {
core.dom.statusCanvas.width = 416;
core.dom.statusCanvas.height = col * BASE_LINEHEIGHT + SPACE + 6;
}
else {
core.dom.statusCanvas.width = 129;
core.dom.statusCanvas.height = 416;
}
if (core.isPlaying())
core.updateStatusBar();
}
////// 渲染DOM //////
@ -3335,5 +3238,12 @@ control.prototype.domRenderer = function(){
core.canvas[cn].canvas.style.height = core.bigmap.height*32*core.domStyle.scale + "px";
});
}
// 动态canvas
for (var i = 0; i < core.dymCanvas._list.length; i++) {
var spirit = core.dymCanvas._list[i];
core.dymCanvas[spirit.id].canvas.style.width = core.dymCanvas[spirit.id].canvas.width * core.domStyle.scale + "px";
core.dymCanvas[spirit.id].canvas.style.height = core.dymCanvas[spirit.id].canvas.height * core.domStyle.scale + "px";
core.dymCanvas[spirit.id].canvas.style.left = spirit.style.left * core.domStyle.scale + "px";
core.dymCanvas[spirit.id].canvas.style.top = spirit.style.top * core.domStyle.scale + "px"
}
}

View File

@ -32,8 +32,12 @@ function core() {
'globalAnimate': false,
'globalTime': null,
'boxTime': null,
'selectorTime': null,
'selectorUp': true,
'animateTime': null,
'moveTime': null,
'lastLegTime': null,
'leftLeg': true,
'speed': null,
'weather': {
'time': null,
@ -41,6 +45,7 @@ function core() {
'level': 0,
'nodes': [],
'data': null,
'fog': null,
},
"asyncId": {}
}
@ -53,6 +58,8 @@ function core() {
'isPlaying': false,
'gainNode': null,
'volume': 1.0, // 音量
'cachedBgms': [], // 缓存BGM内容
'cachedBgmCount': 4, // 缓存的bgm数量
}
this.platform = {
'isOnline': true, // 是否http
@ -74,6 +81,8 @@ function core() {
this.domStyle = {
styles: [],
scale: 1.0,
screenMode: null,
isVertical: false,
toolbarBtn: false,
showStatusBar: true,
}
@ -183,6 +192,9 @@ function core() {
'animateObjs': [],
};
this.status = {};
this.dymCanvas = {
"_list": []
};
}
/////////// 系统事件相关 ///////////
@ -310,7 +322,7 @@ core.prototype.init = function (coreData, callback) {
core.musicStatus.bgmStatus = core.getLocalStorage('bgmStatus', true);
if (!core.musicStatus.startDirectly) // 如果当前网络环境不允许
core.musicStatus.bgmStatus = false;
core.setLocalStorage('bgmStatus', core.musicStatus.bgmStatus);
// core.setLocalStorage('bgmStatus', core.musicStatus.bgmStatus);
core.musicStatus.soundStatus = core.getLocalStorage('soundStatus', true);
core.setLocalStorage('soundStatus', core.musicStatus.soundStatus);
@ -327,6 +339,12 @@ core.prototype.init = function (coreData, callback) {
}
core.material.ground.src = "project/images/ground.png";
core.animateFrame.weather.fog = new Image();
core.animateFrame.weather.fog.onerror = function () {
core.animateFrame.weather.fog = null;
}
core.animateFrame.weather.fog.src = "project/images/fog.png";
core.bigmap.tempCanvas = document.createElement('canvas').getContext('2d');
core.loader.load(function () {
@ -417,8 +435,8 @@ core.prototype.keyDown = function(keyCode) {
}
////// 根据放开键的code来执行一系列操作 //////
core.prototype.keyUp = function(keyCode, altKey) {
return core.actions.keyUp(keyCode, altKey);
core.prototype.keyUp = function(keyCode, altKey, fromReplay) {
return core.actions.keyUp(keyCode, altKey, fromReplay);
}
////// 点击(触摸)事件按下时 //////
@ -613,68 +631,106 @@ core.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback,
}
////// 清除地图 //////
core.prototype.clearMap = function (map, x, y, width, height) {
core.ui.clearMap(map, x, y, width, height);
core.prototype.clearMap = function (name, x, y, width, height) {
core.ui.clearMap(name, x, y, width, height);
}
////// 在某个canvas上绘制一段文字 //////
core.prototype.fillText = function (map, text, x, y, style, font) {
core.ui.fillText(map, text, x, y, style, font);
core.prototype.fillText = function (name, text, x, y, style, font) {
core.ui.fillText(name, text, x, y, style, font);
}
////// 在某个canvas上绘制一段描边文字 //////
core.prototype.fillBoldText = function (canvas, text, style, x, y, font) {
core.ui.fillBoldText(canvas, text, style , x, y, font);
}
////// 在某个canvas上绘制一个矩形 //////
core.prototype.fillRect = function (map, x, y, width, height, style) {
core.ui.fillRect(map, x, y, width, height, style)
core.prototype.fillRect = function (name, x, y, width, height, style) {
core.ui.fillRect(name, x, y, width, height, style)
}
////// 在某个canvas上绘制一个矩形的边框 //////
core.prototype.strokeRect = function (map, x, y, width, height, style, lineWidth) {
core.ui.strokeRect(map, x, y, width, height, style, lineWidth)
core.prototype.strokeRect = function (name, x, y, width, height, style, lineWidth) {
core.ui.strokeRect(name, x, y, width, height, style, lineWidth)
}
////// 在某个canvas上绘制一条线 //////
core.prototype.drawLine = function (map, x1, y1, x2, y2, style, lineWidth) {
core.ui.drawLine(map, x1, y1, x2, y2, style, lineWidth);
core.prototype.drawLine = function (name, x1, y1, x2, y2, style, lineWidth) {
core.ui.drawLine(name, x1, y1, x2, y2, style, lineWidth);
}
////// 在某个canvas上绘制一个箭头 //////
core.prototype.drawArrow = function (name, x1, y1, x2, y2, style, lineWidth) {
core.ui.drawArrow(name, x1, y1, x2, y2, style, lineWidth);
}
////// 设置某个canvas的文字字体 //////
core.prototype.setFont = function (map, font) {
core.ui.setFont(map, font);
core.prototype.setFont = function (name, font) {
core.ui.setFont(name, font);
}
////// 设置某个canvas的线宽度 //////
core.prototype.setLineWidth = function (map, lineWidth) {
core.ui.setLineWidth(map, lineWidth);
core.prototype.setLineWidth = function (name, lineWidth) {
core.ui.setLineWidth(name, lineWidth);
}
////// 保存某个canvas状态 //////
core.prototype.saveCanvas = function (map) {
core.ui.saveCanvas(map);
core.prototype.saveCanvas = function (name) {
core.ui.saveCanvas(name);
}
////// 加载某个canvas状态 //////
core.prototype.loadCanvas = function (map) {
core.ui.loadCanvas(map);
core.prototype.loadCanvas = function (name) {
core.ui.loadCanvas(name);
}
////// 设置某个canvas边框属性 //////
core.prototype.setStrokeStyle = function (map, style) {
core.ui.setStrokeStyle(map, style);
}
////// 设置某个canvas的alpha值 //////
core.prototype.setAlpha = function (map, alpha) {
core.ui.setAlpha(map, alpha);
core.prototype.setAlpha = function (name, alpha) {
core.ui.setAlpha(name, alpha);
}
////// 设置某个canvas的透明度 //////
core.prototype.setOpacity = function (map, opacity) {
core.ui.setOpacity(map, opacity);
core.prototype.setOpacity = function (name, opacity) {
core.ui.setOpacity(name, opacity);
}
////// 设置某个canvas的绘制属性如颜色等 //////
core.prototype.setFillStyle = function (map, style) {
core.ui.setFillStyle(map, style);
core.prototype.setFillStyle = function (name, style) {
core.ui.setFillStyle(name, style);
}
////// 设置某个canvas的边框属性 //////
core.prototype.setStrokeStyle = function (name, style) {
core.ui.setStrokeStyle(name, style);
}
////// canvas创建 //////
core.prototype.createCanvas = function (name, x, y, width, height, z) {
core.ui.createCanvas(name, x, y, width, height, z);
}
////// canvas查找 //////
core.prototype.findCanvas = function (name) {
return core.ui.findCanvas(name);
}
////// canvas重定位 //////
core.prototype.relocateCanvas = function (name, x, y) {
core.ui.relocateCanvas(name, x, y);
}
////// canvas重置 //////
core.prototype.resizeCanvas = function (name, width, height) {
core.ui.resizeCanvas(name, width, height);
}
////// canvas删除 //////
core.prototype.deleteCanvas = function (name) {
core.ui.deleteCanvas(name);
}
////// 删除所有canvas //////
core.prototype.deleteAllCanvas = function () {
core.ui.deleteAllCanvas();
}
core.prototype.drawBlock = function (block, animate, dx, dy) {
@ -682,8 +738,8 @@ core.prototype.drawBlock = function (block, animate, dx, dy) {
}
////// 绘制某张地图 //////
core.prototype.drawMap = function (mapName, callback) {
core.maps.drawMap(mapName, callback);
core.prototype.drawMap = function (floorId, callback) {
core.maps.drawMap(floorId, callback);
}
////// 绘制Autotile //////
@ -757,8 +813,8 @@ core.prototype.animateBlock = function (loc,type,time,callback) {
}
////// 将某个块从禁用变成启用状态 //////
core.prototype.showBlock = function(x, y, floodId) {
core.maps.showBlock(x,y,floodId);
core.prototype.showBlock = function(x, y, floorId) {
core.maps.showBlock(x,y,floorId);
}
////// 将某个块从启用变成禁用状态,但是并不删除它 //////
@ -954,18 +1010,18 @@ core.prototype.drawText = function (contents, callback) {
/////////// 系统机制 ///////////
////// 将文字中的${和}(表达式)进行替换 //////
core.prototype.replaceText = function (text) {
return core.utils.replaceText(text);
core.prototype.replaceText = function (text, need, times) {
return core.utils.replaceText(text, need, times);
}
////// 计算表达式的值 //////
core.prototype.calValue = function (value) {
return core.utils.calValue(value);
core.prototype.calValue = function (value, need, times) {
return core.utils.calValue(value, need, times);
}
////// 执行一个表达式的effect操作 //////
core.prototype.doEffect = function (expression) {
core.control.doEffect(expression);
core.prototype.doEffect = function (expression, need, times) {
core.control.doEffect(expression, need, times);
}
////// 字符串自动换行的分割 //////
@ -1026,8 +1082,8 @@ core.prototype.formatDate2 = function (date) {
}
////// 格式化大数 //////
core.prototype.formatBigNumber = function (x) {
return core.utils.formatBigNumber(x);
core.prototype.formatBigNumber = function (x, onMap) {
return core.utils.formatBigNumber(x, onMap);
}
////// 两位数显示 //////
@ -1081,6 +1137,11 @@ core.prototype.closePanel = function () {
core.ui.closePanel();
}
////// 一般清除事件 //////
core.prototype.clearLastEvent = function () {
core.ui.clearLastEvent();
}
////// 更改播放状态 //////
core.prototype.triggerReplay = function () {
core.control.triggerReplay();
@ -1355,6 +1416,16 @@ core.prototype.resumeBgm = function () {
core.control.resumeBgm();
}
////// 预加载一个背景音乐 //////
core.prototype.loadBgm = function (bgm) {
core.loader.loadBgm(bgm);
}
////// 手动释放一个背景音乐的缓存 //////
core.prototype.freeBgm = function (bgm) {
core.loader.freeBgm(bgm);
}
////// 播放音频 //////
core.prototype.playSound = function (sound) {
core.control.playSound(sound);
@ -1380,6 +1451,11 @@ core.prototype.updateStatusBar = function () {
core.control.updateStatusBar();
}
////// 绘制状态栏 //////
core.prototype.drawStatusBar = function () {
core.ui.drawStatusBar();
}
////// 屏幕分辨率改变后重新自适应 //////
core.prototype.resize = function(clientWidth, clientHeight) {
core.control.resize(clientWidth, clientHeight);

View File

@ -127,6 +127,38 @@ enemys.prototype.getExtraDamage = function (enemy) {
return extra_damage;
}
enemys.prototype.getDamageString = function (enemy, x, y) {
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
var damage = core.enemys.getDamage(enemy, x, y);
var color = '#000000';
if (damage == null) {
damage = "???";
color = '#FF0000';
}
else {
if (damage <= 0) color = '#00FF00';
else if (damage < core.status.hero.hp / 3) color = '#FFFFFF';
else if (damage < core.status.hero.hp * 2 / 3) color = '#FFFF00';
else if (damage < core.status.hero.hp) color = '#FF7F00';
else color = '#FF0000';
damage = core.formatBigNumber(damage, true);
if (core.enemys.hasSpecial(enemy, 19))
damage += "+";
if (core.enemys.hasSpecial(enemy, 21))
damage += "-";
if (core.enemys.hasSpecial(enemy, 11))
damage += "^";
}
return {
"damage": damage,
"color": color
};
}
////// 接下来N个临界值和临界减伤计算 //////
enemys.prototype.nextCriticals = function (enemy, number, x, y, floorId) {
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
@ -164,9 +196,7 @@ enemys.prototype.nextCriticals = function (enemy, number, x, y, floorId) {
for (var t = turn-1;t>=1;t--) {
var nextAtk = Math.ceil(mon_hp/t) + mon_def;
// 装备提升比例的计算临界
if (core.flags.equipPercentage) {
nextAtk = Math.ceil(nextAtk / core.getFlag('equip_atk_buff', 1));
}
nextAtk = Math.ceil(nextAtk / core.getFlag('equip_atk_buff', 1));
if (nextAtk<=hero_atk) break;
if (nextAtk!=pre) {
var nextInfo = this.getDamageInfo(enemy, core.status.hero.hp, nextAtk, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
@ -181,7 +211,9 @@ enemys.prototype.nextCriticals = function (enemy, number, x, y, floorId) {
}
else { // 暴力for循环法
pre = info.damage;
for (var atk=hero_atk+1;atk<=mon_hp+mon_def;atk++) {
var per_add = Math.ceil(hero_atk / (core.flags.loopStep||5000));
if (per_add<0) per_add = 1;
for (var atk=hero_atk+per_add;atk<=mon_hp+mon_def;atk+=per_add) {
var nextInfo = this.getDamageInfo(enemy, core.status.hero.hp, atk, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
if (nextInfo==null) break;
if (pre>nextInfo.damage) {
@ -257,11 +289,10 @@ enemys.prototype.getCurrentEnemys = function (floorId) {
var mon_hp = enemy.hp, mon_atk = enemy.atk, mon_def = enemy.def;
var hero_atk = core.status.hero.atk, hero_def = core.status.hero.def, hero_mdef = core.status.hero.mdef;
if (core.flags.equipPercentage) {
hero_atk = Math.floor(core.getFlag('equip_atk_buff',1)*hero_atk);
hero_def = Math.floor(core.getFlag('equip_def_buff',1)*hero_def);
hero_mdef = Math.floor(core.getFlag('equip_mdef_buff',1)*hero_mdef);
}
hero_atk = Math.floor(core.getFlag('equip_atk_buff',1)*hero_atk);
hero_def = Math.floor(core.getFlag('equip_def_buff',1)*hero_def);
hero_mdef = Math.floor(core.getFlag('equip_mdef_buff',1)*hero_mdef);
var enemyInfo = this.getEnemyInfo(enemy, core.status.hero.hp, hero_atk, hero_def, hero_mdef, null, null, floorId);
var specialText = core.enemys.getSpecialText(enemyId);

View File

@ -9,7 +9,11 @@ events.prototype.init = function () {
this.eventdata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.events;
this.events = {
'battle': function (data, core, callback) {
//core.autosave(true);
// 正在执行自定义事件:不允许战斗
if (core.status.event.id == 'action') {
if (core.isset(callback)) callback();
return;
}
core.battle(data.event.id, data.x, data.y);
if (core.isset(callback))
callback();
@ -20,13 +24,22 @@ events.prototype.init = function () {
callback();
},
'openDoor': function (data, core, callback) {
//core.autosave(true);
// 正在执行自定义事件:不允许开门
if (core.status.event.id == 'action') {
if (core.isset(callback)) callback();
return;
}
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;
}
var heroLoc = {};
if (core.isset(data.event.data.loc))
heroLoc = {'x': data.event.data.loc[0], 'y': data.event.data.loc[1]};
@ -109,6 +122,7 @@ events.prototype.startGame = function (hard, seed, route, callback) {
core.clearMap('all');
core.clearMap('curtain');
core.deleteAllCanvas();
core.clearStatusBar();
var post_start = function () {
@ -117,7 +131,7 @@ events.prototype.startGame = function (hard, seed, route, callback) {
core.changeFloor(core.firstData.floorId, null, nowLoc, null, function() {
if (core.isset(callback)) callback();
}, true);
});
setTimeout(function () {
// Upload
@ -171,6 +185,8 @@ events.prototype.startGame = function (hard, seed, route, callback) {
}
if (main.mode!='play') return;
if (core.flags.startUsingCanvas) {
core.dom.startPanel.style.display = 'none';
start();
@ -210,8 +226,7 @@ events.prototype.gameOver = function (ending, fromReplay, norank) {
// 清空图片和天气
core.clearMap('animate');
core.clearMap('image');
core.clearMap('weather')
core.clearMap('weather');
core.dom.gif2.innerHTML = "";
core.animateFrame.weather.type = null;
core.animateFrame.weather.level = 0;
@ -344,7 +359,7 @@ events.prototype.doEvents = function (list, x, y, callback) {
core.status.event = {'id': 'action', 'data': {
'list': [
{"todo": core.clone(list), "total": core.clone(list), "condition": "false"}
], 'x': x, 'y': y, 'callback': callback, 'startTime': new Date().getTime()
], 'x': x, 'y': y, 'callback': callback
}}
// 停止勇士
@ -361,8 +376,7 @@ events.prototype.doAction = function() {
clearInterval(core.status.event.interval);
core.status.event.interval = null;
core.clearMap('ui');
core.setAlpha('ui', 1.0);
core.clearLastEvent();
// 事件处理完毕
if (core.status.event.data.list.length==0) {
@ -420,6 +434,23 @@ events.prototype.doAction = function() {
}, data.time || 3000);
}
break;
case "scrollText": // 滚动剧情文本
if (core.status.replay.replaying)
core.events.doAction();
else {
var content = core.replaceText(data.text);
var time = data.time || 5000;
if (data.async) {
core.ui.drawScrollText(content, time);
core.events.doAction();
}
else {
core.ui.drawScrollText(content, time, function() {
core.events.doAction();
});
}
}
break;
case "comment":
this.doAction();
break;
@ -701,29 +732,54 @@ events.prototype.doAction = function() {
this.doAction();
break;
case "showImage": // 显示图片
if (!core.isset(data.loc)) data.loc=[];
core.events.showImage(data.name, data.loc[0], data.loc[1]);
this.doAction();
break;
case "animateImage": // 淡入淡出图片
if (core.status.replay.replaying) { // 正在播放录像
if (!core.isset(data.loc)) data.loc=[0, 0];
if (core.status.replay.replaying) {
data.time = 0;
}
var image = core.material.images.images[data.image];
if (!core.isset(image)) {
this.doAction();
break;
}
if (data.async || data.time == 0) {
core.events.showImage(data.code, image, data.loc[0], data.loc[1], data.dw, data.dh, data.opacity, data.time);
this.doAction();
}
else {
if (core.isset(data.loc) && core.isset(core.material.images.images[data.name]) && (data.action=="show" || data.action=="hide")) {
if (data.async) {
core.events.animateImage(data.action, core.material.images.images[data.name], data.loc, data.time, data.keep);
this.doAction();
}
else {
core.events.animateImage(data.action, core.material.images.images[data.name], data.loc, data.time, data.keep, function() {
core.events.doAction();
});
}
}
else {
this.doAction();
}
core.events.showImage(data.code, image, data.loc[0], data.loc[1], data.dw, data.dh, data.opacity, data.time, function () {
core.events.doAction();
});
}
break;
case "showTextImage": // 显示图片化文本
if (!core.isset(data.loc)) data.loc=[0, 0];
if (core.status.replay.replaying) {
data.time = 0;
}
var content = core.replaceText(data.text);
var image = core.events.textImage(content);
if (data.async || data.time == 0) {
core.events.showImage(data.code, image, data.loc[0], data.loc[1], 100, 100, data.opacity, data.time);
this.doAction();
}
else {
core.events.showImage(data.code, image, data.loc[0], data.loc[1], 100, 100, data.opacity, data.time, function() {
core.events.doAction();
});
}
break;
case "hideImage": // 隐藏图片
if (core.status.replay.replaying) {
data.time = 0;
}
if (data.async || data.time == 0) {
core.events.hideImage(data.code, data.time);
this.doAction();
}
else {
core.events.hideImage(data.code, data.time, function () {
core.events.doAction();
});
}
break;
case "showGif": // 显示动图
@ -747,19 +803,14 @@ events.prototype.doAction = function() {
this.doAction();
}
else {
if (core.isset(data.from) && core.isset(data.to) && core.isset(core.material.images.images[data.name])) {
if (data.async) {
core.events.moveImage(core.material.images.images[data.name], data.from, data.to, data.time, data.keep);
this.doAction();
}
else {
core.events.moveImage(core.material.images.images[data.name], data.from, data.to, data.time, data.keep, function() {
core.events.doAction();
});
}
if (data.async) {
core.events.moveImage(data.code, data.to, data.opacity, data.time);
this.doAction();
}
else {
this.doAction();
core.events.moveImage(data.code, data.to, data.opacity, data.time, function() {
core.events.doAction();
});
}
}
break;
@ -864,16 +915,23 @@ events.prototype.doAction = function() {
core.resumeBgm();
this.doAction();
break
case "loadBgm":
core.loadBgm(data.name);
this.doAction();
break;
case "freeBgm":
core.freeBgm(data.name);
this.doAction();
break;
case "setVolume":
data.value = parseInt(data.value||0);
if (data.value<0) data.value=0;
if (data.value>100) data.value=100;
data.value = core.clamp(parseInt(data.value)/100, 0, 1);
core.setFlag("__volume__", data.value);
if (data.async) {
this.setVolume(data.value/100, data.time);
this.setVolume(data.value, data.time);
this.doAction();
}
else {
this.setVolume(data.value/100, data.time, function() {
this.setVolume(data.value, data.time, function() {
core.events.doAction();
});
}
@ -916,6 +974,11 @@ events.prototype.doAction = function() {
this.doAction();
break;
case "setGlobalAttribute":
if (typeof data.value == 'string') {
if ((data.value.charAt(0)=='"' && data.value.charAt(data.value.length-1)=='"')
|| (data.value.charAt(0)=="'" && data.value.charAt(data.value.length-1)=="'"))
data.value = data.value.substring(1, data.value.length-1);
}
core.status.globalAttribute[data.name] = data.value;
core.control.updateGlobalAttribute(data.name);
core.setFlag('globalAttribute', core.status.globalAttribute);
@ -1053,14 +1116,19 @@ events.prototype.doAction = function() {
case "function":
{
var func = data["function"];
if (core.isset(func)) {
if ((typeof func == "string") && func.indexOf("function")==0) {
eval('('+func+')()');
try {
if (core.isset(func)) {
if ((typeof func == "string") && func.indexOf("function")==0) {
eval('('+func+')()');
}
else if (func instanceof Function)
func();
}
else if (func instanceof Function)
func();
} catch (e) {
console.log(e);
}
this.doAction();
if (!data.async)
this.doAction();
break;
}
case "update":
@ -1072,7 +1140,7 @@ events.prototype.doAction = function() {
this.doAction();
break;
case "hideStatusBar":
core.control.triggerStatusBar("hide");
core.control.triggerStatusBar("hide", data.toolbox);
this.doAction();
break;
case "updateEnemys":
@ -1092,13 +1160,9 @@ events.prototype.doAction = function() {
}
break;
case "sleep": // 等待多少毫秒
if (core.status.replay.replaying)
setTimeout(function() {
core.events.doAction();
else {
setTimeout(function () {
core.events.doAction();
}, data.time);
}
}, core.status.replay.replaying?20:data.time);
break;
case "wait":
if (core.status.replay.replaying) {
@ -1160,6 +1224,8 @@ events.prototype.doAction = function() {
////// 往当前事件列表之前添加一个或多个事件 //////
events.prototype.insertAction = function (action, x, y, callback) {
if (core.hasFlag("__statistics__")) return;
if (core.status.event.id != 'action') {
this.doEvents(action, x, y, callback);
}
@ -1384,10 +1450,12 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback
if (index<core.floorIds.length-1) floorId = core.floorIds[index+1];
else floorId=core.status.floorId;
}
if (main.mode!='play') time = 0;
if (!core.isset(time)) time = core.values.floorChangeTime;
if (!core.isset(time)) time = 800;
var displayAnimate=(!core.isset(time) || time>=100) && !core.status.replay.replaying;
var displayAnimate = time>=100 && !core.status.replay.replaying;
time = time || 800;
time /= 20;
core.lockControl();
core.stopHero();
@ -1514,91 +1582,150 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback
}, 25);
}
////// 绘制图片 //////
events.prototype.showImage = function (name, x, y) {
if (core.isset(name) && core.isset(x) && core.isset(y) && core.isset(core.material.images.images[name])) {
core.canvas.image.drawImage(core.material.images.images[name], x, y);
////// 显示图片 //////
events.prototype.showImage = function (code, image, x, y, dw, dh, opacityVal, time, callback) {
dw /= 100;
dh /= 100;
x = core.calValue(x) || 0;
y = core.calValue(y) || 0;
var zIndex = code + 100;
time = time || 0;
var name = "image"+ zIndex;
if (core.findCanvas(name) != -1) {
core.relocateCanvas(name, x, y);
core.resizeCanvas(name, image.width * dw, image.height * dh);
core.dymCanvas[name].style.zIndex = zIndex;
}
else
core.createCanvas(name, x, y, image.width * dw, image.height * dh, zIndex);
core.dymCanvas[name].drawImage(image, 0, 0, image.width * dw, image.height * dh);
if (time == 0)
core.setOpacity(name, opacityVal);
else {
var per_time = 10, steps = parseInt(time / per_time), per_add = opacityVal / steps;
var opacity = 0;
core.setOpacity(name, 0);
var animate = setInterval(function () {
opacity += per_add;
core.setOpacity(name, opacity);
if (opacity >= opacityVal) {
delete core.animateFrame.asyncId[animate];
clearInterval(animate);
core.setOpacity(name, opacityVal);
if (core.isset(callback)) callback();
}
}, per_time);
core.animateFrame.asyncId[animate] = true;
}
else core.clearMap('image');
}
////// 图片淡入/淡出 //////
events.prototype.animateImage = function (type, image, loc, time, keep, callback) {
time = time||0;
if ((type!='show' && type!='hide') || time<=0) {
////// 隐藏图片 //////
events.prototype.hideImage = function (code, time, callback) {
time = time || 0;
var name = "image"+ (code+100);
if (!core.isset(core.dymCanvas[name])) {
console.log(code+"号图片不存在")
if (core.isset(callback)) callback();
return;
}
if (time == 0)
core.deleteCanvas(name);
else {
var opacityVal = parseFloat(core.dymCanvas[name].canvas.style.opacity);
var per_time = 10, steps = parseInt(time / per_time), per_add = opacityVal / steps;
var animate = setInterval(function () {
opacityVal -= per_add;
core.setOpacity(name, opacityVal);
if (opacityVal < 0) {
delete core.animateFrame.asyncId[animate];
clearInterval(animate);
core.deleteCanvas(name);
if (core.isset(callback)) callback();
}
}, per_time);
clearInterval(core.interval.tipAnimate);
var alpha = 0;
if (type == 'hide') alpha = 1;
var x = core.calValue(loc[0]), y = core.calValue(loc[1]);
if (type == 'hide' && keep) {
core.clearMap('image', x, y, image.width, image.height);
core.animateFrame.asyncId[animate] = true;
}
core.setAlpha('data', alpha);
core.canvas.data.drawImage(image, x, y);
core.setAlpha('data', 1);
}
// core.status.replay.animate=true;
var animate = setInterval(function () {
if (type=='show') alpha += 0.1;
else alpha -= 0.1;
core.clearMap('data', x, y, image.width, image.height);
if (alpha >=1 || alpha<=0) {
delete core.animateFrame.asyncId[animate];
clearInterval(animate);
if (type == 'show' && keep)
core.canvas.image.drawImage(image, x, y);
core.setAlpha('data', 1);
if (core.isset(callback)) callback();
}
else {
core.setAlpha('data', alpha);
core.canvas.data.drawImage(image, x, y);
core.setAlpha('data', 1);
}
}, time / 10);
////// 文本图片化 //////
events.prototype.textImage = function (content) {
content = content || "";
core.animateFrame.asyncId[animate] = true;
// 获得颜色的盒子等信息
var textAttribute = core.status.textAttribute || core.initStatus.textAttribute;
var textfont = textAttribute.textfont || 16;
var offset = textAttribute.offset || 15;
var textColor = core.arrayToRGBA(textAttribute.text);
var font = textfont+"px "+core.status.globalAttribute.font;
if (textAttribute.bold) font = "bold "+font;
var contents = core.splitLines('ui', content), lines = contents.length;
// 计算总高度按1.4倍行距计算
var width = 416, height = textfont * 1.4 * lines;
var tempCanvas = core.bigmap.tempCanvas;
tempCanvas.canvas.width = width;
tempCanvas.canvas.height = height;
tempCanvas.clearRect(0, 0, width, height);
tempCanvas.font = font;
tempCanvas.fillStyle = textColor;
// 全部绘制
var currH = textfont;
for (var i = 0; i < lines; ++i) {
var text = contents[i];
tempCanvas.fillText(text, offset, currH);
currH += 1.4 * textfont;
}
return tempCanvas.canvas;
}
////// 移动图片 //////
events.prototype.moveImage = function (image, from, to, time, keep, callback) {
events.prototype.moveImage = function (code, to, opacityVal, time, callback) {
time = time || 1000;
clearInterval(core.interval.tipAnimate);
core.setAlpha('data', 1);
var width = image.width, height = image.height;
var name = "image"+ (code+100), index = core.findCanvas(name);
if (index == -1) {
console.log(code+"号图片不存在")
if (core.isset(callback)) callback();
return;
}
var fromX = core.dymCanvas._list[index].style.left,
fromY = core.dymCanvas._list[index].style.top,
preX = fromX, preY = fromY, toX = fromX, toY = fromY;
// core.status.replay.animate=true;
var fromX = core.calValue(from[0]), fromY = core.calValue(from[1]),
toX = core.calValue(to[0]), toY = core.calValue(to[1]);
if (keep) core.clearMap('image', fromX, fromY, width, height);
var step = 0, preX = fromX, preY = fromY;
var per_time = 10, steps = parseInt(time / per_time);
var drawImage = function () {
preX = parseInt(fromX + (toX-fromX)*step/steps);
preY = parseInt(fromY + (toY-fromY)*step/steps);
core.canvas.data.drawImage(image, preX, preY);
if (core.isset(to)) {
toX = core.calValue(to[0]) || toX;
toY = core.calValue(to[1]) || toY;
}
drawImage();
var step = 0;
var per_time = 10, steps = parseInt(time / per_time);
var preOpac = parseFloat(core.dymCanvas[name].canvas.style.opacity), opacStep = 0;
if (core.isset(opacityVal)) {
opacityVal = core.calValue(opacityVal);
opacStep = (opacityVal - preOpac) / steps;
}
var moveStep = function () {
preOpac += opacStep;
core.setOpacity(name, preOpac);
preX = parseInt(fromX + (toX-fromX)*step/steps);
preY = parseInt(fromY + (toY-fromY)*step/steps);
core.relocateCanvas(name, preX, preY);
}
var animate = setInterval(function () {
core.clearMap('data', preX, preY, width, height);
step++;
if (step <= steps)
drawImage();
else {
moveStep();
if (step > steps) {
if (core.isset(opacityVal))
core.setOpacity(name, opacityVal);
delete core.animateFrame.asyncId[animate];
clearInterval(animate);
if (keep) core.canvas.image.drawImage(image, toX, toY);
if (core.isset(callback)) callback();
}
}, per_time);
@ -1622,21 +1749,20 @@ events.prototype.setVolume = function (value, time, callback) {
if (core.isset(callback)) callback();
return;
}
// core.status.replay.animate=true;
var currVolume = core.musicStatus.volume;
var step = 0;
var per_time = 10, step = 0, steps = parseInt(time / per_time);
var fade = setInterval(function () {
step++;
var nowVolume = currVolume+(value-currVolume)*step/32;
var nowVolume = currVolume+(value-currVolume)*step/steps;
set(nowVolume);
if (step>=32) {
if (step>=steps) {
delete core.animateFrame.asyncId[fade];
clearInterval(fade);
// core.status.replay.animate=false;
if (core.isset(callback))
callback();
}
}, time / 32);
}, per_time);
core.animateFrame.asyncId[fade] = true;
}
@ -1743,20 +1869,18 @@ events.prototype.openShop = function(shopId, needVisited) {
// 拼词
var content = "\t["+shop.name+","+shop.icon+"]";
var times = shop.times, need=eval(shop.need);
var times = shop.times, need=core.calValue(shop.need, null, times);
content = content + shop.text.replace(/\${([^}]+)}/g, function (word, value) {
return eval(value);
});
content += core.replaceText(shop.text, need, times);
var use = shop.use=='experience'?'经验':'金币';
var choices = [];
for (var i=0;i<shop.choices.length;i++) {
var choice = shop.choices[i];
var text = choice.text;
var text = core.replaceText(choice.text, need, times);
if (core.isset(choice.need))
text += ""+eval(choice.need)+use+"";
text += ""+core.calValue(choice.need, null, times)+use+"";
choices.push({"text": text, "color":shop.visited?null:"#999999"});
}
choices.push("离开");
@ -1788,17 +1912,28 @@ events.prototype.setHeroIcon = function (name, noDraw) {
////// 检查升级事件 //////
events.prototype.checkLvUp = function () {
if (!core.flags.enableLevelUp || !core.isset(core.firstData.levelUp)
|| core.status.hero.lv>=core.firstData.levelUp.length) return;
// 计算下一个所需要的数值
var need=core.calValue((core.firstData.levelUp[core.status.hero.lv]||{}).need);
if (!core.isset(need)) return;
if (core.status.hero.experience>=need) {
// 升级
core.status.hero.lv++;
core.insertAction(core.firstData.levelUp[core.status.hero.lv-1].action);
this.checkLvUp();
var check = function () {
if (!core.flags.enableLevelUp || !core.isset(core.firstData.levelUp)
|| core.status.hero.lv>=core.firstData.levelUp.length) return null;
// 计算下一个所需要的数值
var next = (core.firstData.levelUp[core.status.hero.lv]||{});
var need = core.calValue(next.need);
if (!core.isset(need)) return null;
if (core.status.hero.experience>=need) {
// 升级
core.status.hero.lv++;
if (next.clear) core.status.hero.experience -= need;
return next.action||[];
}
return null;
}
var actions = [];
while (true) {
var next = check();
if (next == null) break;
actions = actions.concat(next);
}
if (actions.length>0) core.insertAction(actions);
}
////// 尝试使用道具 //////
@ -1870,13 +2005,14 @@ events.prototype.passNet = function (data) {
if (data.event.id=='weakNet') { // 衰网
if (core.hasFlag('weak')) return;
core.setFlag('weak', true);
var weakValue = core.values.weakValue;
var weakAtk = weakValue>=1?weakValue:Math.floor(weakValue*core.status.hero.atk);
var weakDef = weakValue>=1?weakValue:Math.floor(weakValue*core.status.hero.def);
core.setFlag('weakAtk', weakAtk);
core.setFlag('weakDef', weakDef);
core.status.hero.atk-=weakAtk;
core.status.hero.def-=weakDef;
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 (data.event.id=='curseNet') { // 咒网
if (core.hasFlag('curse')) return;

View File

@ -72,7 +72,12 @@ items.prototype.useItem = function (itemId, callback) {
var itemCls = core.material.items[itemId].cls;
if (itemId in this.useItemEffect) {
eval(this.useItemEffect[itemId]);
try {
eval(this.useItemEffect[itemId]);
}
catch (e) {
console.log(e);
}
}
// 记录路线
if (itemId!='book' && itemId!='fly') {
@ -82,10 +87,11 @@ items.prototype.useItem = function (itemId, callback) {
// 道具使用完毕:删除
if (itemCls=='tools')
core.status.hero.items[itemCls][itemId]--;
if (core.status.hero.items[itemCls][itemId]==0)
if (core.status.hero.items[itemCls][itemId]<=0)
delete core.status.hero.items[itemCls][itemId];
core.updateStatusBar();
if (!core.isset(core.status.event.id)) core.status.event.data = null;
if (core.isset(callback)) callback();
}
@ -95,11 +101,18 @@ items.prototype.canUseItem = function (itemId) {
// 没有道具
if (!core.hasItem(itemId)) return false;
var able = false;
if (itemId in this.canUseItemEffect) {
return eval(this.canUseItemEffect[itemId]);
try {
able = eval(this.canUseItemEffect[itemId]);
}
catch (e) {
console.log(e);
}
}
if (!able) core.status.event.data = null;
return false;
return able;
}
////// 获得某个物品的个数 //////
@ -107,7 +120,7 @@ items.prototype.itemCount = function (itemId) {
if (!core.isset(itemId) || !core.isset(core.material.items[itemId])) return 0;
var itemCls = core.material.items[itemId].cls;
if (itemCls=="items") return 0;
return core.isset(core.status.hero.items[itemCls][itemId]) ? core.status.hero.items[itemCls][itemId] : 0;
return core.status.hero.items[itemCls][itemId]||0;
}
////// 是否存在某个物品 //////
@ -121,7 +134,7 @@ items.prototype.hasEquip = function (itemId) {
if (!core.isset(itemId)) return null;
if (!core.isset((core.material.items[itemId]||{}).equip)) return null;
return itemId == this.getEquip(core.material.items[itemId].equip.type);
return this.getEquip(core.material.items[itemId].equip.type) == itemId;
}
////// 获得某个装备类型的当前装备 //////
@ -132,16 +145,17 @@ items.prototype.getEquip = function (equipType) {
////// 设置某个物品的个数 //////
items.prototype.setItem = function (itemId, itemNum) {
itemNum = itemNum || 0;
if (itemNum<=0) itemNum = 0;
var itemCls = core.material.items[itemId].cls;
if (itemCls == 'items') return;
if (!core.isset(core.status.hero.items[itemCls])) {
core.status.hero.items[itemCls] = {};
}
core.status.hero.items[itemCls][itemId] = itemNum;
if (itemCls!='keys' && itemNum==0) {
delete core.status.hero.items[itemCls][itemId];
if (core.status.hero.items[itemCls][itemId] <= 0) {
if (itemCls!='keys') delete core.status.hero.items[itemCls][itemId];
else core.status.hero.items[itemCls][itemId] = 0;
}
core.updateStatusBar();
}
////// 删除某个物品 //////
@ -150,8 +164,9 @@ items.prototype.removeItem = function (itemId, itemNum) {
if (!core.hasItem(itemId)) return false;
var itemCls = core.material.items[itemId].cls;
core.status.hero.items[itemCls][itemId]-=itemNum;
if (itemCls!='keys' && core.status.hero.items[itemCls][itemId]<=0) {
delete core.status.hero.items[itemCls][itemId];
if (core.status.hero.items[itemCls][itemId] <= 0) {
if (itemCls!='keys') delete core.status.hero.items[itemCls][itemId];
else core.status.hero.items[itemCls][itemId] = 0;
}
core.updateStatusBar();
return true;
@ -159,7 +174,7 @@ items.prototype.removeItem = function (itemId, itemNum) {
////// 增加某个物品的个数 //////
items.prototype.addItem = function (itemId, itemNum) {
itemNum=itemNum||1;
itemNum = itemNum || 1;
var itemData = core.material.items[itemId];
var itemCls = itemData.cls;
if (itemCls == 'items') return;
@ -171,9 +186,14 @@ items.prototype.addItem = function (itemId, itemNum) {
core.status.hero.items[itemCls][itemId] = 0;
}
core.status.hero.items[itemCls][itemId] += itemNum;
if (core.status.hero.items[itemCls][itemId] <= 0) {
if (itemCls!='keys') delete core.status.hero.items[itemCls][itemId];
else core.status.hero.items[itemCls][itemId] = 0;
}
// 永久道具只能有一个
if (itemCls == 'constants' && core.status.hero.items[itemCls][itemId]>1)
core.status.hero.items[itemCls][itemId] = 1;
core.updateStatusBar();
}
@ -182,28 +202,45 @@ items.prototype.loadEquip = function (equipId, callback) {
if (!core.isset(core.status.hero.equipment)) core.status.hero.equipment = [];
var loadEquip = core.material.items[equipId];
if (!core.isset(loadEquip)) {
var loadEquip = core.material.items[equipId]||{};
if (!core.isset(loadEquip.equip)) {
if (core.isset(callback)) callback();
return;
}
var can = this.canEquip[equipId];
if (core.isset(can) && !eval(can)) {
core.drawTip("当前不可换上"+loadEquip.name);
if (core.isset(callback)) callback();
return;
if (core.isset(can)) {
try {
if (!eval(can)) {
core.drawTip("当前不可换上"+loadEquip.name);
if (core.isset(callback)) callback();
return;
}
}
catch (e) {
console.log(e);
}
}
core.playSound('equip.mp3');
var loadEquipType = loadEquip.equip.type;
var unloadEquipId = core.status.hero.equipment[loadEquipType];
var unloadEquip = core.material.items[unloadEquipId] || {};
// ------ 如果当前装备和目标装备的模式不同(一个百分比一个数值),则需要先脱再穿 ------ //
if (core.isset(unloadEquip.equip) && (unloadEquip.equip.percentage||false) != (loadEquip.equip.percentage||false)) {
this.unloadEquip(loadEquipType);
this.loadEquip(equipId);
if (core.isset(callback)) callback();
return;
}
// 下面保证了两者的模式是相同的
// 比较能力值
var result = core.compareEquipment(equipId,unloadEquipId);
if (core.flags.equipPercentage) {
if (loadEquip.equip.percentage) {
core.setFlag('equip_atk_buff', core.getFlag('equip_atk_buff',1)+result.atk/100);
core.setFlag('equip_def_buff', core.getFlag('equip_def_buff',1)+result.def/100);
core.setFlag('equip_mdef_buff', core.getFlag('equip_mdef_buff',1)+result.mdef/100);
@ -218,9 +255,6 @@ items.prototype.loadEquip = function (equipId, callback) {
core.status.hero.equipment[loadEquipType] = equipId;
core.updateStatusBar();
// 记录路线
// core.status.route.push("equip:"+equipId);
// 装备更换完毕:删除换上的装备
core.removeItem(equipId);
@ -245,10 +279,10 @@ items.prototype.unloadEquip = function (equipType, callback) {
if (core.isset(callback)) callback();
return;
}
var unloadEquip = core.material.items[unloadEquipId];
var unloadEquip = core.material.items[unloadEquipId] || {};
// 处理能力值改变
if (core.flags.equipPercentage) {
if (unloadEquip.equip.percentage) {
core.setFlag('equip_atk_buff', core.getFlag('equip_atk_buff',1)-(unloadEquip.equip.atk||0)/100);
core.setFlag('equip_def_buff', core.getFlag('equip_def_buff',1)-(unloadEquip.equip.def||0)/100);
core.setFlag('equip_mdef_buff', core.getFlag('equip_mdef_buff',1)-(unloadEquip.equip.mdef||0)/100);
@ -263,9 +297,6 @@ items.prototype.unloadEquip = function (equipType, callback) {
core.status.hero.equipment[equipType] = null;
core.updateStatusBar();
// 记录路线
// core.status.route.push("unEquip:"+equipType);
// 装备更换完毕:增加卸下的装备
core.addItem(unloadEquipId, 1);

View File

@ -106,14 +106,10 @@ loader.prototype.loadImage = function (imgName, callback) {
if (name.indexOf(".")<0)
name=name+".png";
var image = new Image();
image.src = 'project/images/' + name + "?v=" + main.version;
if (image.complete) {
callback(imgName, image);
return;
}
image.onload = function () {
callback(imgName, image);
}
image.src = 'project/images/' + name + "?v=" + main.version;
}
catch (e) {
console.log(e);
@ -212,12 +208,7 @@ loader.prototype.loadMusic = function () {
}
}
else {
var music = new Audio();
music.preload = 'none';
if (main.bgmRemote) music.src = main.bgmRemoteRoot+core.firstData.name+'/'+t;
else music.src = 'project/sounds/'+t;
music.loop = 'loop';
core.material.bgms[t] = music;
core.loader.loadOneMusic(t);
}
});
@ -238,7 +229,7 @@ loader.prototype.loadMusic = function () {
console.log(ee);
core.material.sounds[t] = null;
}
}, function () {
}, function (e) {
console.log(e);
core.material.sounds[t] = null;
}, null, 'arraybuffer');
@ -255,3 +246,45 @@ loader.prototype.loadMusic = function () {
if (core.musicStatus.startDirectly && core.bgms.length>0)
core.playBgm(core.bgms[0]);
}
loader.prototype.loadOneMusic = function (name) {
var music = new Audio();
music.preload = 'none';
if (main.bgmRemote) music.src = main.bgmRemoteRoot+core.firstData.name+'/'+name;
else music.src = 'project/sounds/'+name;
music.loop = 'loop';
core.material.bgms[name] = music;
}
loader.prototype.freeBgm = function (name) {
if (!core.isset(core.material.bgms[name])) return;
// 从cachedBgms中删除
core.musicStatus.cachedBgms = core.musicStatus.cachedBgms.filter(function (t) {return t!=name; });
// 清掉缓存
core.material.bgms[name].removeAttribute("src");
core.material.bgms[name].load();
core.material.bgms[name] = null;
// 三秒后重新加载
setTimeout(function () {
core.loader.loadOneMusic(name);
}, 3000);
}
loader.prototype.loadBgm = function (name) {
if (!core.isset(core.material.bgms[name])) return;
// 是否已经预加载过
var index = core.musicStatus.cachedBgms.indexOf(name);
if (index>=0) {
core.musicStatus.cachedBgms.splice(index, 1);
}
else {
// 预加载BGM
core.material.bgms[name].load();
// 清理尾巴
if (core.musicStatus.cachedBgms.length == core.musicStatus.cachedBgmCount) {
this.freeBgm(core.musicStatus.cachedBgms.pop());
}
}
// 移动到缓存最前方
core.musicStatus.cachedBgms.unshift(name);
}

View File

@ -18,7 +18,7 @@ maps.prototype.loadFloor = function (floorId, map) {
map = {"map": map};
}
var content = {};
["floorId", "title", "name", "canFlyTo", "canUseQuickShop", "cannotViewMap", "color", "weather",
["floorId", "title", "name", "canFlyTo", "canUseQuickShop", "cannotViewMap", "cannotMoveDirectly", "color", "weather",
"defaultGround", "images", "item_ratio", "upFloor", "bgm", "downFloor", "underGround"].forEach(function (e) {
if (core.isset(map[e])) content[e] = core.clone(map[e]);
else content[e] = core.clone(floor[e]);
@ -146,9 +146,13 @@ maps.prototype.addEvent = function (block, x, y, event) {
if (!core.isset(block.disable) && core.isset(event.enable)) {
block.disable=!event.enable;
}
// 覆盖animate
if (event.animate === false) {
block.event.animate = 1;
}
// 覆盖所有属性
for (var key in event) {
if (key!="enable" && core.isset(event[key])) {
if (key!="enable" && key!="animate" && core.isset(event[key])) {
block.event[key]=core.clone(event[key]);
}
}
@ -317,6 +321,12 @@ maps.prototype.canMoveDirectly = function (destX,destY) {
// 不可瞬间移动请返回-1
if (!core.flags.enableMoveDirectly) return -1;
// 检查该楼层是否不可瞬间移动
if (core.status.thisMap.cannotMoveDirectly) return -1;
// flag:cannotMoveDirectly为true不能
if (core.hasFlag('cannotMoveDirectly')) return -1;
// 中毒状态:不能
if (core.hasFlag('poison')) return -1;
@ -360,29 +370,13 @@ maps.prototype.drawBlock = function (block, animate, dx, dy) {
// none空地
if (block.event.id=='none') return;
var cls = block.event.cls, height = block.event.height || 32;
var cls = block.event.cls;
var image, x, y;
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);
if (cls == 'tileset') {
var offset = core.icons.getTilesetOffset(block.event.id);
if (offset == null) return;
image = core.material.images.tilesets[offset.image];
x = offset.x;
y = offset.y;
}
else if (cls == 'autotile') return;
// 空气墙的单独处理
else if (block.id==17) {
if (!core.isset(core.material.images.airwall)) return;
image = core.material.images.airwall;
x = y = 0;
}
else {
image = core.material.images[cls];
x = (animate||0)%(block.event.animate||1);
y = core.material.icons[cls][block.event.id];
}
dx = dx || 0;
dy = dy || 0;
@ -476,13 +470,13 @@ maps.prototype.drawBgFgMap = function (floorId, canvas, name, animate) {
}
}
}
core.status.autotileAnimateObjs[name+"map"] = core.clone(arr);
if (animate) core.status.autotileAnimateObjs[name+"map"] = core.clone(arr);
}
////// 绘制某张地图 //////
maps.prototype.drawMap = function (mapName, callback) {
mapName = mapName || core.status.floorId;
if (!core.isset(mapName)) {
maps.prototype.drawMap = function (floorId, callback) {
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) {
if (core.isset(callback))
callback();
return;
@ -491,10 +485,10 @@ maps.prototype.drawMap = function (mapName, callback) {
core.removeGlobalAnimate(null, null, true);
var drawBg = function(){
var width = core.floors[mapName].width || 13;
var height = core.floors[mapName].height || 13;
var width = core.floors[floorId].width || 13;
var height = core.floors[floorId].height || 13;
var groundId = (core.status.maps||core.floors)[mapName].defaultGround || "ground";
var groundId = (core.status.maps||core.floors)[floorId].defaultGround || "ground";
var blockIcon = core.material.icons.terrains[groundId];
for (var x = 0; x < width; x++) {
for (var y = 0; y < height; y++) {
@ -503,8 +497,8 @@ maps.prototype.drawMap = function (mapName, callback) {
}
var images = [];
if (core.isset(core.status.maps[mapName].images)) {
images = core.status.maps[mapName].images;
if (core.isset(core.status.maps[floorId].images)) {
images = core.status.maps[floorId].images;
if (typeof images == 'string') {
images = [[0, 0, images]];
}
@ -513,7 +507,7 @@ maps.prototype.drawMap = function (mapName, callback) {
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_"+mapName+"_"+dx+"_"+dy) &&
!core.hasFlag("floorimg_"+floorId+"_"+dx+"_"+dy) &&
core.isset(core.material.images.images[p])) {
var image = core.material.images.images[p];
if (!t[3]) {
@ -543,8 +537,8 @@ maps.prototype.drawMap = function (mapName, callback) {
}
});
core.maps.drawBgFgMap(mapName, core.canvas.bg, "bg", true);
core.maps.drawBgFgMap(mapName, core.canvas.fg, "fg", true);
core.maps.drawBgFgMap(floorId, core.canvas.bg, "bg", true);
core.maps.drawBgFgMap(floorId, core.canvas.fg, "fg", true);
}
if (main.mode=='editor'){
@ -560,8 +554,8 @@ maps.prototype.drawMap = function (mapName, callback) {
drawBg();
}
core.status.floorId = mapName;
core.status.thisMap = core.status.maps[mapName];
core.status.floorId = floorId;
core.status.thisMap = core.status.maps[floorId];
var drawEvent = function(){
var mapData = core.status.maps[core.status.floorId];
@ -766,6 +760,101 @@ maps.prototype.getBlockCls = function (x, y, floorId, showDisable) {
return null;
}
maps.prototype.__getBlockInfo = function (block) {
var image, bx, by, height = block.event.height || 32;
var faceIds = {}, isTileset = false;
if (block.event.cls == 'tileset') {
var offset = core.icons.getTilesetOffset(block.event.id);
if (offset==null) {
return null;
}
bx = offset.x;
by = offset.y;
image = core.material.images.tilesets[offset.image];
isTileset = true;
}
// 不支持autotile
else if (block.event.cls == 'autotile') {
return null;
}
// 空气墙;忽略事件
else if (block.id==17) {
if (!core.isset(core.material.images.airwall)) return null;
image = core.material.images.airwall;
bx = by = 0;
}
else {
image = core.material.images[block.event.cls];
bx = 0;
by = core.material.icons[block.event.cls][block.event.id];
faceIds = block.event.faceIds||{};
}
return {
"image": image,
"bx": bx,
"by": by,
"height": height,
"isTileset": isTileset,
"faceIds": faceIds
};
}
maps.prototype.__moveBlockCanvas = function (image, bx, by, height, nowX, nowY, opacity, headCanvas, bodyCanvas, damageCanvas) {
// 重绘block & 重定位
if (headCanvas != null) {
core.dymCanvas[headCanvas].clearRect(0, 0, 32, height);
core.dymCanvas[headCanvas].drawImage(image, bx * 32, by * height, 32, height - 32, 0, 0, 32, height - 32);
core.relocateCanvas(headCanvas, nowX - core.bigmap.offsetX, nowY+32-height - core.bigmap.offsetY);
core.setOpacity(headCanvas, opacity);
}
if (bodyCanvas != null) {
core.dymCanvas[bodyCanvas].clearRect(0, 0, 32, 32);
core.dymCanvas[bodyCanvas].drawImage(image, bx * 32, by * height + height - 32, 32, 32, 0, 0, 32, 32);
core.relocateCanvas(bodyCanvas, nowX - core.bigmap.offsetX, nowY - core.bigmap.offsetY);
core.setOpacity(bodyCanvas, opacity);
}
if (damageCanvas != null) {
core.relocateCanvas(damageCanvas, nowX - core.bigmap.offsetX, nowY - core.bigmap.offsetY);
core.setOpacity(damageCanvas, opacity);
}
}
maps.prototype.__initBlockCanvas = function (block, height, x, y) {
var headCanvas = null, bodyCanvas = 'block'+x+"_"+y, damageCanvas = null;
core.createCanvas(bodyCanvas, 0, 0, 32, 32, 35);
if (height > 32) {
headCanvas = "blockHead"+x+"_"+y;
core.createCanvas(headCanvas, 0, 0, 32, height - 32, 55);
}
// 显伤
var damage = null, damageColor = null;
if ((block.event.cls == 'enemys' || block.event.cls == 'enemy48') && core.hasItem('book')
&& block.event.displayDamage !== false) {
var damageString = core.enemys.getDamageString(block.event.id, x, y);
damage = damageString.damage; damageColor = damageString.color;
}
if (damage != null) {
damageCanvas = "blockDamage"+x+"_"+y;
core.createCanvas(damageCanvas, 0, 0, 32, 32, 65);
core.dymCanvas[damageCanvas].textAlign = 'left';
core.dymCanvas[damageCanvas].font = "bold 11px Arial";
core.fillBoldText(core.dymCanvas[damageCanvas], damage, damageColor, 1, 31);
if (core.flags.displayCritical) {
var critical = core.enemys.nextCriticals(block.event.id);
if (critical.length>0) critical=critical[0];
critical = core.formatBigNumber(critical[0], true);
if (critical == '???') critical = '?';
core.fillBoldText(core.dymCanvas[damageCanvas], critical, '#FFFFFF', 1, 21);
}
}
return {
"headCanvas": headCanvas,
"bodyCanvas": bodyCanvas,
"damageCanvas": damageCanvas
}
}
////// 显示移动某块的动画,达到{“type”:”move”}的效果 //////
maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) {
time = time || 500;
@ -781,39 +870,12 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) {
core.removeBlock(x,y);
block=block.block;
var image, bx, by, height = block.event.height || 32;
var faceIds = {};
if (block.event.cls == 'tileset') {
var offset = core.icons.getTilesetOffset(block.event.id);
if (offset==null) {
if (core.isset(callback)) callback();
return;
}
bx = offset.x;
by = offset.y;
image = core.material.images.tilesets[offset.image];
}
// 不支持autotile
else if (block.event.cls == 'autotile') {
var blockInfo = this.__getBlockInfo(block);
if (blockInfo == null) {
if (core.isset(callback)) callback();
return;
}
// 空气墙;忽略事件
else if (block.id==17) {
if (core.isset(callback)) callback();
return;
}
else {
image = core.material.images[block.event.cls];
bx = 0;
by = core.material.icons[block.event.cls][block.event.id];
faceIds = block.event.faceIds||{};
}
var alpha = 1;
core.setAlpha('route', alpha);
core.canvas.route.drawImage(image, bx * 32, by * height, 32, height, block.x * 32, block.y * 32 +32 - height, 32, height);
var image = blockInfo.image, bx = blockInfo.bx, by = blockInfo.by, height = blockInfo.height, isTileset = blockInfo.isTileset, faceIds = blockInfo.faceIds;
// 要运行的轨迹将steps展开
var moveSteps=[];
@ -841,9 +903,12 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) {
'right': {'x': 1, 'y': 0}
};
var animateValue = block.event.animate || 1;
var animateCurrent = 0;
var animateTime = 0;
var animateValue = block.event.animate || 1, animateCurrent = isTileset?bx:0, animateTime = 0;
var blockCanvas = this.__initBlockCanvas(block, height, x, y);
var headCanvas = blockCanvas.headCanvas, bodyCanvas = blockCanvas.bodyCanvas, damageCanvas = blockCanvas.damageCanvas;
var opacity = 1;
core.maps.__moveBlockCanvas(image, animateCurrent, by, height, nowX, nowY, opacity, headCanvas, bodyCanvas, damageCanvas);
var animate=window.setInterval(function() {
@ -853,30 +918,27 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) {
animateTime = 0;
if (animateCurrent>=animateValue) animateCurrent=0;
}
if (block.event.cls=='tileset') {
animateCurrent = bx;
}
if (isTileset) animateCurrent = bx;
// 已经移动完毕,消失
if (moveSteps.length==0) {
if (keep) alpha=0;
else alpha -= 0.06;
core.clearMap('route', nowX, nowY-height+32, 32, height);
if (alpha<=0) {
if (keep) opacity=0;
else opacity -= 0.06;
if (opacity<=0) {
delete core.animateFrame.asyncId[animate];
clearInterval(animate);
core.deleteCanvas(headCanvas);
core.deleteCanvas(bodyCanvas);
core.deleteCanvas(damageCanvas);
// 不消失
if (keep) {
core.setBlock(id, nowX/32, nowY/32);
core.showBlock(nowX/32, nowY/32);
}
core.setAlpha('route',1);
if (core.isset(callback)) callback();
}
else {
core.setAlpha('route', alpha);
core.canvas.route.drawImage(image, animateCurrent * 32, by * height, 32, height, nowX, nowY-height+32, 32, height);
core.setAlpha('route', 1);
core.maps.__moveBlockCanvas(image, animateCurrent, by, height, nowX, nowY, opacity, headCanvas, bodyCanvas, damageCanvas);
}
}
else {
@ -891,13 +953,11 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) {
by = tby;
}
}
core.clearMap('route', nowX, nowY-height+32, 32, height);
step++;
nowX+=scan[direction].x*2;
nowY+=scan[direction].y*2;
// 绘制
core.canvas.route.drawImage(image, animateCurrent * 32, by * height, 32, height, nowX, nowY-height+32, 32, height);
// 移动
core.maps.__moveBlockCanvas(image, animateCurrent, by, height, nowX, nowY, opacity, headCanvas, bodyCanvas, damageCanvas);
if (step==16) {
// 该移动完毕,继续
step=0;
@ -924,36 +984,12 @@ maps.prototype.jumpBlock = function(sx,sy,ex,ey,time,keep,callback) {
core.removeBlock(sx,sy);
block=block.block;
var image, bx, by, height = block.event.height || 32;
if (block.event.cls == 'tileset') {
var offset = core.icons.getTilesetOffset(block.event.id);
if (offset==null) {
if (core.isset(callback)) callback();
return;
}
bx = offset.x;
by = offset.y;
image = core.material.images.tilesets[offset.image];
}
// 不支持autotile
else if (block.event.cls == 'autotile') {
var blockInfo = this.__getBlockInfo(block);
if (blockInfo == null) {
if (core.isset(callback)) callback();
return;
}
// 空气墙;忽略事件
else if (block.id==17) {
if (core.isset(callback)) callback();
return;
}
else {
image = core.material.images[block.event.cls];
bx = 0;
by = core.material.icons[block.event.cls][block.event.id];
}
var alpha = 1;
core.setAlpha('route', alpha);
core.canvas.route.drawImage(image, bx*32, by * height, 32, height, block.x * 32, block.y * 32 +32 - height, 32, height);
var image = blockInfo.image, bx = blockInfo.bx, by = blockInfo.by, height = blockInfo.height, isTileset = blockInfo.isTileset, faceIds = blockInfo.faceIds;
core.playSound('jump.mp3');
@ -981,35 +1017,27 @@ maps.prototype.jumpBlock = function(sx,sy,ex,ey,time,keep,callback) {
curry = (curry * jump_count + ey) / (jump_count + 1.0);
}
var animateValue = block.event.animate || 1;
var animateCurrent = 0;
var animateTime = 0;
var blockCanvas = this.__initBlockCanvas(block, height, sx, sy);
var headCanvas = blockCanvas.headCanvas, bodyCanvas = blockCanvas.bodyCanvas, damageCanvas = blockCanvas.damageCanvas;
var opacity = 1;
core.maps.__moveBlockCanvas(image, bx, by, height, drawX(), drawY(), opacity, headCanvas, bodyCanvas, damageCanvas);
var animate=window.setInterval(function() {
animateTime += time / 16 / core.status.replay.speed;
if (animateTime >= core.values.animateSpeed) {
animateCurrent++;
animateTime = 0;
if (animateCurrent >= animateValue) animateCurrent = 0;
}
if (block.event.cls=='tileset') {
animateCurrent = bx;
}
if (jump_count>0) {
core.clearMap('route', drawX(), drawY()-height+32, 32, height);
updateJump();
core.canvas.route.drawImage(image, animateCurrent * 32, by * height, 32, height, drawX(), drawY()-height+32, 32, height);
core.maps.__moveBlockCanvas(image, bx, by, height, drawX(), drawY(), opacity, headCanvas, bodyCanvas, damageCanvas);
}
else {
if (keep) alpha=0;
else alpha -= 0.06;
core.clearMap('route', drawX(), drawY()-height+32, 32, height);
if (alpha<=0) {
if (keep) opacity=0;
else opacity -= 0.06;
if (opacity<=0) {
delete core.animateFrame.asyncId[animate];
clearInterval(animate);
core.clearMap('route');
core.setAlpha('route', 1);
core.deleteCanvas(headCanvas);
core.deleteCanvas(bodyCanvas);
core.deleteCanvas(damageCanvas);
if (keep) {
core.setBlock(id, ex, ey);
core.showBlock(ex, ey);
@ -1017,9 +1045,7 @@ maps.prototype.jumpBlock = function(sx,sy,ex,ey,time,keep,callback) {
if (core.isset(callback)) callback();
}
else {
core.setAlpha('route', alpha);
core.canvas.route.drawImage(image, animateCurrent * 32, by * height, 32, height, drawX(), drawY()-height+32, 32, height);
core.setAlpha('route', 1);
core.maps.__moveBlockCanvas(image, bx, by, height, drawX(), drawY(), opacity, headCanvas, bodyCanvas, damageCanvas);
}
}
@ -1040,65 +1066,47 @@ maps.prototype.animateBlock = function (loc,type,time,callback) {
var block = core.getBlock(t[0],t[1],null,true);
if (block==null) return;
block=block.block;
var image, bx, by, height = block.event.height || 32;
if (block.event.cls == 'tileset') {
var offset = core.icons.getTilesetOffset(block.event.id);
if (offset==null) {
if (core.isset(callback)) callback();
return;
}
bx = offset.x;
by = offset.y;
image = core.material.images.tilesets[offset.image];
}
// 不支持autotile
else if (block.event.cls == 'autotile') {
return;
}
// 空气墙,忽略事件
else if (block.id==17) return;
else {
image = core.material.images[block.event.cls];
bx = 0;
by = core.material.icons[block.event.cls][block.event.id];
}
var blockInfo = core.maps.__getBlockInfo(block);
if (blockInfo == null) return;
var blockCanvas = core.maps.__initBlockCanvas(block, blockInfo.height, t[0], t[1]);
var headCanvas = blockCanvas.headCanvas, bodyCanvas = blockCanvas.bodyCanvas, damageCanvas = blockCanvas.damageCanvas;
list.push({
'x': t[0], 'y': t[1], 'height': height,
'bx': bx, 'by': by, 'image': image
})
})
'x': t[0], 'y': t[1], 'height': blockInfo.height,
'bx': blockInfo.bx, 'by': blockInfo.by, 'image': blockInfo.image,
'headCanvas': headCanvas, 'bodyCanvas': bodyCanvas, 'damageCanvas': damageCanvas
});
});
if (list.length==0) {
if (core.isset(callback)) callback();
return;
}
// core.status.replay.animate=true;
var clear = function () {
list.forEach(function (t) {
core.clearMap('route', t.x*32, t.y*32+32-t.height, 32, t.height);
})
}
var opacity = 0;
if (type=='hide') opacity=1;
var draw = function () {
list.forEach(function (t) {
core.canvas.route.drawImage(t.image, t.bx*32, t.by*t.height, 32, t.height, t.x*32, t.y*32+32-t.height, 32, t.height);
core.maps.__moveBlockCanvas(t.image, t.bx, t.by, t.height, t.x*32, t.y*32, opacity, t.headCanvas, t.bodyCanvas, t.damageCanvas);
})
}
var alpha = 0;
if (type=='hide') alpha=1;
core.setAlpha('route', alpha);
};
draw();
var animate = window.setInterval(function () {
if (type=='show') alpha += 0.1;
else alpha -= 0.1;
clear();
if (alpha >=1 || alpha<=0) {
var per_time = 10, steps = parseInt(time / per_time), delta = 1 / steps;
var animate = setInterval(function () {
if (type=='show') opacity += delta;
else opacity -= delta;
if (opacity >=1 || opacity<=0) {
delete core.animateFrame.asyncId[animate];
clearInterval(animate);
core.setAlpha('route', 1);
list.forEach(function (t) {
core.deleteCanvas(t.headCanvas);
core.deleteCanvas(t.bodyCanvas);
core.deleteCanvas(t.damageCanvas);
});
if (type == 'show') {
loc.forEach(function (t) {
core.showBlock(t[0],t[1],data.floorId);
@ -1112,10 +1120,9 @@ maps.prototype.animateBlock = function (loc,type,time,callback) {
if (core.isset(callback)) callback();
}
else {
core.setAlpha('route', alpha);
draw();
}
}, time / 10 / core.status.replay.speed);
}, per_time);
core.animateFrame.asyncId[animate] = true;
}
@ -1449,13 +1456,12 @@ maps.prototype.setBgFgMap = function (type, name, loc, floorId, callback) {
maps.prototype.resetMap = function(floorId) {
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) return;
core.status.maps[floorId] = this.loadFloor(floorId);
if (floorId==core.status.floorId) {
this.drawMap(floorId, function () {
core.drawTip("地图重置成功");
})
}
else {
core.drawTip(floorId+"地图重置成功");
}
if (typeof floorId == 'string') floorId = [floorId];
var needRefresh = false;
floorId.forEach(function (t) {
core.status.maps[t] = core.maps.loadFloor(t);
if (t == core.status.floorId) needRefresh = true;
});
if (needRefresh) this.drawMap(core.status.floorId);
core.drawTip("地图重置成功");
}

View File

@ -17,9 +17,17 @@ ui.prototype.init = function () {
////////////////// 地图设置
ui.prototype.getContextByName = function (name) {
if (core.isset(core.canvas[name]))
return core.canvas[name];
if (core.isset(core.dymCanvas[name]))
return core.dymCanvas[name];
return null;
}
////// 清除地图 //////
ui.prototype.clearMap = function (map, x, y, width, height) {
if (map == 'all') {
ui.prototype.clearMap = function (name, x, y, width, height) {
if (name == 'all') {
for (var m in core.canvas) {
// 不擦除curtain层
if (m=='curtain') continue;
@ -28,144 +36,144 @@ ui.prototype.clearMap = function (map, x, y, width, height) {
core.dom.gif.innerHTML = "";
}
else {
core.canvas[map].clearRect(x||0, y||0, width||core.bigmap.width*32, height||core.bigmap.height*32);
var ctx = this.getContextByName(name);
if (ctx) ctx.clearRect(x||0, y||0, width||ctx.canvas.width, height||ctx.canvas.height);
}
}
////// 在某个canvas上绘制一段文字 //////
ui.prototype.fillText = function (map, text, x, y, style, font) {
ui.prototype.fillText = function (name, text, x, y, style, font) {
if (core.isset(style)) {
core.setFillStyle(map, style);
core.setFillStyle(name, style);
}
if (core.isset(font)) {
core.setFont(map, font);
core.setFont(name, font);
}
core.canvas[map].fillText(text, x, y);
var ctx = this.getContextByName(name);
if (ctx) ctx.fillText(text, x, y);
}
////// 在某个canvas上绘制粗体 //////
ui.prototype.fillBoldText = function (canvas, text, style, x, y, font) {
if (core.isset(font)) canvas.font = font;
canvas.fillStyle = '#000000';
canvas.fillText(text, x-1, y-1);
canvas.fillText(text, x-1, y+1);
canvas.fillText(text, x+1, y-1);
canvas.fillText(text, x+1, y+1);
canvas.fillStyle = style;
canvas.fillText(text, x, y);
}
////// 在某个canvas上绘制一个矩形 //////
ui.prototype.fillRect = function (map, x, y, width, height, style) {
ui.prototype.fillRect = function (name, x, y, width, height, style) {
if (core.isset(style)) {
core.setFillStyle(map, style);
core.setFillStyle(name, style);
}
core.canvas[map].fillRect(x, y, width, height);
var ctx = this.getContextByName(name);
if (ctx) ctx.fillRect(x, y, width, height);
}
////// 在某个canvas上绘制一个矩形的边框 //////
ui.prototype.strokeRect = function (map, x, y, width, height, style, lineWidth) {
ui.prototype.strokeRect = function (name, x, y, width, height, style, lineWidth) {
if (core.isset(style)) {
core.setStrokeStyle(map, style);
core.setStrokeStyle(name, style);
}
if (core.isset(lineWidth)) {
core.setLineWidth(map, lineWidth);
core.setLineWidth(name, lineWidth);
}
core.canvas[map].strokeRect(x, y, width, height);
var ctx = this.getContextByName(name);
if (ctx) ctx.strokeRect(x, y, width, height);
}
////// 在某个canvas上绘制一条线 //////
ui.prototype.drawLine = function (map, x1, y1, x2, y2, style, lineWidth) {
ui.prototype.drawLine = function (name, x1, y1, x2, y2, style, lineWidth) {
if (core.isset(style)) {
core.setStrokeStyle(map, style);
core.setStrokeStyle(name, style);
}
if (core.isset(lineWidth)) {
core.setLineWidth(map, lineWidth);
core.setLineWidth(name, lineWidth);
}
var ctx = this.getContextByName(name);
if (ctx) {
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
}
core.canvas[map].beginPath();
core.canvas[map].moveTo(x1, y1);
core.canvas[map].lineTo(x2, y2);
core.canvas[map].stroke();
}
////// 在某个canvas上绘制一个箭头 //////
ui.prototype.drawArrow = function (map, x1, y1, x2, y2, style, lineWidth) {
ui.prototype.drawArrow = function (name, x1, y1, x2, y2, style, lineWidth) {
if (x1==x2 && y1==y2) return;
if (core.isset(style)) {
core.setStrokeStyle(map, style);
core.setStrokeStyle(name, style);
}
if (core.isset(lineWidth)) {
core.setLineWidth(map, lineWidth);
core.setLineWidth(name, lineWidth);
}
var ctx = this.getContextByName(name);
if (ctx) {
var head = 10;
var dx = x2-x1, dy=y2-y1;
var angle = Math.atan2(dy,dx);
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineTo(x2, y2);
ctx.lineTo(x2-head*Math.cos(angle-Math.PI/6),y2-head*Math.sin(angle-Math.PI/6));
ctx.moveTo(x2, y2);
ctx.lineTo(x2-head*Math.cos(angle+Math.PI/6),y2-head*Math.sin(angle+Math.PI/6));
ctx.stroke();
}
var head = 10;
var dx = x2-x1, dy=y2-y1;
var angle = Math.atan2(dy,dx);
core.canvas[map].beginPath();
core.canvas[map].moveTo(x1,y1);
core.canvas[map].lineTo(x2, y2);
core.canvas[map].lineTo(x2-head*Math.cos(angle-Math.PI/6),y2-head*Math.sin(angle-Math.PI/6));
core.canvas[map].moveTo(x2, y2);
core.canvas[map].lineTo(x2-head*Math.cos(angle+Math.PI/6),y2-head*Math.sin(angle+Math.PI/6));
core.canvas[map].stroke();
}
////// 设置某个canvas的文字字体 //////
ui.prototype.setFont = function (map, font) {
core.canvas[map].font = font;
ui.prototype.setFont = function (name, font) {
var ctx = this.getContextByName(name);
if (ctx) ctx.font = font;
}
////// 设置某个canvas的线宽度 //////
ui.prototype.setLineWidth = function (map, lineWidth) {
if (map == 'all') {
for (var m in core.canvas) {
core.canvas[m].lineWidth = lineWidth;
}
}
core.canvas[map].lineWidth = lineWidth;
ui.prototype.setLineWidth = function (name, lineWidth) {
var ctx = this.getContextByName(name);
if (ctx) ctx.lineWidth = lineWidth;
}
////// 保存某个canvas状态 //////
ui.prototype.saveCanvas = function (map) {
core.canvas[map].save();
ui.prototype.saveCanvas = function (name) {
var ctx = this.getContextByName(name);
if (ctx) ctx.save();
}
////// 加载某个canvas状态 //////
ui.prototype.loadCanvas = function (map) {
core.canvas[map].restore();
}
////// 设置某个canvas边框属性 //////
ui.prototype.setStrokeStyle = function (map, style) {
if (map == 'all') {
for (var m in core.canvas) {
core.canvas[m].strokeStyle = style;
}
}
else {
core.canvas[map].strokeStyle = style;
}
ui.prototype.loadCanvas = function (name) {
var ctx = this.getContextByName(name);
if (ctx) ctx.restore();
}
////// 设置某个canvas的alpha值 //////
ui.prototype.setAlpha = function (map, alpha) {
if (map == 'all') {
for (var m in core.canvas) {
core.canvas[m].globalAlpha = alpha;
}
}
else core.canvas[map].globalAlpha = alpha;
ui.prototype.setAlpha = function (name, alpha) {
var ctx = this.getContextByName(name);
if (ctx) ctx.globalAlpha = alpha;
}
////// 设置某个canvas的透明度尽量不要使用本函数而是全部换成setAlpha实现 //////
ui.prototype.setOpacity = function (map, opacity) {
if (map == 'all') {
for (var m in core.canvas) {
core.canvas[m].canvas.style.opacity = opacity;
}
}
else core.canvas[map].canvas.style.opacity = opacity;
ui.prototype.setOpacity = function (name, opacity) {
var ctx = this.getContextByName(name);
if (ctx) ctx.canvas.style.opacity = opacity;
}
////// 设置某个canvas的绘制属性如颜色等 //////
ui.prototype.setFillStyle = function (map, style) {
if (map == 'all') {
for (var m in core.canvas) {
core.canvas[m].fillStyle = style;
}
}
else {
core.canvas[map].fillStyle = style;
}
ui.prototype.setFillStyle = function (name, style) {
var ctx = this.getContextByName(name);
if (ctx) ctx.fillStyle = style;
}
////// 设置某个canvas边框属性 //////
ui.prototype.setStrokeStyle = function (name, style) {
var ctx = this.getContextByName(name);
if (ctx) ctx.strokeStyle = style;
}
///////////////// UI绘制
@ -174,8 +182,7 @@ ui.prototype.setFillStyle = function (map, style) {
ui.prototype.closePanel = function () {
core.status.boxAnimateObjs = [];
clearInterval(core.status.event.interval);
core.clearMap('ui');
core.setAlpha('ui', 1.0);
core.clearLastEvent();
core.unLockControl();
core.status.event.data = null;
core.status.event.id = null;
@ -184,6 +191,14 @@ ui.prototype.closePanel = function () {
core.status.event.interval = null;
}
////// 一般清除事件 //////
ui.prototype.clearLastEvent = function () {
if (core.isset(core.dymCanvas.selector))
core.deleteCanvas("selector");
core.clearMap('ui');
core.setAlpha('ui', 1);
}
////// 左上角绘制一段提示 //////
ui.prototype.drawTip = function (text, itemIcon) {
var textX, textY, width, height, hide = false, alpha = 0;
@ -351,40 +366,59 @@ ui.prototype.getTitleAndIcon = function (content) {
}
// 绘制选择光标
ui.prototype.drawWindowSelector = function(background,canvas,x,y,w,h) {
var dstImage = core.canvas[canvas];
ui.prototype.drawWindowSelector = function(background,x,y,w,h) {
w = Math.round(w), h = Math.round(h);
if (core.isset(core.dymCanvas.selector)) {
core.relocateCanvas("selector", x, y);
core.resizeCanvas("selector", w, h);
}
else {
core.ui.createCanvas("selector", x, y, w, h, 165);
}
core.setOpacity("selector", 0.8);
var dstImage = core.dymCanvas.selector;
// back
dstImage.drawImage(background,130,66,28,28,x+2,y+2,w-4,h-4);
dstImage.drawImage(background, 130, 66, 28, 28, 2, 2,w-4,h-4);
// corner
dstImage.drawImage(background,128,64,2,2,x,y,2,2);
dstImage.drawImage(background,158,64,2,2,x+w-2,y,2,2);
dstImage.drawImage(background,128,94,2,2,x,y+h-2,2,2);
dstImage.drawImage(background,158,94,2,2,x+w-2,y+h-2,2,2);
dstImage.drawImage(background, 128, 64, 2, 2, 0, 0, 2, 2);
dstImage.drawImage(background, 158, 64, 2, 2,w-2, 0, 2, 2);
dstImage.drawImage(background, 128, 94, 2, 2, 0,h-2, 2, 2);
dstImage.drawImage(background, 158, 94, 2, 2,w-2,h-2, 2, 2);
// border
dstImage.drawImage(background,130,64,28,2,x+2,y,w-4,2);
dstImage.drawImage(background,130,94,28,2,x+2,y+h-2,w-4,2);
dstImage.drawImage(background,128,66,2,28,x,y+2,2,h-4);
dstImage.drawImage(background,158,66,2,28,x+w-2,y+2,2,h-4);
dstImage.drawImage(background, 130, 64, 28, 2, 2, 0,w-4, 2);
dstImage.drawImage(background, 130, 94, 28, 2, 2,h-2,w-4, 2);
dstImage.drawImage(background, 128, 66, 2, 28, 0, 2, 2,h-4);
dstImage.drawImage(background, 158, 66, 2, 28,w-2, 2, 2,h-4);
}
// 绘制皮肤
ui.prototype.drawWindowSkin = function(background,canvas,x,y,w,h,direction,px,py) {
// 仿RM窗口皮肤 ↓
var dstImage = core.canvas[canvas];
var dx = 0, dy = 0;
// 绘制背景
dstImage.drawImage(background, 0, 0, 128, 128, x+2, y+2, w-4, h-4);
// 绘制边框
// 上方
dstImage.drawImage(background, 128, 0, 16, 16, x, y, 16, 16);
for (dx = 0; dx < w - 64; dx += 32) {
dstImage.drawImage(background, 144, 0, 32, 16,x+dx+16, y, 32, 16);
dstImage.drawImage(background, 144,48, 32, 16,x+dx+16, y+h-16, 32, 16);
}
dstImage.drawImage(background, 144, 0,w-dx-32, 16,x+dx+16, y,w-dx-32, 16);
dstImage.drawImage(background, 144,48,w-dx-32, 16,x+dx+16, y+h-16,w-dx-32, 16);
dstImage.drawImage(background, 176, 0, 16, 16, x+w-16, y, 16, 16);
// 左右
for (dy = 0; dy < h - 64; dy += 32) {
dstImage.drawImage(background, 128,16, 16, 32, x,y+dy+16, 16, 32);
dstImage.drawImage(background, 176,16, 16, 32, x+w-16,y+dy+16, 16, 32);
}
dstImage.drawImage(background, 128,16, 16,h-dy-32, x,y+dy+16, 16,h-dy-32);
dstImage.drawImage(background, 176,16, 16,h-dy-32, x+w-16,y+dy+16, 16,h-dy-32);
// 下方
dstImage.drawImage(background, 128,48, 16, 16, x, y+h-16, 16, 16);
dstImage.drawImage(background, 176,48, 16, 16, x+w-16, y+h-16, 16, 16);
// back
dstImage.drawImage(background,0,0,128,128,x+1,y+1,w-2,h-2);
// corner
dstImage.drawImage(background,128,0,16,16,x,y,16,16);
dstImage.drawImage(background,176,0,16,16,x+w-16,y,16,16);
dstImage.drawImage(background,128,48,16,16,x,y+h-16,16,16);
dstImage.drawImage(background,176,48,16,16,x+w-16,y+h-16,16,16);
// border
dstImage.drawImage(background,144,0,32,16,x+16,y,w-32,16);
dstImage.drawImage(background,144,48,32,16,x+16,y+h-16,w-32,16);
dstImage.drawImage(background,128,16,16,32,x,y+16,16,h-32);
dstImage.drawImage(background,176,16,16,32,x+w-16,y+16,16,h-32);
// arrow
if(core.isset(px) && core.isset(py)){
if(direction == 'up'){
@ -403,6 +437,11 @@ ui.prototype.calTextBoxWidth = function (canvas, content, min_width, max_width)
// 如果不存在手动换行,则二分自动换行
if (allLines.length == 1) {
var w = core.canvas[canvas].measureText(allLines[0]).width;
if (w<min_width*2.3) return core.clamp(w / 1.4, min_width, max_width);
if (w<max_width*2.2) return core.clamp(w / 2.4, min_width, max_width);
return core.clamp(w / 3.4, min_width, max_width);
/*
var prefer_lines = 3;
var start = Math.floor(min_width), end = Math.floor(max_width);
while (start < end) {
@ -413,6 +452,7 @@ ui.prototype.calTextBoxWidth = function (canvas, content, min_width, max_width)
start = mid + 1;
}
return mid;
*/
}
// 存在手动换行:以最长的为准
else {
@ -496,7 +536,7 @@ ui.prototype.drawTextBox = function(content, showAll) {
content = core.replaceText(content);
core.status.boxAnimateObjs = [];
core.clearMap('ui');
core.clearLastEvent();
// drawImage
content = content.replace(/(\f|\\f)\[(.*?)]/g, function (text, sympol, str) {
@ -530,14 +570,10 @@ ui.prototype.drawTextBox = function(content, showAll) {
validWidth = this.calTextBoxWidth('ui', realContent, min_width, max_width);
width = validWidth + leftSpace + rightSpace;
// left必须在7~416-7-width区间内以保证left>=7right<=416-7
left = core.clamp(32*px+16-width/2, 7, 416-7-width);
left -= core.bigmap.offsetX;
left = core.clamp(32*px+16-width/2-core.bigmap.offsetX, 7, 416-7-width);
right = left + width;
}
var content_left = left + leftSpace;
var height = 30 + (textfont+5)*core.splitLines("ui", realContent, validWidth, font).length;
if (core.isset(name)) height += titlefont + 5;
@ -715,6 +751,62 @@ ui.prototype.drawTextBox = function(content, showAll) {
}
////// 绘制滚动字幕 //////
ui.prototype.drawScrollText = function (content, time, callback) {
content = content || "";
time = time || 5000;
clearInterval(core.status.event.interval);
core.status.event.interval = null;
// 获得颜色的盒子等信息
var textAttribute = core.status.textAttribute || core.initStatus.textAttribute;
var textfont = textAttribute.textfont || 16;
var offset = textAttribute.offset || 15;
var textColor = core.arrayToRGBA(textAttribute.text);
var font = textfont+"px "+core.status.globalAttribute.font;
if (textAttribute.bold) font = "bold "+font;
var contents = core.splitLines('ui', content), lines = contents.length;
// 计算总高度按1.4倍行距计算
var width = 416, height = textfont * 1.4 * lines;
var tempCanvas = core.bigmap.tempCanvas;
tempCanvas.canvas.width = width;
tempCanvas.canvas.height = height;
tempCanvas.clearRect(0, 0, width, height);
tempCanvas.font = font;
tempCanvas.fillStyle = textColor;
// 全部绘制
var currH = textfont;
for (var i = 0; i < lines; ++i) {
var text = contents[i];
tempCanvas.fillText(text, offset, currH);
currH += 1.4 * textfont;
}
// 开始绘制到UI上
core.clearMap('ui');
var per_pixel = 1, per_time = time * per_pixel / (416+height);
var currH = 416;
core.canvas.ui.drawImage(tempCanvas.canvas, 0, currH);
var animate = setInterval(function () {
core.clearMap('ui');
currH -= per_pixel;
if (currH < -height) {
delete core.animateFrame.asyncId[animate];
clearInterval(animate);
if (core.isset(callback)) callback();
return;
}
core.canvas.ui.drawImage(tempCanvas.canvas, 0, currH);
}, per_time);
core.animateFrame.asyncId[animate] = true;
}
////// 绘制一个选项界面 //////
ui.prototype.drawChoices = function(content, choices) {
@ -847,7 +939,7 @@ ui.prototype.drawChoices = function(content, choices) {
while (core.status.event.selection>=choices.length) core.status.event.selection-=choices.length;
var len = core.canvas.ui.measureText(core.replaceText(choices[core.status.event.selection].text || choices[core.status.event.selection])).width;
if (isWindowSkin)
this.drawWindowSelector(background, 'ui' ,208-len/2-5, choice_top + 32 * core.status.event.selection - 20, len+10, 28);
this.drawWindowSelector(background, 208-len/2-5, choice_top + 32 * core.status.event.selection - 20, len+10, 28);
else
core.strokeRect('ui', 208-len/2-5, choice_top + 32 * core.status.event.selection - 20, len+10, 28, "#FFD700", 2);
}
@ -865,9 +957,19 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) {
if (!core.isset(core.status.event.selection) || core.status.event.selection>1) core.status.event.selection=1;
if (core.status.event.selection<0) core.status.event.selection=0;
core.clearMap('ui');
core.setAlpha('ui', 1);
core.setFillStyle('ui', core.material.groundPattern);
core.clearLastEvent();
var background = core.status.textAttribute.background;
var isWindowSkin = false;
if (typeof background == 'string') {
background = core.material.images.images[background];
if (core.isset(background) && background.width==192 && background.height==128) isWindowSkin = true;
else background = core.initStatus.textAttribute.background;
}
if (!isWindowSkin) background = core.arrayToRGBA(background);
var borderColor = core.status.globalAttribute.borderColor;
var textColor = core.arrayToRGBA(core.status.textAttribute.text);
var globalFont = core.status.globalAttribute.font;
core.setFont('ui', "bold 19px "+globalFont);
@ -880,29 +982,35 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) {
var left = Math.min(208 - 40 - parseInt(max_length / 2), 100);
var top = 140 - (lines-1)*30;
var right = 416 - 2 * left, bottom = 416 - 140 - top;
var right = 416 - left, bottom = 416 - 140, width = right - left, height = bottom - top;
var borderColor = core.status.globalAttribute.borderColor;
core.clearMap('ui');
if (isWindowSkin) {
core.setAlpha('ui', 0.85);
this.drawWindowSkin(background,'ui',left,top,width,height);
}
else {
core.fillRect('ui', left, top, width, height, background);
core.strokeRect('ui', left - 1, top - 1, width + 1, height + 1, borderColor, 2);
}
core.setAlpha('ui', 1);
if (core.isPlaying())
core.fillRect('ui', left, top, right, bottom, core.material.groundPattern);
if (core.isPlaying())
core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, borderColor, 2);
core.canvas.ui.textAlign = "center";
for (var i in contents) {
core.fillText('ui', contents[i], 208, top + 50 + i*30, "#FFFFFF");
core.fillText('ui', contents[i], 208, top + 50 + i*30, textColor);
}
core.fillText('ui', "确定", 208 - 38, top + bottom - 35, "#FFFFFF", "bold 17px "+globalFont);
core.fillText('ui', "取消", 208 + 38, top + bottom - 35);
core.fillText('ui', "确定", 208 - 38, bottom - 35, null, "bold 17px "+globalFont);
core.fillText('ui', "取消", 208 + 38, bottom - 35);
var len=core.canvas.ui.measureText("确定").width;
if (core.status.event.selection==0) {
core.strokeRect('ui', 208-38-parseInt(len/2)-5, top+bottom-35-20, len+10, 28, "#FFD700", 2);
}
if (core.status.event.selection==1) {
core.strokeRect('ui', 208+38-parseInt(len/2)-5, top+bottom-35-20, len+10, 28, "#FFD700", 2);
}
var strokeLeft = 208 + (76*core.status.event.selection-38) - parseInt(len/2) - 5;
if (isWindowSkin)
this.drawWindowSelector(background, strokeLeft, bottom-35-20, len+10, 28);
else
core.strokeRect('ui', strokeLeft, bottom-35-20, len+10, 28, "#FFD700", 2);
}
@ -919,8 +1027,6 @@ ui.prototype.drawSwitchs = function() {
"领域显伤: "+(core.flags.displayExtraDamage ? "[ON]" : "[OFF]"),
"新版存档: "+(core.platform.useLocalForage ? "[ON]":"[OFF]"),
"单击瞬移: "+(core.getFlag('clickMove', true) ? "[ON]":"[OFF]"),
"查看工程",
"下载离线版本",
"返回主菜单"
];
this.drawChoices(null, choices);
@ -966,11 +1072,9 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) {
hero_def=Math.max(0, hero_def);
hero_mdef=Math.max(0, hero_mdef);
if (core.flags.equipPercentage) {
hero_atk = Math.floor(core.getFlag('equip_atk_buff',1)*hero_atk);
hero_def = Math.floor(core.getFlag('equip_def_buff',1)*hero_def);
hero_mdef = Math.floor(core.getFlag('equip_mdef_buff',1)*hero_mdef);
}
hero_atk = Math.floor(core.getFlag('equip_atk_buff',1)*hero_atk);
hero_def = Math.floor(core.getFlag('equip_def_buff',1)*hero_def);
hero_mdef = Math.floor(core.getFlag('equip_mdef_buff',1)*hero_mdef);
var enemy = core.material.enemys[monsterId];
var enemyInfo = core.enemys.getEnemyInfo(enemy, hero_hp, hero_atk, hero_def, hero_mdef);
@ -1262,22 +1366,39 @@ ui.prototype.drawWaiting = function(text) {
core.lockControl();
core.status.event.id = 'waiting';
core.clearMap('ui');
core.setAlpha('ui', 1);
core.setFillStyle('ui', core.material.groundPattern);
core.clearLastEvent();
var background = core.status.textAttribute.background;
var isWindowSkin = false;
if (typeof background == 'string') {
background = core.material.images.images[background];
if (core.isset(background) && background.width==192 && background.height==128) isWindowSkin = true;
else background = core.initStatus.textAttribute.background;
}
if (!isWindowSkin) background = core.arrayToRGBA(background);
var borderColor = core.status.globalAttribute.borderColor;
var textColor = core.arrayToRGBA(core.status.textAttribute.text);
var globalFont = core.status.globalAttribute.font;
core.setFont('ui', 'bold 17px '+globalFont);
core.setFont('ui', "bold 19px "+globalFont);
var text_length = core.canvas.ui.measureText(text).width;
var right = Math.max(text_length+50, 220);
var left = 208-parseInt(right/2), top = 208 - 32 - 16, bottom = 416 - 2 * top;
core.fillRect('ui', left, top, right, bottom);
core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2);
core.clearMap('ui');
if (isWindowSkin) {
core.setAlpha('ui', 0.85);
this.drawWindowSkin(background,'ui',left,top,right,bottom);
}
else {
core.fillRect('ui', left, top, right, bottom, background);
core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, borderColor, 2);
}
core.setAlpha('ui', 1);
core.canvas.ui.textAlign = "center";
core.fillText('ui', text, 208, top + 56, '#FFFFFF');
core.fillText('ui', text, 208, top + 56, textColor);
}
@ -1327,7 +1448,7 @@ ui.prototype.drawReplay = function () {
ui.prototype.drawGameInfo = function () {
core.status.event.id = 'gameInfo';
this.drawChoices(null, [
"数据统计", "查看评论", "操作帮助", "关于本塔", "返回上级菜单"
"数据统计", "查看工程", "查看评论", "操作帮助", "关于本塔","下载离线版本", "返回主菜单"
]);
}
@ -1381,11 +1502,7 @@ ui.prototype.drawCursor = function () {
ui.prototype.drawBook = function (index) {
var enemys = core.enemys.getCurrentEnemys(core.floorIds[(core.status.event.selection||{}).index]);
clearInterval(core.interval.tipAnimate);
core.clearMap('data');
core.clearMap('ui');
core.setAlpha('ui', 1);
core.clearLastEvent();
core.setFillStyle('ui', core.material.groundPattern);
core.fillRect('ui', 0, 0, 416, 416);
@ -1482,8 +1599,8 @@ ui.prototype.drawBook = function (index) {
if (line_cnt==2) damageOffset=361;
core.canvas.ui.textAlign = "center";
var damage = enemy.damage;
var damage = enemy.damage;
var color = '#FFFF00';
if (damage == null) {
damage = '无法战斗';
@ -1503,7 +1620,6 @@ ui.prototype.drawBook = function (index) {
}
if (enemy.notBomb)
damage += "[b]";
core.fillText('ui', damage, damageOffset, 62 * i + 50, color, 'bold 13px '+globalFont);
core.canvas.ui.textAlign = "left";
@ -1573,7 +1689,7 @@ ui.prototype.drawBookDetail = function (index) {
u.push(t);
}
});
hints.push(JSON.stringify(u.map(function (v) {return v[0]+":"+v[1];})));
hints.push(JSON.stringify(u.map(function (v) {return core.formatBigNumber(v[0])+":"+core.formatBigNumber(v[1]);})));
}
}
@ -1607,7 +1723,7 @@ ui.prototype.drawBookDetail = function (index) {
hints.push("");
var criticals = core.enemys.nextCriticals(enemyId, 10).map(function (v) {
return v[0]+":"+v[1];
return core.formatBigNumber(v[0])+":"+core.formatBigNumber(v[1]);
});
while (criticals[0]=='0:0') criticals.shift();
hints.push("临界表:"+JSON.stringify(criticals))
@ -1699,8 +1815,7 @@ ui.prototype.drawMaps = function (index, x, y) {
if (!core.isset(index)) {
core.status.event.data = null;
core.clearMap('ui');
core.setAlpha('ui', 1);
core.clearLastEvent();
core.clearMap('animate');
core.fillRect('animate', 0, 0, 416, 416, 'rgba(0,0,0,0.4)');
@ -2034,30 +2149,41 @@ ui.prototype.drawEquipbox = function(index) {
// 比较属性
if (lines.length==1) {
var compare;
var compare, differentMode = false;
if (index<12) compare = core.compareEquipment(null, selectId);
else {
compare = core.compareEquipment(selectId, equipEquipment[equip.equip.type]);
}
var drawOffset = 10;
[['攻击','atk'], ['防御','def'], ['魔防','mdef']].forEach(function (t) {
var title = t[0], name = t[1];
if (!core.isset(compare[name]) || compare[name]==0) return;
var color = '#00FF00';
if (compare[name]<0) color = '#FF0000';
var nowValue = core.getStatus(name), newValue = nowValue + compare[name];
if (core.flags.equipPercentage) {
var nowBuff = core.getFlag('equip_'+name+"_buff",1), newBuff = nowBuff+compare[name]/100;
nowValue = Math.floor(nowBuff*core.getStatus(name));
newValue = Math.floor(newBuff*core.getStatus(name));
var last = core.material.items[equipEquipment[equipType]]||{};
// 检查是不是数值模式和比例模式之间的切换
if (core.isset(last.equip) && (last.equip.percentage||false) != (equip.equip.percentage||false)) {
differentMode = true;
}
var content = title + ' ' + nowValue + '->';
core.fillText('ui', content, drawOffset, 89, '#CCCCCC', 'bold 14px '+globalFont);
drawOffset += core.canvas.ui.measureText(content).width;
core.fillText('ui', newValue, drawOffset, 89, color);
drawOffset += core.canvas.ui.measureText(newValue).width + 15;
})
else {
compare = core.compareEquipment(selectId, equipEquipment[equipType]);
}
}
if (differentMode) {
core.fillText('ui', '<数值和比例模式之间的切换不显示属性变化>', 10, 89, '#CCCCCC', '14px '+globalFont);
}
else {
var drawOffset = 10;
[['攻击','atk'], ['防御','def'], ['魔防','mdef']].forEach(function (t) {
var title = t[0], name = t[1];
if (!core.isset(compare[name]) || compare[name]==0) return;
var color = '#00FF00';
if (compare[name]<0) color = '#FF0000';
var nowValue = core.getStatus(name), newValue = nowValue + compare[name];
if (equip.equip.percentage) {
var nowBuff = core.getFlag('equip_'+name+"_buff",1), newBuff = nowBuff+compare[name]/100;
nowValue = Math.floor(nowBuff*core.getStatus(name));
newValue = Math.floor(newBuff*core.getStatus(name));
}
var content = title + ' ' + nowValue + '->';
core.fillText('ui', content, drawOffset, 89, '#CCCCCC', 'bold 14px '+globalFont);
drawOffset += core.canvas.ui.measureText(content).width;
core.fillText('ui', newValue, drawOffset, 89, color);
drawOffset += core.canvas.ui.measureText(newValue).width + 15;
})
}
}
else {
var leftText = text.substring(lines[0].length);
@ -2154,8 +2280,8 @@ ui.prototype.drawSLPanel = function(index, refresh) {
core.strokeRect('ui', (2*i+1)*u-size/2, 45, size, size, i==offset?strokeColor:'#FFFFFF', i==offset?6:2);
if (core.isset(data) && core.isset(data.floorId)) {
core.ui.drawThumbnail(data.floorId, 'ui', core.maps.load(data.maps, data.floorId).blocks, (2*i+1)*u-size/2, 45, size, data.hero.loc.x, data.hero.loc.y, data.hero.loc, data.hero.flags.heroIcon||"hero.png");
var v = core.formatBigNumber(data.hero.hp)+"/"+core.formatBigNumber(data.hero.atk)+"/"+core.formatBigNumber(data.hero.def);
var v2 = "/"+core.formatBigNumber(data.hero.mdef);
var v = core.formatBigNumber(data.hero.hp,true)+"/"+core.formatBigNumber(data.hero.atk,true)+"/"+core.formatBigNumber(data.hero.def,true);
var v2 = "/"+core.formatBigNumber(data.hero.mdef,true);
if (v.length+v2.length<=21) v+=v2;
core.fillText('ui', v, (2*i+1)*u, 60+size, '#FFD700', '10px '+globalFont);
core.fillText('ui', core.formatDate(new Date(data.time)), (2*i+1)*u, 73+size, data.hero.flags.consoleOpened?'#FF6A6A':'#FFFFFF');
@ -2170,8 +2296,8 @@ ui.prototype.drawSLPanel = function(index, refresh) {
core.strokeRect('ui', (2*i-5)*u-size/2, 233, size, size, i==offset?strokeColor:'#FFFFFF', i==offset?6:2);
if (core.isset(data) && core.isset(data.floorId)) {
core.ui.drawThumbnail(data.floorId, 'ui', core.maps.load(data.maps, data.floorId).blocks, (2*i-5)*u-size/2, 233, size, data.hero.loc.x, data.hero.loc.y, data.hero.loc, data.hero.flags.heroIcon||"hero.png");
var v = core.formatBigNumber(data.hero.hp)+"/"+core.formatBigNumber(data.hero.atk)+"/"+core.formatBigNumber(data.hero.def);
var v2 = "/"+core.formatBigNumber(data.hero.mdef);
var v = core.formatBigNumber(data.hero.hp,true)+"/"+core.formatBigNumber(data.hero.atk,true)+"/"+core.formatBigNumber(data.hero.def,true);
var v2 = "/"+core.formatBigNumber(data.hero.mdef,true);
if (v.length+v2.length<=21) v+=v2;
core.fillText('ui', v, (2*i-5)*u, 248+size, '#FFD700', '10px '+globalFont);
core.fillText('ui', core.formatDate(new Date(data.time)), (2*i-5)*u, 261+size, data.hero.flags.consoleOpened?'#FF6A6A':'#FFFFFF', '10px '+globalFont);
@ -2343,7 +2469,7 @@ ui.prototype.drawKeyBoard = function () {
core.lockControl();
core.status.event.id = 'keyBoard';
core.clearMap('ui');
core.clearLastEvent();
var left = 16, top = 48, right = 416 - 2 * left, bottom = 416 - 2 * top;
core.fillRect('ui', left, top, right, bottom, core.material.groundPattern);
@ -2379,6 +2505,11 @@ ui.prototype.drawKeyBoard = function () {
core.fillText("ui", "返回游戏", 416-80, offset-3, '#FFFFFF', 'bold 15px '+globalFont);
}
////// 绘制状态栏 /////
ui.prototype.drawStatusBar = function () {
this.uidata.drawStatusBar();
}
////// 绘制“数据统计”界面 //////
ui.prototype.drawStatistics = function () {
@ -2448,6 +2579,8 @@ ui.prototype.drawStatistics = function () {
var temp = core.clone(core.status.hero);
core.setFlag("__statistics__", true);
if (core.isset(total.count[id])) {
var hp=0, atk=0, def=0, mdef=0;
@ -2455,6 +2588,7 @@ ui.prototype.drawStatistics = function () {
var ratio = floor.item_ratio||1;
if (core.isset(core.items.itemEffect[id])) {
try {
// 需要检查是否是测试状态...
eval(core.items.itemEffect[id]);
}
catch (e) {}
@ -2555,7 +2689,8 @@ ui.prototype.drawStatistics = function () {
+",总游戏时长"+formatTime(statistics.totalTime)
+"。\n瞬间移动次数"+statistics.moveDirectly+",共计少走"+statistics.ignoreSteps+"步。"
+"\n\n总计通过血瓶恢复生命值为"+core.formatBigNumber(statistics.hp)+"点。\n\n"
+"总计打死了"+statistics.battle+"个怪物,受到的伤害为"+core.formatBigNumber(statistics.battleDamage+statistics.poisonDamage+statistics.extraDamage)
+"总计打死了"+statistics.battle+"个怪物,得到了"+core.formatBigNumber(statistics.money)+"金币,"+core.formatBigNumber(statistics.experience)+"点经验。\n\n"
+"受到的总伤害为"+core.formatBigNumber(statistics.battleDamage+statistics.poisonDamage+statistics.extraDamage)
+",其中战斗伤害"+core.formatBigNumber(statistics.battleDamage)+"点"
+(core.flags.enableDebuff?(",中毒伤害"+core.formatBigNumber(statistics.poisonDamage)+"点"):"")
+",领域/夹击/阻击/血网伤害"+core.formatBigNumber(statistics.extraDamage)+"点。",
@ -2587,7 +2722,7 @@ ui.prototype.drawPaint = function () {
core.status.event.id = 'paint';
core.status.event.data = {"x": null, "y": null, "erase": false};
core.clearMap('ui');
core.clearLastEvent();
core.clearMap('route');
core.setAlpha('route', 1);
@ -2641,3 +2776,93 @@ ui.prototype.drawHelp = function () {
]);
}
////// 动态canvas //////
////// canvas创建 //////
ui.prototype.createCanvas = function (name, x, y, width, height, z) {
// 如果画布已存在则直接调用
var cv = this.findCanvas(name);
if (cv!=-1) {
this.relocateCanvas(name, x, y);
this.resizeCanvas(name, width, height);
core.dymCanvas[name].canvas.style.zIndex = z;
return;
}
var newCanvas = document.createElement("canvas");
newCanvas.id = name;
newCanvas.style.display = 'block';
newCanvas.width = width;
newCanvas.height = height;
newCanvas.style.width = width * core.domStyle.scale + 'px';
newCanvas.style.height = height * core.domStyle.scale + 'px';
newCanvas.style.left = x * core.domStyle.scale + 'px';
newCanvas.style.top = y * core.domStyle.scale + 'px';
newCanvas.style.zIndex = z;
newCanvas.style.position = 'absolute';
core.dymCanvas[name] = newCanvas.getContext('2d');
core.dymCanvas._list.push({
"id": name,
"style": {
"left": x,
"top": y,
}
});
core.dom.gameDraw.appendChild(newCanvas);
}
////// canvas查找 //////
ui.prototype.findCanvas = function (name) {
if (!core.isset(name)) return -1;
for (var index = 0; index < core.dymCanvas._list.length; index++) {
if (core.dymCanvas._list[index].id == name)
return index;
}
return -1;
}
////// canvas重定位 //////
ui.prototype.relocateCanvas = function (name, x, y) {
if (!core.isset(name)) return;
var index = core.findCanvas(name);
if (index < 0) return;
if (core.isset(x)) {
core.dymCanvas[name].canvas.style.left = x * core.domStyle.scale + 'px';
core.dymCanvas._list[index].style.left = x;
}
if (core.isset(y)) {
core.dymCanvas[name].canvas.style.top = y * core.domStyle.scale + 'px';
core.dymCanvas._list[index].style.top = y;
}
}
////// canvas重置 //////
ui.prototype.resizeCanvas = function (name, width, height) {
if (!core.isset(name)) return;
var dstCanvas = core.dymCanvas[name].canvas;
if (core.isset(width)) {
dstCanvas.width = width;
dstCanvas.style.width = width * core.domStyle.scale + 'px';
}
if (core.isset(height)) {
dstCanvas.height = height;
dstCanvas.style.height = height * core.domStyle.scale + 'px';
}
}
////// canvas删除 //////
ui.prototype.deleteCanvas = function (name) {
if (!core.isset(name)) return;
var index = core.findCanvas(name);
if (index == -1) return;
core.dom.gameDraw.removeChild(core.dymCanvas[name].canvas);
delete core.dymCanvas[name];
core.dymCanvas._list.splice(index,1);
}
////// 删除所有动态canvas //////
ui.prototype.deleteAllCanvas = function () {
core.dymCanvas._list.forEach(function (t) {
core.dom.gameDraw.removeChild(core.dymCanvas[t.id].canvas);
delete core.dymCanvas[t.id];
});
core.dymCanvas._list = [];
}

View File

@ -39,14 +39,14 @@ utils.prototype.init = function () {
}
////// 将文字中的${和}(表达式)进行替换 //////
utils.prototype.replaceText = function (text) {
utils.prototype.replaceText = function (text, need, times) {
return text.replace(/\${(.*?)}/g, function (word, value) {
return core.calValue(value);
return core.calValue(value, need, times);
});
}
////// 计算表达式的值 //////
utils.prototype.calValue = function (value) {
utils.prototype.calValue = function (value, need, times) {
if (!core.isset(value)) return value;
if (typeof value == 'number') {
return value;
@ -297,14 +297,14 @@ utils.prototype.setTwoDigits = function (x) {
return parseInt(x)<10?"0"+x:x;
}
utils.prototype.formatBigNumber = function (x) {
utils.prototype.formatBigNumber = function (x, onMap) {
x = Math.floor(parseFloat(x));
if (!core.isset(x)) return '???';
var c = x<0?"-":"";
x = Math.abs(x);
if (x<=999999) return c + x;
if (x<=99999 || (!onMap && x<=999999)) return c + x;
var all = [
{"val": 1e20, "c": "g"},
@ -316,9 +316,17 @@ utils.prototype.formatBigNumber = function (x) {
for (var i=0;i<all.length;i++) {
var one = all[i];
if (x>=10*one.val) {
var v = x/one.val;
return c + v.toFixed(Math.max(0, Math.floor(4-Math.log10(v+1)))) + one.c;
if (onMap) {
if (x>=one.val) {
var v = x/one.val;
return c + v.toFixed(Math.max(0, Math.floor(3-Math.log10(v+1)))) + one.c;
}
}
else {
if (x>=10*one.val) {
var v = x/one.val;
return c + v.toFixed(Math.max(0, Math.floor(4-Math.log10(v+1)))) + one.c;
}
}
}
@ -735,14 +743,10 @@ utils.prototype.copy = function (data) {
////// 动画显示某对象 //////
utils.prototype.show = function (obj, speed, callback) {
if (!core.isset(speed)) {
obj.style.display = 'block';
return;
}
obj.style.display = 'block';
if (main.mode!='play'){
if (!core.isset(speed) && main.mode!='play') {
obj.style.opacity = 1;
if (core.isset(callback)) {callback();}
if (core.isset(callback)) callback();
return;
}
obj.style.opacity = 0;
@ -761,15 +765,12 @@ utils.prototype.show = function (obj, speed, callback) {
////// 动画使某对象消失 //////
utils.prototype.hide = function (obj, speed, callback) {
if (!core.isset(speed)) {
if (!core.isset(speed) || main.mode!='play'){
obj.style.display = 'none';
if (core.isset(callback)) callback();
return;
}
if (main.mode!='play'){
obj.style.display = 'none';
if (core.isset(callback)) {callback();}
return;
}
obj.style.opacity = 1;
var opacityVal = 1;
var hideAnimate = window.setInterval(function () {
opacityVal -= 0.03;
@ -812,6 +813,12 @@ utils.prototype.encodeCanvas = function (ctx) {
////// 解析arr数组并绘制到tempCanvas上 //////
utils.prototype.decodeCanvas = function (arr, width, height) {
// 清空tempCanvas
var tempCanvas = core.bigmap.tempCanvas;
tempCanvas.canvas.width=width;
tempCanvas.canvas.height=height;
tempCanvas.clearRect(0, 0, width, height);
if (!core.isset(arr)) return null;
// to byte array
var curr = 0, list = [];
@ -819,11 +826,6 @@ utils.prototype.decodeCanvas = function (arr, width, height) {
for (var i=0;i<x;i++) list.push(curr);
curr = 1-curr;
})
// 使用tempCanvas
var tempCanvas = core.bigmap.tempCanvas;
tempCanvas.canvas.width=width;
tempCanvas.canvas.height=height;
tempCanvas.clearRect(0, 0, width, height);
var imgData = tempCanvas.getImageData(0, 0, width, height);
for (var i=0;i<imgData.data.length;i+=4) {
@ -837,6 +839,7 @@ utils.prototype.decodeCanvas = function (arr, width, height) {
}
utils.prototype.consoleOpened = function () {
if (!core.flags.checkConsole) return false;
if (window.Firebug && window.Firebug.chrome && window.Firebug.chrome.isInitialized)
return true;
var threshold = 160;

View File

@ -2,7 +2,7 @@ function main() {
//------------------------ 用户修改内容 ------------------------//
this.version = "2.5.2"; // 游戏版本号如果更改了游戏内容建议修改此version以免造成缓存问题。
this.version = "2.5.3"; // 游戏版本号如果更改了游戏内容建议修改此version以免造成缓存问题。
this.useCompress = false; // 是否使用压缩文件
// 当你即将发布你的塔时请使用“JS代码压缩工具”将所有js代码进行压缩然后将这里的useCompress改为true。
@ -55,16 +55,20 @@ function main() {
'nameCol': document.getElementById('nameCol'),
'lvCol': document.getElementById('lvCol'),
'hpmaxCol': document.getElementById('hpmaxCol'),
'hpCol': document.getElementById('hpCol'),
'manaCol': document.getElementById('manaCol'),
'atkCol': document.getElementById('atkCol'),
'defCol': document.getElementById('defCol'),
'mdefCol': document.getElementById('mdefCol'),
'moneyCol': document.getElementById('moneyCol'),
'expCol': document.getElementById('expCol'),
'experienceCol': document.getElementById('experienceCol'),
'upCol': document.getElementById('upCol'),
'keyCol': document.getElementById('keyCol'),
'pzfCol': document.getElementById('pzfCol'),
'debuffCol': document.getElementById('debuffCol'),
'skillCol': document.getElementById('skillCol'),
'hard': document.getElementById('hard'),
'statusCanvas': document.getElementById('statusCanvas'),
};
this.mode = 'play';
this.loadList = [

View File

@ -70,7 +70,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"firstData": {
"title": "魔塔样板",
"name": "template",
"version": "Ver 2.5.2",
"version": "Ver 2.5.3",
"floorId": "sample0",
"hero": {
"name": "阳光",
@ -110,11 +110,16 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
},
{
"type": "showImage",
"name": "bg.jpg",
"code": 1,
"image": "bg.jpg",
"loc": [
0,
0
]
],
"dw": 100,
"dh": 100,
"opacity": 100,
"time": 0
},
{
"type": "comment",
@ -163,7 +168,9 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
]
},
{
"type": "showImage"
"type": "hideImage",
"code": 1,
"time": 0
},
{
"type": "comment",
@ -179,7 +186,9 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"function": "function(){\ncore.control.checkBgm()\n}"
},
{
"type": "showImage"
"type": "hideImage",
"code": 1,
"time": 0
},
{
"type": "comment",
@ -202,6 +211,11 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"type": "function",
"function": "function(){\ncore.control.checkBgm()\n}"
},
{
"type": "hideImage",
"code": 1,
"time": 0
},
{
"type": "comment",
"text": "这段代码会结束事件,选择录像文件,播放录像或重新开始"
@ -338,7 +352,8 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"purify": 3,
"hatred": 2,
"moveSpeed": 100,
"animateSpeed": 300
"animateSpeed": 300,
"floorChangeTime": 800
},
"flags": {
"enableFloor": true,
@ -362,14 +377,16 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"bigKeyIsBox": false,
"equipment": false,
"equipboxButton": false,
"equipPercentage": false,
"enableAddPoint": false,
"enableNegativeDamage": false,
"hatredDecrease": true,
"betweenAttackCeil": false,
"useLoop": false,
"loopStep": 5000,
"startUsingCanvas": false,
"startDirectly": false,
"statusCanvas": false,
"statusCanvasRowsOnMobile": 3,
"canOpenBattleAnimate": true,
"showBattleAnimateConfirm": false,
"battleAnimate": false,
@ -382,6 +399,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"canGoDeadZone": false,
"enableMoveDirectly": true,
"enableDisabledShop": true,
"disableShopOnDamage": false
"disableShopOnDamage": false,
"checkConsole": false
}
}

View File

@ -60,6 +60,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
core.waitHeroToStop(function() {
core.removeGlobalAnimate(0,0,true);
core.clearMap('all'); core.clearMap('curtain'); // 清空全地图
core.deleteAllCanvas();
// 请注意:
// 成绩统计时是按照hp进行上传并排名因此光在这里改${status:hp}是无效的
// 如需按照其他的的分数统计方式请先将hp设置为你的得分
@ -87,16 +88,19 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
"afterChangeFloor": function (floorId, fromLoad) {
// 转换楼层结束的事件
// floorId是切换到的楼层fromLoad若为true则代表是从读档行为造成的楼层切换
// 每次抵达楼层时执行的事件
if (!fromLoad || core.hasFlag("forceSave")) {
core.insertAction(core.floors[floorId].eachArrive);
}
// 首次抵达楼层时执行的事件(后插入,先执行)
var visited = core.getFlag("__visited__", []);
if (visited.indexOf(floorId)===-1) {
core.insertAction(core.floors[floorId].firstArrive);
visited.push(floorId);
core.setFlag("__visited__", visited);
}
// 每次抵达楼层时执行的事件
if (!fromLoad) {
core.insertAction(core.floors[floorId].eachArrive);
}
},
"addPoint": function (enemy) {
// 加点事件
@ -155,9 +159,11 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
if (core.hasItem('coin')) money *= 2;
if (core.hasFlag('curse')) money=0;
core.status.hero.money += money;
core.status.hero.statistics.money += money;
var experience =enemy.experience;
if (core.hasFlag('curse')) experience=0;
core.status.hero.experience += experience;
core.status.hero.statistics.experience += experience;
var hint = "打败 " + enemy.name;
if (core.flags.enableMoney)
hint += ",金币+" + money;
@ -179,13 +185,14 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// 衰弱
if (core.enemys.hasSpecial(special, 13) && !core.hasFlag('weak')) {
core.setFlag('weak', true);
var weakValue = core.values.weakValue;
var weakAtk = weakValue>=1?weakValue:Math.floor(weakValue*core.status.hero.atk);
var weakDef = weakValue>=1?weakValue:Math.floor(weakValue*core.status.hero.def);
core.setFlag('weakAtk', weakAtk);
core.setFlag('weakDef', weakDef);
core.status.hero.atk-=weakAtk;
core.status.hero.def-=weakDef;
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, 14) && !core.hasFlag('curse')) {
@ -416,16 +423,20 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
var mon_hp = enemy.hp, mon_atk = enemy.atk, mon_def = enemy.def, mon_special = enemy.special;
var mon_money = enemy.money, mon_experience = enemy.experience, mon_point = enemy.point;
// 模仿
if (this.hasSpecial(mon_special, 10)) {
if (core.hasSpecial(mon_special, 10)) {
mon_atk = hero_atk;
mon_def = hero_def;
}
// 坚固
if (this.hasSpecial(mon_special, 3) && mon_def < hero_atk - 1) {
if (core.hasSpecial(mon_special, 3) && mon_def < hero_atk - 1) {
mon_def = hero_atk - 1;
}
// 光环效果
// V2.5.3备注:
// 这一部分是检查光环代码的,需要对整个地图上的图块进行遍历,可能会造成不必要的性能的损耗,尤其是循环计算临界会变得非常慢。
// 因此默认注释掉此段代码以加快游戏运行速度。
// 如果游戏中有光环怪物存在取消注释或按需根据floorId加判定即可。
/*
// 检查当前楼层所有光环怪物数字25
var hp_delta = 0, atk_delta = 0, def_delta = 0, cnt = 0;
// 遍历每个图块
@ -449,10 +460,11 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
mon_hp *= (1+hp_delta/100);
mon_atk *= (1+atk_delta/100);
mon_def *= (1+def_delta/100);
*/
// TODO可以在这里新增其他的怪物数据变化
// 比如仿攻(怪物攻击不低于勇士攻击):
// if (this.hasSpecial(mon_special, 27) && mon_atk < hero_atk) {
// if (core.hasSpecial(mon_special, 27) && mon_atk < hero_atk) {
// mon_atk = hero_atk;
// }
// 也可以按需增加各种自定义内容(比如幻塔的魔杖效果等)
@ -484,12 +496,10 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
hero_def=Math.max(0, hero_def);
hero_mdef=Math.max(0, hero_mdef);
// 装备按比例增加属性
if (core.flags.equipPercentage) {
hero_atk = Math.floor(core.getFlag('equip_atk_buff',1)*hero_atk);
hero_def = Math.floor(core.getFlag('equip_def_buff',1)*hero_def);
hero_mdef = Math.floor(core.getFlag('equip_mdef_buff',1)*hero_mdef);
}
// 计算装备按比例增加属性后的数值
hero_atk = Math.floor(core.getFlag('equip_atk_buff',1)*hero_atk);
hero_def = Math.floor(core.getFlag('equip_def_buff',1)*hero_def);
hero_mdef = Math.floor(core.getFlag('equip_mdef_buff',1)*hero_mdef);
// 怪物的各项数据
// 对坚固模仿等处理扔到了脚本编辑-getEnemyInfo之中
@ -502,14 +512,14 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
}
// 如果是无敌属性,且勇士未持有十字架
if (this.hasSpecial(mon_special, 20) && !core.hasItem("cross"))
if (core.hasSpecial(mon_special, 20) && !core.hasItem("cross"))
return null; // 不可战斗
// 战前造成的额外伤害(可被魔防抵消)
var init_damage = 0;
// 吸血
if (this.hasSpecial(mon_special, 11)) {
if (core.hasSpecial(mon_special, 11)) {
var vampire_damage = hero_hp * enemy.value;
// 如果有神圣盾免疫吸血等可以在这里写
@ -524,38 +534,39 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
init_damage += vampire_damage;
}
// 检查是否破防;否则直接返回不可战斗
if (hero_atk <= mon_def) return null;
// 每回合怪物对勇士造成的战斗伤害
var per_damage = mon_atk - hero_def;
// 魔攻:战斗伤害就是怪物攻击力
if (this.hasSpecial(mon_special, 2)) per_damage = mon_atk;
if (core.hasSpecial(mon_special, 2)) per_damage = mon_atk;
// 战斗伤害不能为负值
if (per_damage < 0) per_damage = 0;
// 2连击 & 3连击 & N连击
if (this.hasSpecial(mon_special, 4)) per_damage *= 2;
if (this.hasSpecial(mon_special, 5)) per_damage *= 3;
if (this.hasSpecial(mon_special, 6)) per_damage *= (enemy.n||4);
if (core.hasSpecial(mon_special, 4)) per_damage *= 2;
if (core.hasSpecial(mon_special, 5)) per_damage *= 3;
if (core.hasSpecial(mon_special, 6)) per_damage *= (enemy.n||4);
// 每回合的反击伤害;反击是按照勇士的攻击次数来计算回合
var counterDamage = 0;
if (this.hasSpecial(mon_special, 8)) counterDamage += Math.floor(core.values.counterAttack * hero_atk);
if (core.hasSpecial(mon_special, 8)) counterDamage += Math.floor(core.values.counterAttack * hero_atk);
// 先攻
if (this.hasSpecial(mon_special, 1)) init_damage += per_damage;
if (core.hasSpecial(mon_special, 1)) init_damage += per_damage;
// 破甲
if (this.hasSpecial(mon_special, 7))
if (core.hasSpecial(mon_special, 7))
init_damage += Math.floor(core.values.breakArmor * hero_def);
// 净化
if (this.hasSpecial(mon_special, 9))
if (core.hasSpecial(mon_special, 9))
init_damage += Math.floor(core.values.purify * hero_mdef);
// 勇士每回合对怪物造成的伤害
var hero_per_damage = hero_atk - mon_def;
var hero_per_damage = Math.max(hero_atk - mon_def, 0);
// 如果没有破防,则不可战斗
if (hero_per_damage <= 0) return null;
// 勇士的攻击回合数;为怪物生命除以每回合伤害向上取整
var turn = Math.ceil(mon_hp / hero_per_damage);
// 最终伤害:初始伤害 + 怪物对勇士造成的伤害 + 反击伤害
@ -679,7 +690,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
break;
case 80: // P查看评论
window.open("/score.php?name="+core.firstData.name+"&num=10", "_blank");
break;
break;
case 49: // 快捷键1: 破
if (core.hasItem('pickaxe')) {
if (core.canUseItem('pickaxe')) {
@ -726,6 +737,9 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
}
}
break;
case 55: // 快捷键7绑定为轻按方便手机版操作
core.getNextItem();
break;
case 118: // F7开启debug模式
core.debug();
break;
@ -809,16 +823,11 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// 向下取整
if (core.isset(core.status.hero[item]))
core.status.hero[item] = Math.floor(core.status.hero[item]);
// 大数据格式化
core.statusBar[item].innerHTML = core.formatBigNumber(core.getStatus(item));
// 装备按比例增加属性
var value = Math.floor(core.getStatus(item)*core.getFlag('equip_'+item+'_buff',1));
// 大数据格式化;
core.statusBar[item].innerHTML = core.formatBigNumber(value);
});
// 装备按比例增加属性
if (core.flags.equipPercentage) {
core.statusBar.atk.innerHTML = core.formatBigNumber(Math.floor(core.getFlag('equip_atk_buff',1)*core.getStatus('atk')));
core.statusBar.def.innerHTML = core.formatBigNumber(Math.floor(core.getFlag('equip_def_buff',1)*core.getStatus('def')));
core.statusBar.mdef.innerHTML = core.formatBigNumber(Math.floor(core.getFlag('equip_mdef_buff',1)*core.getStatus('mdef')));
}
// 设置魔力值
if (core.flags.enableMana) {
@ -841,9 +850,9 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
if (core.flags.enableLevelUp && core.status.hero.lv<core.firstData.levelUp.length) {
var need = core.calValue(core.firstData.levelUp[core.status.hero.lv].need);
if (core.flags.levelUpLeftMode)
core.statusBar.up.innerHTML = (need - core.getStatus('experience')) || " ";
core.statusBar.up.innerHTML = (need - core.getStatus('experience')) || " ";
else
core.statusBar.up.innerHTML = need || " ";
core.statusBar.up.innerHTML = need || " ";
}
else core.statusBar.up.innerHTML = " ";
@ -867,6 +876,8 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// 难度
core.statusBar.hard.innerHTML = core.status.hard;
// 状态栏绘制
core.drawStatusBar();
// 更新阻激夹域的伤害值
core.updateCheckBlock();
@ -1002,9 +1013,90 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
}
}
}
},
"moveOneStep": function () {
// 勇士每走一步后执行的操作
core.status.hero.steps++;
// 中毒状态:扣血
if (core.hasFlag('poison')) {
core.status.hero.statistics.poisonDamage += core.values.poisonDamage;
core.status.hero.hp -= core.values.poisonDamage;
if (core.status.hero.hp<=0) {
core.status.hero.hp=0;
core.updateStatusBar();
core.events.lose();
return;
}
core.updateStatusBar();
}
// 备注:瞬间移动不会执行该函数。如果要控制能否瞬间移动有三种方法:
// 1. 将全塔属性中的cannotMoveDirectly这个开关勾上即可在全塔中全程禁止使用瞬移。
// 2, 将楼层属性中的cannotMoveDirectly这个开关勾上即禁止在该层楼使用瞬移。
// 3. 将flag:cannotMoveDirectly置为true即可使用flag控制在某段剧情范围内禁止瞬移。
}
},
"ui": {
"drawStatusBar": function () {
// 如果是非状态栏canvas化直接返回
if (!core.flags.statusCanvas) return;
var canvas = core.dom.statusCanvas, ctx = canvas.getContext('2d');
// 清空状态栏
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 如果是隐藏状态栏模式,直接返回
if (!core.domStyle.showStatusBar) return;
// 作为样板,只绘制楼层、生命、攻击、防御、魔防、金币、钥匙这七个内容
// 需要其他的请自行进行修改;横竖屏都需要进行适配绘制。
// 可以使用Chrome浏览器开控制台来模拟手机上的竖屏模式的显示效果具体方式自行百度
// 横屏模式下的画布大小是 129*416
// 竖屏模式下的画布大小是 416*(32*rows+9) 其中rows为状态栏行数即全塔属性中statusCanvasRowsOnMobile值
// 可以使用 core.domStyle.isVertical 来判定当前是否是竖屏模式
ctx.fillStyle = core.status.globalAttribute.statusBarColor || core.initStatus.globalAttribute.statusBarColor;
ctx.font = 'italic bold 18px Verdana';
// 距离左侧边框6像素上侧边框9像素行距约为39像素
var leftOffset = 6, topOffset = 9, lineHeight = 39;
if (core.domStyle.isVertical) { // 竖屏模式行高32像素
leftOffset = 6; topOffset = 6; lineHeight = 32;
}
var toDraw = ["floor", "hp", "atk", "def", "mdef", "money"];
for (var index = 0; index < toDraw.length; index++) {
// 绘制下一个数据
var name = toDraw[index];
// 图片大小25x25
ctx.drawImage(core.statusBar.icons[name], leftOffset, topOffset, 25, 25);
// 文字内容
var text = (core.statusBar[name]||{}).innerText || " ";
// 斜体判定:如果不是纯数字和字母,斜体会非常难看,需要取消
if (!/^[-+_.a-zA-Z0-9]*$/.test(text)) ctx.font = 'bold 18px Verdana';
// 绘制文字
ctx.fillText(text, leftOffset + 36, topOffset + 20);
ctx.font = 'italic bold 18px Verdana';
// 计算下一个绘制的坐标
if (core.domStyle.isVertical) {
// 竖屏模式
if (index % 3 != 2) leftOffset += 131;
else {
leftOffset = 6;
topOffset += lineHeight;
}
}
else {
// 横屏模式
topOffset += lineHeight;
}
}
// 绘制三色钥匙
ctx.fillStyle = '#FFCCAA';
ctx.fillText(core.statusBar.yellowKey.innerText, leftOffset + 5, topOffset + 20);
ctx.fillStyle = '#AAAADD';
ctx.fillText(core.statusBar.blueKey.innerText, leftOffset + 40, topOffset + 20);
ctx.fillStyle = '#FF8888';
ctx.fillText(core.statusBar.redKey.innerText, leftOffset + 75, topOffset + 20);
},
"drawStatistics": function () {
// 浏览地图时参与的统计项目
@ -1064,7 +1156,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
eval(core.floors[core.status.floorId].parallelDo);
} catch (e) {
console.log(e);
}
}
}
// 下面是一个并行事件开门的样例
@ -1115,21 +1207,23 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// core.plugin.drawLight([255,255,0,0.2], [[25,11,46,0.1]]); // 全图为不透明度0.2的黄色,其中在(25,11)点存在一个半径为46的灯光效果灯光中心不透明度0.1。
// core.plugin.drawLight(0.9, [[25,11,46],[105,121,88],[301,221,106]]); // 存在三个灯光效果,分别是中心(25,11)半径46中心(105,121)半径88中心(301,221)半径106。
// core.plugin.drawLight([0,0,255,0.3], [[25,11,46],[105,121,88,0.2]], 0.4); // 存在两个灯光效果它们在内圈40%范围内保持全亮且40%后才开始衰减。
// 【注意事项】
// 此函数会和更改画面色调发生冲突,请只选择一个使用。
this.drawLight = function (color, lights, lightDec) {
// 清空色调层
var ctx = core.canvas.curtain;
// 清空色调层也可以修改成其它层比如animate/weather层或者用自己创建的canvas
var canvasName = 'curtain';
var ctx = core.ui.getContextByName(canvasName);
if (ctx == null) return;
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.msImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
core.clearMap('curtain');
ctx.clearRect(0, 0, 416, 416);
// 绘制色调层,默认不透明度
if (!core.isset(color)) color = 0.9;
if (typeof color == "number") color = [0,0,0,color];
core.fillRect('curtain', 0, 0, 416, 416, core.arrayToRGBA(color));
ctx.fillStyle = core.arrayToRGBA(color);
ctx.fillRect(0, 0, 416, 416);
// 绘制每个灯光效果
if (!core.isset(lights) || lights.length==0) return;

BIN
project/images/fog.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -1,4 +1,4 @@
var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
{
"items": {
"yellowKey": {
@ -301,7 +301,7 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
"cls": "constants",
"name": "技能:二倍斩",
"text": "可以打开或关闭主动技能二倍斩",
"hideInReplay": true
"hideInReplay": true
}
},
"itemEffect": {
@ -368,9 +368,9 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
"upFly": "var loc = {'direction': core.status.hero.loc.direction, 'x': core.status.event.data.x, 'y': core.status.event.data.y};\ncore.changeFloor(core.status.event.data.id, null, loc, null, function (){\n\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n\tcore.replay();\n});",
"downFly": "var loc = {'direction': core.status.hero.loc.direction, 'x': core.status.event.data.x, 'y': core.status.event.data.y};\ncore.changeFloor(core.status.event.data.id, null, loc, null, function (){\n\tcore.drawTip(core.material.items[itemId].name + '使用成功');\n\tcore.replay();\n});",
"poisonWine": "core.removeFlag('poison');",
"weakWine": "core.removeFlag('weak');\ncore.status.hero.atk += core.getFlag('weakAtk', core.values.weakValue);\ncore.status.hero.def += core.getFlag('weakDef', core.values.weakValue);",
"weakWine": "core.removeFlag('weak');\nif (core.values.weakValue>=1) { // >=1直接扣数值\n\tcore.status.hero.atk += core.values.weakValue;\n\tcore.status.hero.def += core.values.weakValue;\n}\nelse { // <1扣比例\n\tcore.setFlag(\"equip_atk_buff\", core.getFlag(\"equip_atk_buff\", 1) + core.values.weakValue);\n\tcore.setFlag(\"equip_def_buff\", core.getFlag(\"equip_def_buff\", 1) + core.values.weakValue);\n}",
"curseWine": "core.removeFlag('curse');",
"superWine": "core.removeFlag('poison');\nif (core.hasFlag('weak')) {\n\tcore.removeFlag('weak');\n\tcore.status.hero.atk += core.getFlag('weakAtk', core.values.weakValue);\n\tcore.status.hero.def += core.getFlag('weakDef', core.values.weakValue);\n}\ncore.removeFlag('curse');",
"superWine": "core.removeFlag('poison');\nif (core.hasFlag('weak')) {\n\tcore.removeFlag('weak');\n\tif (core.values.weakValue>=1) { // >=1直接扣数值\n\t\tcore.status.hero.atk += core.values.weakValue;\n\t\tcore.status.hero.def += core.values.weakValue;\n\t}\n\telse { // <1扣比例\n\t\tcore.setFlag(\"equip_atk_buff\", core.getFlag(\"equip_atk_buff\", 1) + core.values.weakValue);\n\t\tcore.setFlag(\"equip_def_buff\", core.getFlag(\"equip_def_buff\", 1) + core.values.weakValue);\n\t}\n}\ncore.removeFlag('curse');",
"lifeWand": "core.insertAction([\n\t{\"type\": \"input\", \"text\": \"请输入生命魔杖使用次数:(0-${item:lifeWand})\"},\n\t{\"type\": \"if\", \"condition\": \"flag:input<=item:lifeWand\",\n\t\t\"true\": [\n\t\t\t{\"type\": \"setValue\", \"name\": \"item:lifeWand\", \"value\": \"item:lifeWand-flag:input\"},\n\t\t\t{\"type\": \"setValue\", \"name\": \"status:hp\", \"value\": \"status:hp+flag:input*100\"},\n\t\t\t\"成功使用${flag:input}次生命魔杖,恢复${flag:input*100}点生命。\"\n\t\t],\n\t\t\"false\": [\"输入不合法!\"]\n\t},\n]);\ncore.addItem('lifeWand', 1);",
"jumpShoes": "core.insertAction({\"type\":\"jumpHero\",\"loc\":[core.nextX(2),core.nextY(2)]});",
"redPotion": "core.status.hero.hp += core.values.redPotion",
@ -411,5 +411,6 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a =
"greenJewel": "true",
"yellowJewel": "true",
"skill1": "true"
}
},
"canEquip": {}
}

View File

@ -79,7 +79,9 @@ var maps_90f36752_8815_4be8_b32b_d7fad1d0542e =
'65':{'cls': 'items', 'id': 'hammer'}, // 圣锤
'68':{'cls': 'items', 'id': 'lifeWand'}, // 生命魔杖
'69':{'cls': 'items', 'id': 'jumpShoes'}, // 生命魔杖
'70':{'cls': 'items', 'id': 'skill1'}, // 技能:二倍斩
'70':{'cls': 'items', 'id': 'sword0'},
'71':{'cls': 'items', 'id': 'shield0'},
'72':{'cls': 'items', 'id': 'skill1'}, // 技能:二倍斩
////////////////////////// 门、楼梯、传送点部分 //////////////////////////

View File

@ -21,7 +21,7 @@
position: fixed;
top: 10px;
left: 10px;
z-index: 320;
z-index: 370;
}
#startPanel {
@ -32,7 +32,7 @@
left: 0;
background-color: #fff;
overflow: hidden;
z-index: 250;
z-index: 300;
}
#startTop {
@ -42,7 +42,7 @@
top: 0;
left: 0;
background-color: #000;
z-index: 300;
z-index: 350;
}
#startTopProgressBar {
@ -77,12 +77,12 @@
height: 100%;
width: auto;
transform:translate(-50%,-50%);
z-index: 210;
z-index: 260;
}
#startLogo {
position: absolute;
z-index: 240;
z-index: 290;
left: 0;
right: 0;
margin-left: auto;
@ -95,7 +95,7 @@
#startTitle {
position: absolute;
z-index: 230;
z-index: 280;
}
#startButtonGroup {
@ -106,7 +106,7 @@
background-color: #000;
opacity: 0.85;
display: none;
z-index: 260;
z-index: 310;
bottom: 0;
margin-bottom: 7%;
}
@ -142,7 +142,7 @@
display: none;
color: #fff;
background-color: #000;
z-index: 180;
z-index: 230;
}
#logoLabel {
@ -170,7 +170,7 @@
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
background: url(project/images/ground.png) repeat;
z-index: 135;
z-index: 185;
display: none;
}
#statusBar .status{
@ -200,7 +200,7 @@
#toolBar {
position: absolute;
background: url(project/images/ground.png) repeat;
z-index: 160;
z-index: 210;
box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
@ -220,6 +220,7 @@ p#hard {
font: bold normal 1.1em "Arial Black";
text-align: center;
margin: 0 6px 6px 0;
word-break: keep-all;
}
span#poison, span#weak, span#curse, span#pickaxe, span#bomb, span#fly {
@ -254,7 +255,7 @@ p#name {
position: absolute;
background: #000000;
overflow: hidden;
z-index: 135;
z-index: 185;
}
#bg {
@ -297,16 +298,12 @@ p#name {
z-index: 100;
}
#image {
z-index: 105;
}
#ui {
z-index: 110;
z-index: 160;
}
#data {
z-index: 120;
z-index: 170;
}
.clearfix:before,

Binary file not shown.