Merge pull request #270 from ckcz123/v2.0

V2.0
This commit is contained in:
Zhang Chen 2018-12-04 12:48:51 +08:00 committed by GitHub
commit f610a4f28a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 840 additions and 262 deletions

View File

@ -183,6 +183,18 @@ var code = '[\n'+action_0+']\n';
return code;
*/;
//eachArrive 事件编辑器入口之一
eachArrive_m
: '每次到达楼层' BGNL? Newline action+ BEND
/* eachArrive_m
tooltip : 每次到达楼层
helpUrl : https://h5mota.com/games/template/docs/#/event?id=%e7%b3%bb%e7%bb%9f%e5%bc%95%e5%8f%91%e7%9a%84%e8%87%aa%e5%ae%9a%e4%b9%89%e4%ba%8b%e4%bb%b6
var code = '[\n'+action_0+']\n';
return code;
*/;
//changeFloor 事件编辑器入口之一
changeFloor_m
: '楼梯, 传送门' BGNL? Newline Floor_List IdString? Stair_List 'x' Number ',' 'y' Number '朝向' DirectionEx_List '动画时间' Int? '允许穿透' Bool BEND
@ -235,6 +247,7 @@ action
| updateEnemys_s
| sleep_s
| wait_s
| waitAsync_s
| battle_s
| openDoor_s
| changeFloor_s
@ -245,7 +258,7 @@ action
| follow_s
| unfollow_s
| animate_s
| viberate_s
| vibrate_s
| showImage_0_s
| showImage_1_s
| animateImage_0_s
@ -470,13 +483,13 @@ return code;
show_s
: '显示事件' 'x' EvalString? ',' 'y' EvalString? '楼层' IdString? '动画时间' Int? Newline
: '显示事件' 'x' EvalString? ',' 'y' EvalString? '楼层' IdString? '动画时间' Int? '不等待执行完毕' Bool? Newline
/* show_s
tooltip : show: 将禁用事件启用,楼层和动画时间可不填,xy可用逗号分隔表示多个点
helpUrl : https://h5mota.com/games/template/docs/#/event?id=show%EF%BC%9A%E5%B0%86%E4%B8%80%E4%B8%AA%E7%A6%81%E7%94%A8%E4%BA%8B%E4%BB%B6%E5%90%AF%E7%94%A8
default : ["","","",500]
default : ["","","",500,false]
colour : this.eventColor
var floorstr = '';
if (EvalString_0 && EvalString_1) {
@ -497,18 +510,19 @@ if (EvalString_0 && EvalString_1) {
}
IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"');
Int_0 = Int_0 ?(', "time": '+Int_0):'';
var code = '{"type": "show"'+floorstr+IdString_0+''+Int_0+'},\n';
Bool_0 = Bool_0 ?', "async": true':'';
var code = '{"type": "show"'+floorstr+IdString_0+''+Int_0+Bool_0+'},\n';
return code;
*/;
hide_s
: '隐藏事件' 'x' EvalString? ',' 'y' EvalString? '楼层' IdString? '动画时间' Int? Newline
: '隐藏事件' 'x' EvalString? ',' 'y' EvalString? '楼层' IdString? '动画时间' Int? '不等待执行完毕' Bool? Newline
/* hide_s
tooltip : hide: 将一个启用事件禁用,所有参数均可不填,代表禁用事件自身,xy可用逗号分隔表示多个点
helpUrl : https://h5mota.com/games/template/docs/#/event?id=hide%EF%BC%9A%E5%B0%86%E4%B8%80%E4%B8%AA%E5%90%AF%E7%94%A8%E4%BA%8B%E4%BB%B6%E7%A6%81%E7%94%A8
default : ["","","",500]
default : ["","","",500,false]
colour : this.eventColor
var floorstr = '';
if (EvalString_0 && EvalString_1) {
@ -529,7 +543,8 @@ if (EvalString_0 && EvalString_1) {
}
IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"');
Int_0 = Int_0 ?(', "time": '+Int_0):'';
var code = '{"type": "hide"'+floorstr+IdString_0+''+Int_0+'},\n';
Bool_0 = Bool_0 ?', "async": true':'';
var code = '{"type": "hide"'+floorstr+IdString_0+''+Int_0+Bool_0+'},\n';
return code;
*/;
@ -819,6 +834,7 @@ var code = '{"type": "sleep", "time": '+Int_0+'},\n';
return code;
*/;
battle_s
: '强制战斗' IdString Newline
@ -949,18 +965,18 @@ var code = '{"type": "unfollow"' + EvalString_0 + '},\n';
return code;
*/;
viberate_s
vibrate_s
: '画面震动' '时间' Int '不等待执行完毕' Bool Newline
/* viberate_s
tooltip : viberate: 画面震动
helpUrl : https://h5mota.com/games/template/docs/#/event?id=viberate%ef%bc%9a%e7%94%bb%e9%9d%a2%e9%9c%87%e5%8a%a8
/* vibrate_s
tooltip : vibrate: 画面震动
helpUrl : https://h5mota.com/games/template/docs/#/event?id=vibrate%ef%bc%9a%e7%94%bb%e9%9d%a2%e9%9c%87%e5%8a%a8
default : [2000,false]
colour : this.soundColor
Int_0 = Int_0 ?(', "time": '+Int_0):'';
var async = Bool_0?', "async": true':''
var code = '{"type": "viberate"' + Int_0 + async + '},\n';
var code = '{"type": "vibrate"' + Int_0 + async + '},\n';
return code;
*/;
@ -1459,6 +1475,20 @@ var code = '{"type": "wait"},\n';
return code;
*/;
waitAsync_s
: '等待所有异步事件执行完毕'
/* waitAsync_s
tooltip : waitAsync: 等待所有异步事件执行完毕
helpUrl : https://h5mota.com/games/template/docs/#/event?id=waitAsync%ef%bc%9a%e7%ad%89%e5%be%85%e6%89%80%e6%9c%89%e5%bc%82%e6%ad%a5%e4%ba%8b%e4%bb%b6%e6%89%a7%e8%a1%8c%e5%ae%8c%e6%af%95
colour : this.soundColor
var code = '{"type": "waitAsync"},\n';
return code;
*/;
function_s
: '自定义JS脚本' BGNL? Newline RawEvalString Newline BEND Newline
@ -1644,8 +1674,8 @@ Global_Attribute_List
/*Global_Attribute_List ['font','statusLeftBackground','statusTopBackground', 'toolsBackground', 'borderColor', 'statusBarColor', 'hardLabelColor', 'floorChangingBackground', 'floorChangingTextColor']*/;
Global_Value_List
: '血网伤害'|'中毒伤害'|'衰弱效果'|'红宝石效果'|'蓝宝石效果'|'绿宝石效果'|'红血瓶效果'|'蓝血瓶效果'|'黄血瓶效果'|'绿血瓶效果'|'破甲比例'|'反击比例'|'净化比例'|'仇恨增加值'|'最大合法HP'|'动画时间'
/*Global_Value_List ['lavaDamage','poisonDamage','weakValue', 'redJewel', 'blueJewel', 'greenJewel', 'redPotion', 'bluePotion', 'yellowPotion', 'greenPotion', 'breakArmor', 'counterAttack', 'purify', 'hatred', 'maxValidHp', 'animateSpeed']*/;
: '血网伤害'|'中毒伤害'|'衰弱效果'|'红宝石效果'|'蓝宝石效果'|'绿宝石效果'|'红血瓶效果'|'蓝血瓶效果'|'黄血瓶效果'|'绿血瓶效果'|'破甲比例'|'反击比例'|'净化比例'|'仇恨增加值'|'行走速度'|'动画时间'
/*Global_Value_List ['lavaDamage','poisonDamage','weakValue', 'redJewel', 'blueJewel', 'greenJewel', 'redPotion', 'bluePotion', 'yellowPotion', 'greenPotion', 'breakArmor', 'counterAttack', 'purify', 'hatred', 'moveSpeed', 'animateSpeed']*/;
Bool: 'TRUE'
| 'FALSE'
@ -1901,7 +1931,7 @@ ActionParser.prototype.parseAction = function() {
y_str.push(t[1]);
})
this.next = MotaActionBlocks['show_s'].xmlText([
x_str.join(','),y_str.join(','),data.floorId||'',data.time||0,this.next]);
x_str.join(','),y_str.join(','),data.floorId||'',data.time||0,data.async||false,this.next]);
break;
case "hide": // 消失
data.loc=data.loc||[];
@ -1913,7 +1943,7 @@ ActionParser.prototype.parseAction = function() {
y_str.push(t[1]);
})
this.next = MotaActionBlocks['hide_s'].xmlText([
x_str.join(','),y_str.join(','),data.floorId||'',data.time||0,this.next]);
x_str.join(','),y_str.join(','),data.floorId||'',data.time||0,data.async||false,this.next]);
break;
case "setBlock": // 设置图块
data.loc=data.loc||['',''];
@ -2023,8 +2053,8 @@ ActionParser.prototype.parseAction = function() {
this.next = MotaActionBlocks['animate_s'].xmlText([
data.name,animate_loc,data.async||false,this.next]);
break;
case "viberate": // 画面震动
this.next = MotaActionBlocks['viberate_s'].xmlText([data.time||0, data.async||false, this.next]);
case "vibrate": // 画面震动
this.next = MotaActionBlocks['vibrate_s'].xmlText([data.time||0, data.async||false, this.next]);
break;
case "showImage": // 显示图片
if(this.isset(data.name)){
@ -2221,6 +2251,10 @@ ActionParser.prototype.parseAction = function() {
this.next = MotaActionBlocks['wait_s'].xmlText([
this.next]);
break;
case "waitAsync": // 等待所有异步事件执行完毕
this.next = MotaActionBlocks['waitAsync_s'].xmlText([
this.next]);
break;
case "revisit": // 立刻重新执行该事件
this.next = MotaActionBlocks['revisit_s'].xmlText([
this.next]);

View File

@ -330,6 +330,12 @@ var comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_event": "firstArrive",
"_data": "第一次到该楼层触发的事件,可以双击进入事件编辑器。"
},
"eachArrive": {
"_leaf": true,
"_type": "event",
"_event": "eachArrive",
"_data": "每次到该楼层触发的事件可以双击进入事件编辑器该事件会比firstArrive先执行。"
},
"parallelDo": {
"_leaf": true,
"_type": "textarea",

View File

@ -276,6 +276,13 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
}
}
},
"startCanvas": {
"_leaf": true,
"_type": "event",
"_event": "firstArrive",
"_range": "thiseval==null || thiseval instanceof Array",
"_data": "标题界面事件化,可以使用事件流的形式来绘制开始界面等。\n需要开启startUsingCanvas这个开关。\n详见文档-个性化-标题界面事件化。"
},
"startText": {
"_leaf": true,
"_type": "event",
@ -373,11 +380,10 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_type": "textarea",
"_data": "仇恨属性中,每杀死一个怪物获得的仇恨值"
},
"maxValidHp": {
"moveSpeed": {
"_leaf": true,
"_type": "textarea",
"_range": "thiseval==null||thiseval>0",
"_data": "最大合法生命值如果此项不为null且用户通关血量超过本值则视为作弊不上传成绩"
"_data": "行走速度即勇士每走一格的时间一般100比较合适"
},
"animateSpeed": {
"_leaf": true,
@ -560,6 +566,12 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_bool": "bool",
"_data": "是否循环计算临界如果此项为true则使用循环法而不是回合数计算法来算临界"
},
"startUsingCanvas": {
"_leaf": true,
"_type": "checkbox",
"_bool": "bool",
"_data": "是否开始菜单canvas化如果此项为true则将使用canvas来绘制开始菜单"
},
"startDirectly": {
"_leaf": true,
"_type": "checkbox",

View File

@ -11,6 +11,7 @@ function editor() {
if (string.indexOf(substring) > -1){
message = 'Script Error: See Browser Console for Detail';
} else {
if (url) url = url.substring(url.lastIndexOf('/')+1);
message = [
'Message: ' + msg,
'URL: ' + url,
@ -183,6 +184,7 @@ editor.prototype.mapInit = function () {
editor.currentFloorData.fgmap = editor.fgmap;
editor.currentFloorData.bgmap = editor.bgmap;
editor.currentFloorData.firstArrive = [];
editor.currentFloorData.eachArrive = [];
editor.currentFloorData.events = {};
editor.currentFloorData.changeFloor = {};
editor.currentFloorData.afterBattle = {};

View File

@ -52,6 +52,7 @@ editor_blockly = function () {
MotaActionBlocks['afterGetItem_m'].xmlText(),
MotaActionBlocks['afterOpenDoor_m'].xmlText(),
MotaActionBlocks['firstArrive_m'].xmlText(),
MotaActionBlocks['eachArrive_m'].xmlText(),
MotaActionBlocks['level_m'].xmlText(),
],
'显示文字':[
@ -131,7 +132,8 @@ editor_blockly = function () {
'特效/声音':[
MotaActionBlocks['sleep_s'].xmlText(),
MotaActionBlocks['wait_s'].xmlText(),
MotaActionBlocks['viberate_s'].xmlText(),
MotaActionBlocks['waitAsync_s'].xmlText(),
MotaActionBlocks['vibrate_s'].xmlText(),
MotaActionBlocks['animate_s'].xmlText(),
MotaActionBlocks['showStatusBar_s'].xmlText(),
MotaActionBlocks['hideStatusBar_s'].xmlText(),
@ -420,7 +422,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'));
codeAreaHL.setValue(input.value.replace(/\\r/g,'\\\\r').replace(/\\f/,'\\\\f'));
document.getElementById('entryType').value = type;
editor_blockly.parse();
editor_blockly.show();

View File

@ -156,6 +156,7 @@ editor_file = function (editor, callback) {
color: saveStatus?currData.color:null,
weather: saveStatus?currData.weather:null,
firstArrive: [],
eachArrive: [],
parallelDo: "",
events: {},
changeFloor: {},

View File

@ -313,6 +313,7 @@ floorId指定的是目标楼层的唯一标识符ID
- 使用`\b[...]`来制作对话框效果,如`\b[up,3,2]`。
- 使用`\r[...]`来动态修改局部文本的颜色,如`\r[red]`。
- 使用`${}`来计算一个表达式的值,如`${status:atk+status:def}`。
- 使用`\f[...]`来同时插入一张立绘图,如`\f[1.png,100,200]`。
从V2.5.2开始,也允许绘制一张头像图在对话框中,只要通过`\t[1.png]`或`\t[标题,1.png]`的写法。

View File

@ -228,7 +228,7 @@
除此以外,我们还能实现“对话框效果”,只要有`\b[...]`就可以。
- `\b[up]` 直接显示在当前点上方。同样把这里的up换成down则为下方。
- 如果不存在当前点如在firstArrive中调用则显示在屏幕最上方最下方
- 如果不存在当前点如在firstArrive或eachArrive中调用),则显示在屏幕最上方(最下方)
- `\b[up,hero]` 显示在勇士上方。同样把这里的up换成down则为下方。
- `\b[up,x,y]` 显示在(x,y)点的上方下方x和y都为整数且在0到12之间。
@ -253,6 +253,20 @@
]
```
从V2.5.3以后,也可以使用`\f[...]`来同时绘制一张图片。
其基本写法是`\f[图片名,起始x像素,起始y像素]`,或者`\f[图片名,起始x像素,起始y像素,绘制宽度,绘制高度]`。
需要注意的是这个图片是绘制在UI层上的下一个事件执行时即会擦除同时如果使用了\t的图标动画效果重叠的地方也会被图标动画给覆盖掉。
``` js
"x,y": [ // 实际执行的事件列表
"\t[勇士]\b[up,hero]\f[1.png,100,100]以(100,100)为左上角绘制1.png图片",
"\t[hero]\f[1.png,100,100]\f[2.png,300,300]同时绘制了两张图片",
"\f[1.png,100,100,300,300]也可以填写宽高,这样会把图片强制进行放缩到指定的宽高值"
]
```
另外值得一提的是,我们是可以在文字中计算一个表达式的值的。只需要将表达式用 `${ }`整个括起来就可以。
``` js
@ -441,7 +455,7 @@ value为必填项代表要修改到的结果。此项无需再手动加单引
name必填项代表要修改的全局数值其和全塔属性中的values一一对应。目前只能为`"lavaDamage", "poisonDamage", "weakValue", "redJewel",
"blueJewel", "greenJewel", "redPotion", "bluePotion", "yellowPotion", "greenPotion", "breakArmor", "counterAttack",
"purify", "hatred", "maxValidHp", "animateSpeed"`。
"purify", "hatred", "moveSpeed", "animateSpeed"`。
value为必填项代表要修改到的结果。该项必须是个数值。
@ -456,7 +470,8 @@ value为必填项代表要修改到的结果。该项必须是个数值。
{"type": "show", "loc": [3,6], "floorId": "MT1", "time": 500}, // 启用MT1层[3,6]位置事件动画500ms
{"type": "show", "loc": [3,6], "time": 500}, // 如果启用目标是当前层则可以省略floorId项
{"type": "show", "loc": [3,6]}, // 如果不指定动画时间则立刻显示否则动画效果逐渐显示time为动画时间
{"type": "show", "loc": [[3,6],[2,9],[1,2]], "time": 500} // 我们也可以同时动画显示多个点。
{"type": "show", "loc": [[3,6],[2,9],[1,2]], "time": 500}, // 我们也可以同时动画显示多个点。
{"type": "show", "loc": [3,6], "time": 500, "async": true} // 可以使用异步动画效果
]
```
@ -468,13 +483,15 @@ floorId为目标点的楼层如果不是该楼层的事件比如4楼小偷
time为动画效果时间如果指定了某个大于0的数则会以动画效果慢慢从无到有显示动画时间为该数值如果不指定该选项则无动画直接立刻显示。
async可选如果为true则会异步执行即不等待当前事件执行完毕立刻执行下一个事件
!> **要注意的是调用show事件后只是让该事件从禁用状态变成启用从不可见不可交互变成可见可交互但本身不会去执行该点的事件。**
### hide将一个启用事件禁用
`{"type":"hide"}`和show刚好相反它会让一个已经启用的事件被禁用。
其参数和show也完全相同loc指定事件的位置floorId为楼层同层可忽略time指定的话事件会以动画效果从有到无慢慢消失。
其参数和show也完全相同loc指定事件的位置floorId为楼层同层可忽略time指定的话事件会以动画效果从有到无慢慢消失async代表是否是异步效果
loc同样可以简单的写[x,y]表示单个点,或二维数组[[x1,y1],[x2,y2],...]表示多个点。
@ -492,7 +509,7 @@ NPC对话事件结束后如果需要NPC消失也需要调用 `{"type": "hide"}`
{"type": "hide", "loc": [[3,6],[2,9],[1,2]], "time": 500}, // 也可以同时指定多个点消失
{"type": "hide", "time": 500}, // 如果不指定loc选项则默认为当前点 例如这个就是500ms消失当前对话的NPC
{"type": "hide"}, // 无动画将当前事件禁用,常常适用于某个空地点(触发陷阱事件、触发机关门这种)
{"type": "hide", "loc": [3,6], "time": 500, "async": true} // 可以使用异步动画效果
]
```
@ -807,8 +824,6 @@ time为可选的指定的话将作为楼层切换动画的时间。
**如果time指定为小于100则视为没有楼层切换动画。**
!> **changeFloor到达一个新的楼层将不会执行firstArrive事件如有需求请在到达点设置自定义事件然后使用type: trigger立刻调用之。**
### changePos当前位置切换/勇士转向
有时候我们不想要楼层切换的动画效果而是直接让勇士从A点到B点。
@ -863,9 +878,9 @@ name为可选的是要取消跟随的行走图文件名。
如果name省略则会取消所有的跟随效果。
### viberate画面震动
### vibrate画面震动
使用 `{"type": "viberate", "time": 2000, "async": true}` 可以造成画面震动效果。
使用 `{"type": "vibrate", "time": 2000, "async": true}` 可以造成画面震动效果。
time可以指定震动时间默认是2000毫秒。
@ -1548,6 +1563,19 @@ choices为一个数组其中每一项都是一个选项列表。
```
### waitAsync等待所有异步事件执行完毕
上面有很多很多的异步事件(也就是执行时不等待执行完毕)。
由于录像是加速播放,且会跳过`{"type":"sleep"}`等待X毫秒事件因此异步行为很有可能导致录像播放出错。
例如异步移动一个NPC去某格然后等待X毫秒再勇士走过去对话
但是录像播放中等待X毫秒的行为会被跳过因此勇士可能走过去时异步还未执行完成导致录像出错。
我们可以使用`{"type":"waitAsync"}`来等待所有异步事件执行完毕。
该事件会进行等待,直到所有可能的异步事件(异步动画除外)执行完毕。
### function: 自定义JS脚本
上述给出了这么多事件,但有时候往往不能满足需求,这时候就需要执行自定义脚本了。
@ -2113,7 +2141,7 @@ if (core.getFlag("door",0)==2) {
core.stopReplay();
core.waitHeroToStop(function() {
core.removeGlobalAnimate(0,0,true);
core.clearMap('all'); // 清空全地图
core.clearMap('all'); core.clearMap('curtain'); // 清空全地图
core.drawText([
"\t[恭喜通关]你的分数是${status:hp}。"
], function () {

View File

@ -17,10 +17,10 @@ HTML5魔塔是使用画布canvas来绘制存在若干个图层它们
- fg前景层绘制前景图层素材fgmap和前景贴图
- damage显伤层主要用来绘制怪物显伤和领域显伤
- animate动画层主要用来绘制动画。showImage事件绘制的图片也是在这一层。
- image图片层主要用来绘制显示图片
- weather天气层主要用来绘制天气雨/雪)
- route路线层主要用来绘制勇士的行走路线图也用来绘制图块的淡入/淡出效果,图块的移动等。
- curtain色调层用来控制当前楼层的画面色调
- image图片层主要用来绘制显示图片该层之所以在curtain层上是为了可以在全黑时贴大头像图
- uiUI层用来绘制一切UI窗口如剧情文本、怪物手册、楼传器、系统菜单等等
- data数据层用来绘制一些顶层的或更新比较快的数据如左上角的提示战斗界面中数据的变化等等。
@ -51,7 +51,7 @@ HTML5魔塔是使用画布canvas来绘制存在若干个图层它们
在地图编辑器中绘图时,下拉框选中“背景层”或“前景层”即可在对应的图层上绘图。
其中背景层和前景层仅为静态绘图(不支持动画),但可以使用自动元件autotile
其中背景层和前景层可以使用任何素材,以及使用自动元件autotile
可以使用`showBgFgMap`, `hideBgFgMap`, `setBgFgBlock`等事件对背景和前景图层进行操作。
@ -560,6 +560,39 @@ this.myfunc = function(x) {
通过这种将脚本和自定义事件混用的方式可以达到和RM中公共事件类似的效果即一个调用触发一系列事件。
-->
## 标题界面事件化
从V2.5.3开始,我们可以将标题界面的绘制和游戏开始用事件来完成。可以通过绘制画布、
全塔属性flags中的startUsingCanvas可以决定是否开启标题界面事件化。
然后就可以使用“事件流”的形式来绘制标题界面、提供选项等等。
在这里可以调用任意事件。例如,可以贴若干个图,可以事件切换楼层到某个剧情层再执行若干事件,等等。
关于选项样板默认给出的是最简单的choices事件你也可以使用贴按钮图循环处理+等待操作来定制自己的按钮点击效果。
!> 开始游戏、读取存档、录像回放的效果已经默认给出,请不要修改或删减这些内容,以免出现问题。
标题界面事件全部处理完后将再继续执行startText事件。
## 手机端按键模式
从V2.5.3以后,我们可以给手机端增加按键了,这样将非常有利于技能的释放。
当用户在竖屏模式下点击工具栏,就会在工具栏按钮和快捷键模式之间进行切换。
切换到快捷键模式后可以点1-7分别等价于在电脑端按键1-7。
可以在脚本编辑的onKeyUp中定义每个快捷键的使用效果比如使用道具或释放技能等。
默认值下1使用破2使用炸3使用飞4使用其他存在的道具5-7未定义。可以相应修改成自己的效果。
也可以替换icons.png中的对应图标以及修改main.js中`main.statusBar.image.btn1~7`中的onclick事件来自定义按钮和对应按键。
非竖屏模式下、回放录像中、隐藏状态栏中,将不允许进行切换。
## 自定义状态栏(新增显示项)
在V2.2以后,我们可以自定义状态栏背景图(全塔属性 - statusLeftBackground等等。
@ -577,7 +610,7 @@ this.myfunc = function(x) {
</div>
```
3. 在editor.html中的statusBar323行起仿照第二点同样添加这一项如果不进行则会地图编辑器报错。editor-mobile.html同理。
4. 使用便捷PS工具打开icons.png新增一行并将魔力的图标P上去记下其索引比如30从0开始数
4. 使用便捷PS工具打开icons.png新增一行并将魔力的图标P上去记下其索引比如37从0开始数
5. 在main.js的this.statusBar中增加图片、图标和内容的定义。
``` js
this.statusBar = {

View File

@ -174,6 +174,7 @@
<option value="afterGetItem">afterGetItem</option>
<option value="afterOpenDoor">afterOpenDoor</option>
<option value="firstArrive">firstArrive</option>
<option value="eachArrive">eachArrive</option>
</select>
<button onclick="editor_blockly.confirm()">确认</button>
<button onclick="editor_blockly.parse()">解析</button>
@ -412,6 +413,13 @@
<img class="tools" id='img-save'>
<img class="tools" id='img-load'>
<img class="tools" id='img-settings'>
<img class="tools" id='img-btn1' style='display:none'>
<img class="tools" id='img-btn2' style='display:none'>
<img class="tools" id='img-btn3' style='display:none'>
<img class="tools" id='img-btn4' style='display:none'>
<img class="tools" id='img-btn5' style='display:none'>
<img class="tools" id='img-btn6' style='display:none'>
<img class="tools" id='img-btn7' style='display:none'>
<p class="statusLabel tools" id="hard"></p>
</div>
<div id="gameDraw">

View File

@ -173,6 +173,7 @@
<option value="afterGetItem">afterGetItem</option>
<option value="afterOpenDoor">afterOpenDoor</option>
<option value="firstArrive">firstArrive</option>
<option value="eachArrive">eachArrive</option>
</select>
<button onclick="editor_blockly.confirm()">确认</button>
<button onclick="editor_blockly.parse()">解析</button>
@ -398,6 +399,13 @@
<img class="tools" id='img-save'>
<img class="tools" id='img-load'>
<img class="tools" id='img-settings'>
<img class="tools" id='img-btn1' style='display:none'>
<img class="tools" id='img-btn2' style='display:none'>
<img class="tools" id='img-btn3' style='display:none'>
<img class="tools" id='img-btn4' style='display:none'>
<img class="tools" id='img-btn5' style='display:none'>
<img class="tools" id='img-btn6' style='display:none'>
<img class="tools" id='img-btn7' style='display:none'>
<p class="statusLabel tools" id="hard"></p>
</div>
<div id="gameDraw">

View File

@ -118,6 +118,13 @@
<img class="tools" id='img-save'>
<img class="tools" id='img-load'>
<img class="tools" id='img-settings'>
<img class="tools" id='img-btn1' style='display:none'>
<img class="tools" id='img-btn2' style='display:none'>
<img class="tools" id='img-btn3' style='display:none'>
<img class="tools" id='img-btn4' style='display:none'>
<img class="tools" id='img-btn5' style='display:none'>
<img class="tools" id='img-btn6' style='display:none'>
<img class="tools" id='img-btn7' style='display:none'>
<p class="statusLabel tools" id="hard"></p>
</div>
<div id="gameDraw">

View File

@ -166,6 +166,9 @@ actions.prototype.keyDown = function(keyCode) {
if (core.status.event.id=='replay') {
this.keyDownReplay(keyCode);
}
if (core.status.event.id=='gameInfo') {
this.keyDownGameInfo(keyCode);
}
return;
}
if(!core.status.played) {
@ -280,6 +283,10 @@ actions.prototype.keyUp = function(keyCode, altKey) {
this.keyUpReplay(keyCode);
return;
}
if (core.status.event.id=='gameInfo') {
this.keyUpGameInfo(keyCode);
return;
}
if (core.status.event.id=='centerFly') {
this.keyUpCenterFly(keyCode);
return;
@ -590,6 +597,10 @@ actions.prototype.onclick = function (x, y, stepPostfix) {
return;
}
if (core.status.event.id=='gameInfo') {
this.clickGameInfo(x,y);
}
}
////// 滑动鼠标滚轮时的操作 //////
@ -991,7 +1002,6 @@ actions.prototype.clickViewMaps = function (x,y) {
}
else if (x>=2 && x<=10 && y>=5 && y<=7) {
core.clearMap('data');
core.setOpacity('data', 1);
core.ui.closePanel();
}
}
@ -1020,7 +1030,6 @@ actions.prototype.keyUpViewMaps = function (keycode) {
if (keycode==27 || keycode==13 || keycode==32 || (!core.status.replay.replaying && keycode==67)) {
core.clearMap('data');
core.setOpacity('data', 1);
core.ui.closePanel();
return;
}
@ -1903,25 +1912,10 @@ actions.prototype.clickSettings = function (x,y) {
core.ui.drawSyncSave();
break;
case 5:
core.ui.drawStatistics();
core.status.event.selection=0;
core.ui.drawGameInfo();
break;
case 6:
if (core.platform.isPC) {
window.open("/score.php?name="+core.firstData.name+"&num=10", "_blank");
}
else {
if (confirm("即将离开本塔,跳转至本塔评论页面,确认?")) {
window.location.href = "/score.php?name="+core.firstData.name+"&num=10";
}
}
break;
case 7:
core.ui.drawHelp();
break;
case 8:
core.ui.drawAbout();
break;
case 9:
core.status.event.selection=1;
core.ui.drawConfirmBox("你确定要返回标题页面吗?", function () {
core.ui.closePanel();
@ -1931,7 +1925,7 @@ actions.prototype.clickSettings = function (x,y) {
core.ui.drawSettings();
});
break;
case 10:
case 7:
core.ui.closePanel();
break;
}
@ -2057,7 +2051,7 @@ actions.prototype.clickSyncSave = function (x,y) {
core.ui.drawStorageRemove();
break;
case 7:
core.status.event.selection=3;
core.status.event.selection=4;
core.ui.drawSettings();
break;
@ -2291,7 +2285,7 @@ actions.prototype.clickStorageRemove = function (x, y) {
}
break;
case 2:
core.status.event.selection=5;
core.status.event.selection=6;
core.ui.drawSyncSave();
break;
}
@ -2414,6 +2408,77 @@ actions.prototype.keyUpReplay = function (keycode) {
}
}
////// 游戏信息界面时的点击操作 //////
actions.prototype.clickGameInfo = function (x, y) {
if (x<5 || x>7) return;
var choices = core.status.event.ui.choices;
var topIndex = 6 - parseInt((choices.length - 1) / 2);
if (y>=topIndex && y<topIndex+choices.length) {
var selection = y - topIndex;
switch (selection) {
case 0:
core.ui.drawStatistics();
break;
case 1:
if (core.platform.isPC) {
window.open("/score.php?name="+core.firstData.name+"&num=10", "_blank");
}
else {
if (confirm("即将离开本塔,跳转至本塔评论页面,确认?")) {
window.location.href = "/score.php?name="+core.firstData.name+"&num=10";
}
}
break;
case 2:
core.ui.drawHelp();
break;
case 3:
core.ui.drawAbout();
break;
case 4:
core.status.event.selection=5;
core.ui.drawSettings();
break;
}
}
}
////// 游戏信息界面时,按下某个键的操作 //////
actions.prototype.keyDownGameInfo = function (keycode) {
if (keycode==38) {
core.status.event.selection--;
core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices);
}
if (keycode==40) {
core.status.event.selection++;
core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices);
}
}
////// 游戏信息界面时,放开某个键的操作 //////
actions.prototype.keyUpGameInfo = function (keycode) {
if (keycode==27 || keycode==88) {
core.ui.closePanel();
return;
}
var choices = core.status.event.ui.choices;
if (keycode==13 || keycode==32 || keycode==67) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
this.clickGameInfo(6, topIndex+core.status.event.selection);
}
// 数字键快速选择
if (keycode>=49 && keycode<=57) {
var index = keycode-49;
if (index<choices.length) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
this.clickGameInfo(6, topIndex+index);
}
}
}
////// “虚拟键盘”界面时的点击操作 //////
actions.prototype.clickKeyBoard = function (x, y) {
if (y==3 && x>=1 && x<=11) {

View File

@ -70,7 +70,7 @@ control.prototype.setRequestAnimationFrame = function () {
}
// Global Animate
if (core.animateFrame.globalAnimate && core.isPlaying()) {
if (core.animateFrame.globalAnimate && core.isPlaying() && core.isset(core.status.floorId)) {
if (timestamp-core.animateFrame.globalTime>core.animateFrame.speed && core.isset(core.status.globalAnimateObjs)) {
@ -81,9 +81,21 @@ control.prototype.setRequestAnimationFrame = function () {
}
if ((core.status.autotileAnimateObjs.blocks||[]).length>0) {
var groundId = (core.status.maps||core.floors)[core.status.floorId].defaultGround || "ground";
var blockIcon = core.material.icons.terrains[groundId];
core.status.autotileAnimateObjs.status++;
core.status.autotileAnimateObjs.blocks.forEach(function (block) {
core.drawAutotile(core.canvas.event, core.status.autotileAnimateObjs.map, block, 32, 0, 0, core.status.autotileAnimateObjs.status);
var cv = core.isset(block.name)?core.canvas[block.name]:core.canvas.event;
cv.clearRect(block.x * 32, block.y * 32, 32, 32);
if (core.isset(block.name)) {
if (block.name == 'bg') {
core.canvas.bg.drawImage(core.material.images.terrains, 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32);
}
core.drawAutotile(cv, core.status.autotileAnimateObjs[block.name+"map"], block, 32, 0, 0, core.status.autotileAnimateObjs.status);
}
else {
core.drawAutotile(cv, core.status.autotileAnimateObjs.map, block, 32, 0, 0, core.status.autotileAnimateObjs.status);
}
})
}
@ -221,6 +233,15 @@ control.prototype.showStartAnimate = function (noAnimate, callback) {
core.status.played = false;
core.clearStatus();
core.clearMap('all');
core.clearMap('curtain');
if (core.flags.startUsingCanvas) {
core.dom.startTop.style.display = 'none';
core.dom.startButtonGroup.style.display = 'block';
core.events.startGame('');
if (core.isset(callback)) callback();
return;
}
if(noAnimate) {
core.dom.startTop.style.display = 'none';
@ -444,7 +465,7 @@ control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) {
core.control.tryMoveDirectly(destX, destY);
}
core.status.automaticRoute.moveDirectly = false;
}, 100);
}, core.values.moveSpeed || 100);
}
return;
}
@ -693,7 +714,7 @@ control.prototype.setHeroMoveInterval = function (direction, x, y, callback) {
core.status.heroMoving = 0;
if (core.isset(callback)) callback();
}
}, 12.5 * toAdd / core.status.replay.speed);
}, (core.values.moveSpeed||100) / 8 * toAdd / core.status.replay.speed);
}
////// 实际每一步的行走过程 //////
@ -836,7 +857,7 @@ control.prototype.moveHero = function (direction, callback) {
/////// 使用事件让勇士移动。这个函数将不会触发任何事件 //////
control.prototype.eventMoveHero = function(steps, time, callback) {
time = time || 100;
time = time || core.values.moveSpeed || 100;
// 要运行的轨迹将steps展开
var moveSteps=[];
@ -867,6 +888,7 @@ control.prototype.eventMoveHero = function(steps, time, callback) {
var animate=window.setInterval(function() {
var x=core.getHeroLoc('x'), y=core.getHeroLoc('y');
if (moveSteps.length==0) {
delete core.animateFrame.asyncId[animate];
clearInterval(animate);
core.drawHero(null, x, y);
if (core.isset(callback)) callback();
@ -889,7 +911,9 @@ control.prototype.eventMoveHero = function(steps, time, callback) {
moveSteps.shift();
}
}
}, time / 8 / core.status.replay.speed)
}, time / 8 / core.status.replay.speed);
core.animateFrame.asyncId[animate] = true;
}
////// 勇士跳跃事件 //////
@ -944,6 +968,7 @@ control.prototype.jumpHero = function (ex, ey, time, callback) {
nowx - core.bigmap.offsetX, nowy + 32-height - core.bigmap.offsetY, 32, height);
}
else {
delete core.animateFrame.asyncId[animate];
clearInterval(animate);
core.setHeroLoc('x', ex);
core.setHeroLoc('y', ey);
@ -953,8 +978,7 @@ control.prototype.jumpHero = function (ex, ey, time, callback) {
}, time / 16 / core.status.replay.speed);
core.animateFrame.asyncId[animate] = true;
}
////// 每移动一格后执行的事件 //////
@ -1025,7 +1049,7 @@ control.prototype.updateViewport = function() {
////// 绘制勇士 //////
control.prototype.drawHero = function (direction, x, y, status, offset) {
if (!core.isPlaying() || core.status.isStarting) return;
if (!core.isPlaying()) return;
var scan = {
'up': {'x': 0, 'y': -1},
@ -1492,26 +1516,26 @@ control.prototype.setFg = function(color, time, callback) {
core.fillRect('curtain', 0, 0, 416, 416, core.arrayToRGBA([nowR,nowG,nowB,nowA]));
if (step>=25) {
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);
core.animateFrame.asyncId[changeAnimate] = true;
}
////// 更新全地图显伤 //////
control.prototype.updateDamage = function (floorId, canvas) {
if (!core.isset(floorId)) floorId = core.status.floorId;
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) return;
if (!core.isset(canvas)) {
canvas = core.canvas.damage;
core.clearMap('damage');
}
// 正在开始游戏中
if (core.status.isStarting) return;
// 更新显伤
var mapBlocks = core.status.maps[floorId].blocks;
// 没有怪物手册
@ -1655,15 +1679,21 @@ control.prototype.chooseReplayFile = function () {
}
if (core.isset(obj.version) && obj.version!=core.firstData.version) {
// alert("游戏版本不一致!");
if (!confirm("游戏版本不一致!\n你仍然想播放录像吗"))
if (!confirm("游戏版本不一致!\n你仍然想播放录像吗")) {
return;
}
}
if (!core.isset(obj.route) || !core.isset(obj.hard)) {
if (!core.isset(obj.route)) {
alert("无效的录像!");
return;
}
core.startGame(obj.hard, obj.seed, core.decodeRoute(obj.route));
if (core.flags.startUsingCanvas) {
core.startGame('', obj.seed, core.decodeRoute(obj.route));
}
else {
core.startGame(obj.hard, obj.seed, core.decodeRoute(obj.route));
}
}, function () {
})
@ -2672,6 +2702,16 @@ control.prototype.playSound = function (sound) {
}
}
control.prototype.checkBgm = function() {
if (core.musicStatus.startDirectly && core.musicStatus.bgmStatus) {
if (core.musicStatus.playingBgm==null
|| core.material.bgms[core.musicStatus.playingBgm].paused) {
core.musicStatus.playingBgm=null;
core.playBgm(core.bgms[0]);
}
}
}
////// 清空状态栏 //////
control.prototype.clearStatusBar = function() {
@ -2738,7 +2778,8 @@ control.prototype.triggerStatusBar = function (name) {
if (name!='hide') name='show';
var statusItems = core.dom.status;
var toolItems = core.dom.tools;
if (name == 'hide') {
core.domStyle.showStatusBar = name == 'show';
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)
@ -2747,10 +2788,8 @@ control.prototype.triggerStatusBar = function (name) {
else {
for (var i = 0; i < statusItems.length; ++i)
statusItems[i].style.opacity = 1;
for (var i = 0; i < toolItems.length; ++i)
toolItems[i].style.display = 'block';
if (core.domStyle.screenMode != 'vertical')
core.statusBar.image.shop.style.display = 'none';
this.setToolbarButton(false);
core.dom.tools.hard.style.display = 'block';
}
}
@ -2832,6 +2871,33 @@ control.prototype.updateGlobalAttribute = function (name) {
}
}
////// 改变工具栏为按钮1-7 //////
control.prototype.setToolbarButton = function (useButton) {
if (!core.domStyle.showStatusBar) return;
if (!core.isset(useButton)) useButton = core.domStyle.toolbarBtn;
if (core.domStyle.screenMode != 'vertical') useButton = false;
core.domStyle.toolbarBtn = useButton;
if (useButton) {
["book","fly","toolbox","shop","save","load","settings"].forEach(function (t) {
core.statusBar.image[t].style.display = 'none';
});
["btn1","btn2","btn3","btn4","btn5","btn6","btn7"].forEach(function (t) {
core.statusBar.image[t].style.display = 'block';
})
}
else {
["btn1","btn2","btn3","btn4","btn5","btn6","btn7"].forEach(function (t) {
core.statusBar.image[t].style.display = 'none';
});
["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";
}
}
////// 屏幕分辨率改变后重新自适应 //////
control.prototype.resize = function(clientWidth, clientHeight) {
if (main.mode=='editor')return;
@ -2894,6 +2960,8 @@ control.prototype.resize = function(clientWidth, clientHeight) {
var zoom = (ADAPT_WIDTH - width) / 4.22;
var aScale = 1 - zoom / 100;
core.domStyle.toolbarBtn = false;
// 移动端
if (width < CHANGE_WIDTH) {
if(width < ADAPT_WIDTH){
@ -3132,7 +3200,7 @@ control.prototype.resize = function(clientWidth, clientHeight) {
{
imgId: 'shop',
rules:{
display: shopDisplay
display: shopDisplay && core.domStyle.showStatusBar
}
},
{
@ -3222,6 +3290,7 @@ control.prototype.resize = function(clientWidth, clientHeight) {
},
]
core.domRenderer();
this.setToolbarButton();
}
////// 渲染DOM //////

View File

@ -41,7 +41,8 @@ function core() {
'level': 0,
'nodes': [],
'data': null,
}
},
"asyncId": {}
}
this.musicStatus = {
'audioContext': null, // WebAudioContext
@ -73,6 +74,8 @@ function core() {
this.domStyle = {
styles: [],
scale: 1.0,
toolbarBtn: false,
showStatusBar: true,
}
this.bigmap = {
canvas: ["bg", "event", "event2", "fg", "damage", "route"],
@ -176,7 +179,7 @@ function core() {
// 动画
'globalAnimateObjs': [],
'boxAnimateObjs': [],
'autotileAnimateObjs': {},
'autotileAnimateObjs': {"status": 0, "blocks": [], "map": null, "bgmap": null, "fgmap": null},
'animateObjs': [],
};
this.status = {};

View File

@ -91,14 +91,15 @@ events.prototype.initGame = function () {
////// 游戏开始事件 //////
events.prototype.startGame = function (hard, seed, route, callback) {
if (core.status.isStarting) return;
core.status.isStarting = true;
main.dom.levelChooseButtons.style.display='none';
main.dom.startButtonGroup.style.display='none';
var start = function () {
console.log('开始游戏');
core.resetStatus(core.firstData.hero, hard, core.firstData.floorId, null, core.initStatus.maps);
core.status.isStarting = true;
core.resetStatus(core.firstData.hero, hard, null, null, core.initStatus.maps);
var nowLoc = core.clone(core.getHeroLoc());
core.setHeroLoc('x', -1);
core.setHeroLoc('y', -1);
if (core.isset(seed)) {
core.setFlag('__seed__', seed);
@ -106,15 +107,15 @@ events.prototype.startGame = function (hard, seed, route, callback) {
}
else core.utils.__init_seed();
core.events.setInitData(hard);
core.clearMap('all');
core.clearMap('curtain');
core.clearStatusBar();
var post_start = function () {
core.status.isStarting = false;
core.control.triggerStatusBar('show');
core.changeFloor(core.status.floorId, null, core.status.hero.loc, null, function() {
core.changeFloor(core.firstData.floorId, null, nowLoc, null, function() {
if (core.isset(callback)) callback();
}, true);
@ -125,7 +126,7 @@ events.prototype.startGame = function (hard, seed, route, callback) {
formData.append('name', core.firstData.name);
formData.append('version', core.firstData.version);
formData.append('platform', core.platform.isPC?"PC":core.platform.isAndroid?"Android":core.platform.isIOS?"iOS":"");
formData.append('hard', core.encodeBase64(hard));
formData.append('hard', core.encodeBase64(core.status.hard));
formData.append('hardCode', core.getFlag('hard', 0));
formData.append('base64', 1);
@ -133,23 +134,36 @@ events.prototype.startGame = function (hard, seed, route, callback) {
})
}
core.insertAction(core.clone(core.firstData.startText), null, null, function() {
if (!core.status.replay.replaying && core.flags.showBattleAnimateConfirm) { // 是否提供“开启战斗动画”的选择项
core.status.event.selection = core.flags.battleAnimate ? 0 : 1;
core.ui.drawConfirmBox("你想开启战斗动画吗?\n之后可以在菜单栏中开启或关闭。\n强烈建议新手开启此项", function () {
core.flags.battleAnimate = true;
core.setLocalStorage('battleAnimate', true);
var real_start = function () {
core.insertAction(core.clone(core.firstData.startText), null, null, function() {
if (!core.flags.startUsingCanvas && !core.status.replay.replaying && core.flags.showBattleAnimateConfirm) { // 是否提供“开启战斗动画”的选择项
core.status.event.selection = core.flags.battleAnimate ? 0 : 1;
core.ui.drawConfirmBox("你想开启战斗动画吗?\n之后可以在菜单栏中开启或关闭。\n强烈建议新手开启此项", function () {
core.flags.battleAnimate = true;
core.setLocalStorage('battleAnimate', true);
post_start();
}, function () {
core.flags.battleAnimate = false;
core.setLocalStorage('battleAnimate', false);
post_start();
});
}
else {
post_start();
}, function () {
core.flags.battleAnimate = false;
core.setLocalStorage('battleAnimate', false);
post_start();
});
}
else {
post_start();
}
});
}
});
}
if (core.flags.startUsingCanvas) {
core.control.triggerStatusBar('hide');
core.insertAction(core.clone(core.firstData.startCanvas), null, null, function() {
real_start();
});
}
else {
core.events.setInitData(hard);
real_start();
}
if (core.isset(route)) {
core.startReplay(route);
@ -157,6 +171,12 @@ events.prototype.startGame = function (hard, seed, route, callback) {
}
if (core.flags.startUsingCanvas) {
core.dom.startPanel.style.display = 'none';
start();
return;
}
if (core.isset(route)) {
core.dom.startPanel.style.display = 'none';
start();
@ -290,12 +310,7 @@ events.prototype.gameOver = function (ending, fromReplay, norank) {
}
else {
if (core.isset(core.values.maxValidHp) && core.status.hero.hp>core.values.maxValidHp) {
core.drawText("作弊可耻!", function () {
core.restart();
});
}
else if (core.hasFlag('debug')) {
if (core.hasFlag('debug')) {
core.drawText("\t[系统提示]调试模式下无法上传成绩", function () {
core.restart();
})
@ -438,12 +453,15 @@ events.prototype.doAction = function() {
&& (typeof data.loc[1] == 'number' || typeof data.loc[1] == 'string'))
data.loc = [[core.calValue(data.loc[0]), core.calValue(data.loc[1])]];
if (core.isset(data.time) && data.time>0 && (!core.isset(data.floorId) || data.floorId==core.status.floorId)) {
core.animateBlock(data.loc,'show', data.time, function () {
data.loc.forEach(function (t) {
core.showBlock(t[0],t[1],data.floorId);
})
core.events.doAction();
});
if (data.async) {
core.animateBlock(data.loc, 'show', data.time);
this.doAction();
}
else {
core.animateBlock(data.loc,'show', data.time, function () {
core.events.doAction();
});
}
}
else {
data.loc.forEach(function (t) {
@ -461,13 +479,16 @@ events.prototype.doAction = function() {
if (core.isset(data.time) && data.time>0 && (!core.isset(data.floorId) || data.floorId==core.status.floorId)) {
data.loc.forEach(function (t) {
core.hideBlock(t[0],t[1],data.floorId);
})
core.animateBlock(data.loc,'hide',data.time, function () {
data.loc.forEach(function (t) {
core.removeBlock(t[0],t[1],data.floorId)
})
core.events.doAction();
});
if (data.async) {
core.animateBlock(data.loc, 'hide', data.time);
this.doAction();
}
else {
core.animateBlock(data.loc,'hide', data.time, function () {
core.events.doAction();
});
}
}
else {
data.loc.forEach(function (t) {
@ -1059,7 +1080,7 @@ events.prototype.doAction = function() {
core.updateStatusBar();
this.doAction();
break;
case "viberate":
case "vibrate":
if (data.async) {
core.events.vibrate(data.time);
this.doAction();
@ -1102,6 +1123,16 @@ events.prototype.doAction = function() {
}
}
break;
case "waitAsync": // 等待所有异步事件执行完毕
{
var test = window.setInterval(function () {
if (Object.keys(core.animateFrame.asyncId)==0) {
clearInterval(test);
core.events.doAction();
}
}, 50);
break;
}
case "revisit": // 立刻重新执行该事件
{
var block=core.getBlock(x,y); // 重新获得事件
@ -1312,6 +1343,7 @@ events.prototype.trigger = function (x, y) {
events.prototype.setFloorName = function (floorId) {
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) return;
// 根据文字判断是否斜体
var floorName = core.status.maps[floorId].name || "";
if (typeof floorName == 'number') floorName = ""+floorName;
@ -1336,7 +1368,11 @@ events.prototype.setFloorName = function (floorId) {
////// 楼层切换 //////
events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback, fromLoad) {
if (!core.isset(floorId)) floorId = core.status.floorId;
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) {
if (core.isset(callback)) callback();
return;
}
if (floorId == ':before') {
var index=core.floorIds.indexOf(core.status.floorId);
@ -1495,33 +1531,40 @@ events.prototype.animateImage = function (type, image, loc, time, keep, callback
}
clearInterval(core.interval.tipAnimate);
core.setAlpha('data', 1);
var opacityVal = 0;
if (type == 'hide') opacityVal = 1;
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');
core.clearMap('image', x, y, image.width, image.height);
}
core.setOpacity('data', opacityVal);
var x = core.calValue(loc[0]), y = core.calValue(loc[1]);
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') opacityVal += 0.1;
else opacityVal -= 0.1;
core.setOpacity('data', opacityVal);
if (opacityVal >=1 || opacityVal<=0) {
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.clearMap('data');
core.setOpacity('data', 1);
// core.status.replay.animate=false;
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);
core.animateFrame.asyncId[animate] = true;
}
////// 移动图片 //////
@ -1529,7 +1572,6 @@ events.prototype.moveImage = function (image, from, to, time, keep, callback) {
time = time || 1000;
clearInterval(core.interval.tipAnimate);
core.setAlpha('data', 1);
core.setOpacity('data', 1);
var width = image.width, height = image.height;
@ -1554,13 +1596,14 @@ events.prototype.moveImage = function (image, from, to, time, keep, callback) {
if (step <= steps)
drawImage();
else {
delete core.animateFrame.asyncId[animate];
clearInterval(animate);
// score.clearMap('data');
// core.status.replay.animate=false;
if (keep) core.canvas.image.drawImage(image, toX, toY);
if (core.isset(callback)) callback();
}
}, per_time);
core.animateFrame.asyncId[animate] = true;
}
////// 淡入淡出音乐 //////
@ -1587,12 +1630,15 @@ events.prototype.setVolume = function (value, time, callback) {
var nowVolume = currVolume+(value-currVolume)*step/32;
set(nowVolume);
if (step>=32) {
delete core.animateFrame.asyncId[fade];
clearInterval(fade);
// core.status.replay.animate=false;
if (core.isset(callback))
callback();
}
}, time / 32);
core.animateFrame.asyncId[fade] = true;
}
////// 画面震动 //////
@ -1650,11 +1696,14 @@ events.prototype.vibrate = function(time, callback) {
update();
addGameCanvasTranslate(shake, 0);
if(shake_duration===0) {
delete core.animateFrame.asyncId[animate];
clearInterval(animate);
// core.status.replay.animate=false;
if (core.isset(callback)) callback();
}
}, 50/3);
core.animateFrame.asyncId[animate] = true;
}
////// 打开一个全局商店 //////

View File

@ -211,6 +211,7 @@ maps.prototype.save = function(maps, floorId) {
////// 更改地图画布的尺寸
maps.prototype.resizeMap = function(floorId) {
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) return;
core.bigmap.width = core.floors[floorId].width || 13;
core.bigmap.height = core.floors[floorId].height || 13;
var cwidth = core.bigmap.width * 32;
@ -229,7 +230,7 @@ maps.prototype.resizeMap = function(floorId) {
////// 将存档中的地图信息重新读取出来 //////
maps.prototype.load = function (data, floorId) {
if (floorId == undefined) {
if (!core.isset(floorId)) {
var map = {};
core.floorIds.forEach(function (id) {
map[id] = core.maps.loadFloor(id, data[id]);
@ -266,7 +267,8 @@ maps.prototype.canMoveHero = function(x,y,direction,floorId) {
if (!core.isset(x)) x=core.getHeroLoc('x');
if (!core.isset(y)) y=core.getHeroLoc('y');
if (!core.isset(direction)) direction=core.getHeroLoc('direction');
if (!core.isset(floorId)) floorId=core.status.floorId;
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) return false;
// 检查当前块的cannotMove
if (core.isset(core.floors[floorId].cannotMove)) {
@ -384,6 +386,17 @@ maps.prototype.drawBlock = function (block, animate, dx, dy) {
dx = dx || 0;
dy = dy || 0;
if (core.isset(block.name)) {
core.canvas[block.name].clearRect(block.x * 32, block.y * 32, 32, 32);
if (block.name == 'bg') {
var groundId = (core.status.maps||core.floors)[core.status.floorId].defaultGround || "ground";
var blockIcon = core.material.icons.terrains[groundId];
core.canvas.bg.drawImage(core.material.images.terrains, 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32);
}
core.canvas[block.name].drawImage(image, x * 32, y * 32, 32, 32, block.x * 32, block.y * 32, 32, 32);
return;
}
core.canvas.event.clearRect(block.x * 32 + dx, block.y * 32 + dy, 32, 32);
core.canvas.event.drawImage(image, x * 32, y * height + height-32, 32, 32, block.x * 32 + dx, block.y * 32 + dy, 32, 32);
if (height>32) {
@ -394,6 +407,7 @@ maps.prototype.drawBlock = function (block, animate, dx, dy) {
maps.prototype.getBgFgMapArray = function (floorId, name) {
floorId = floorId||core.status.floorId;
if (!core.isset(floorId)) return [];
var width = core.floors[floorId].width || 13;
var height = core.floors[floorId].height || 13;
@ -415,8 +429,9 @@ maps.prototype.getBgFgMapArray = function (floorId, name) {
}
////// 背景/前景图块的绘制 //////
maps.prototype.drawBgFgMap = function (floorId, canvas, name) {
maps.prototype.drawBgFgMap = function (floorId, canvas, name, animate) {
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) return;
var width = core.floors[floorId].width || 13;
var height = core.floors[floorId].height || 13;
@ -428,10 +443,15 @@ maps.prototype.drawBgFgMap = function (floorId, canvas, name) {
for (var y = 0; y < height; y++) {
if (arr[y][x]>0) {
var block = core.maps.initBlock(x, y, arr[y][x]);
this.addInfo(block);
block.name = name;
if (core.isset(block.event)) {
var id = block.event.id, cls = block.event.cls;
if (cls == 'autotile')
if (cls == 'autotile') {
core.drawAutotile(canvas, arr, block, 32, 0, 0);
if (animate)
core.status.autotileAnimateObjs.blocks.push(core.clone(block));
}
else if (cls == 'tileset') {
var offset = core.icons.getTilesetOffset(id);
if (offset!=null) {
@ -443,18 +463,30 @@ maps.prototype.drawBgFgMap = function (floorId, canvas, name) {
canvas.drawImage(core.material.images.airwall, 32*x, 32*y);
}
}
else
canvas.drawImage(core.material.images[cls], 0, core.material.icons[cls][id] * 32, 32, 32, x * 32, y * 32, 32, 32);
else {
if (animate) {
this.drawBlock(block);
this.addGlobalAnimate(block);
}
else {
canvas.drawImage(core.material.images[cls], 0, core.material.icons[cls][id] * 32, 32, 32, x * 32, y * 32, 32, 32);
}
}
}
}
}
}
core.status.autotileAnimateObjs[name+"map"] = core.clone(arr);
}
////// 绘制某张地图 //////
maps.prototype.drawMap = function (mapName, callback) {
mapName = mapName || core.status.floorId;
if (!core.isset(mapName)) {
if (core.isset(callback))
callback();
return;
}
core.clearMap('all');
core.removeGlobalAnimate(null, null, true);
@ -511,8 +543,8 @@ maps.prototype.drawMap = function (mapName, callback) {
}
});
core.maps.drawBgFgMap(mapName, core.canvas.bg, "bg");
core.maps.drawBgFgMap(mapName, core.canvas.fg, "fg");
core.maps.drawBgFgMap(mapName, core.canvas.bg, "bg", true);
core.maps.drawBgFgMap(mapName, core.canvas.fg, "fg", true);
}
if (main.mode=='editor'){
@ -531,7 +563,6 @@ maps.prototype.drawMap = function (mapName, callback) {
core.status.floorId = mapName;
core.status.thisMap = core.status.maps[mapName];
var drawEvent = function(){
core.status.autotileAnimateObjs = {"status": 0, "blocks": [], "map": null};
var mapData = core.status.maps[core.status.floorId];
var mapBlocks = mapData.blocks;
@ -707,7 +738,8 @@ maps.prototype.enemyExists = function (x, y, id,floorId) {
////// 获得某个点的block //////
maps.prototype.getBlock = function (x, y, floorId, showDisable) {
if (!core.isset(floorId)) floorId=core.status.floorId;
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) return null;
var blocks = core.status.maps[floorId].blocks;
for (var n=0;n<blocks.length;n++) {
if (blocks[n].x==x && blocks[n].y==y && core.isset(blocks[n].event)) {
@ -831,13 +863,14 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) {
else alpha -= 0.06;
core.clearMap('route', nowX, nowY-height+32, 32, height);
if (alpha<=0) {
delete core.animateFrame.asyncId[animate];
clearInterval(animate);
// 不消失
if (keep) {
core.setBlock(id, nowX/32, nowY/32);
core.showBlock(nowX/32, nowY/32);
}
// core.status.replay.animate=false;
core.setAlpha('route',1);
if (core.isset(callback)) callback();
}
else {
@ -872,6 +905,9 @@ maps.prototype.moveBlock = function(x,y,steps,time,keep,callback) {
}
}
}, time / 16 / core.status.replay.speed);
core.animateFrame.asyncId[animate] = true;
}
////// 显示跳跃某块的动画,达到{"type":"jump"}的效果 //////
@ -970,9 +1006,10 @@ maps.prototype.jumpBlock = function(sx,sy,ex,ey,time,keep,callback) {
else alpha -= 0.06;
core.clearMap('route', drawX(), drawY()-height+32, 32, height);
if (alpha<=0) {
delete core.animateFrame.asyncId[animate];
clearInterval(animate);
core.clearMap('route');
core.setOpacity('route', 1);
core.setAlpha('route', 1);
if (keep) {
core.setBlock(id, ex, ey);
core.showBlock(ex, ey);
@ -987,14 +1024,14 @@ maps.prototype.jumpBlock = function(sx,sy,ex,ey,time,keep,callback) {
}
}, time / 16 / core.status.replay.speed);
core.animateFrame.asyncId[animate] = true;
}
////// 显示/隐藏某个块时的动画效果 //////
maps.prototype.animateBlock = function (loc,type,time,callback) {
if (type!='hide') type='show';
core.clearMap('route');
if (typeof loc[0] == 'number' && typeof loc[1] == 'number')
loc = [loc];
@ -1037,43 +1074,64 @@ maps.prototype.animateBlock = function (loc,type,time,callback) {
}
// 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 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);
})
}
var opacityVal = 0;
if (type=='hide') opacityVal=1;
var alpha = 0;
if (type=='hide') alpha=1;
core.setOpacity('route', opacityVal);
core.setAlpha('route', alpha);
draw();
var animate = window.setInterval(function () {
if (type=='show') opacityVal += 0.1;
else opacityVal -= 0.1;
core.setOpacity('route', opacityVal);
if (opacityVal >=1 || opacityVal<=0) {
if (type=='show') alpha += 0.1;
else alpha -= 0.1;
clear();
if (alpha >=1 || alpha<=0) {
delete core.animateFrame.asyncId[animate];
clearInterval(animate);
core.clearMap('route');
core.setOpacity('route', 1);
// core.status.replay.animate=false;
core.setAlpha('route', 1);
if (type == 'show') {
loc.forEach(function (t) {
core.showBlock(t[0],t[1],data.floorId);
});
}
else {
loc.forEach(function (t) {
core.removeBlock(t[0],t[1],data.floorId);
});
}
if (core.isset(callback)) callback();
}
else {
core.setAlpha('route', alpha);
draw();
}
}, time / 10 / core.status.replay.speed);
core.animateFrame.asyncId[animate] = true;
}
////// 将某个块从禁用变成启用状态 //////
maps.prototype.showBlock = function(x, y, floodId) {
floodId = floodId || core.status.floorId;
var block = core.getBlock(x,y,floodId,true);
maps.prototype.showBlock = function(x, y, floorId) {
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) return;
var block = core.getBlock(x,y,floorId,true);
if (block==null) return; // 不存在
block=block.block;
// 本身是禁用事件,启用之
if (block.disable) {
block.disable = false;
// 在本层,添加动画
if (floodId == core.status.floorId && core.isset(block.event)) {
if (floorId == core.status.floorId && core.isset(block.event)) {
core.drawBlock(block);
core.addGlobalAnimate(block);
core.syncGlobalAnimate();
@ -1085,6 +1143,7 @@ maps.prototype.showBlock = function(x, y, floodId) {
////// 只隐藏但不删除某块 //////
maps.prototype.hideBlock = function (x, y, floorId) {
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) return;
var block = core.getBlock(x,y,floorId,true);
if (block==null) return; // 不存在
@ -1106,6 +1165,7 @@ maps.prototype.hideBlock = function (x, y, floorId) {
////// 将某个块从启用变成禁用状态 //////
maps.prototype.removeBlock = function (x, y, floorId) {
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) return;
var block = core.getBlock(x,y,floorId,true);
if (block==null) return; // 不存在
@ -1129,6 +1189,8 @@ maps.prototype.removeBlock = function (x, y, floorId) {
////// 根据block的索引删除该块 //////
maps.prototype.removeBlockById = function (index, floorId) {
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) return;
var blocks = core.status.maps[floorId].blocks, block = blocks[index];
var x=block.x, y=block.y;
@ -1154,6 +1216,8 @@ maps.prototype.removeBlockById = function (index, floorId) {
////// 一次性删除多个block //////
maps.prototype.removeBlockByIds = function (floorId, ids) {
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) return;
ids.sort(function (a,b) {return b-a}).forEach(function (id) {
core.removeBlockById(id, floorId);
});
@ -1162,6 +1226,7 @@ maps.prototype.removeBlockByIds = function (floorId, ids) {
////// 改变图块 //////
maps.prototype.setBlock = function (number, x, y, floorId) {
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) return;
if (!core.isset(number) || !core.isset(x) || !core.isset(y)) return;
if (x<0 || x>=core.bigmap.width || y<0 || y>=core.bigmap.height) return;
@ -1187,6 +1252,7 @@ maps.prototype.setBlock = function (number, x, y, floorId) {
////// 改变图层块 //////
maps.prototype.setBgFgBlock = function (name, number, x, y, floorId) {
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) return;
if (!core.isset(number) || !core.isset(x) || !core.isset(y)) return;
if (x<0 || x>=core.bigmap.width || y<0 || y>=core.bigmap.height) return;
if (name!='bg' && name!='fg') return;
@ -1207,24 +1273,23 @@ maps.prototype.addGlobalAnimate = function (b) {
block.status = 0;
core.status.globalAnimateObjs.push(block);
}
////// 删除一个或所有全局动画 //////
maps.prototype.removeGlobalAnimate = function (x, y, all) {
maps.prototype.removeGlobalAnimate = function (x, y, all, name) {
if (main.mode=='editor' && main.editor.disableGlobalAnimate) return;
if (all) {
core.status.globalAnimateObjs = [];
core.status.autotileAnimateObjs = {};
core.status.autotileAnimateObjs = {"status": 0, "blocks": [], "map": null, "bgmap": null, "fgmap": null};
return;
}
core.status.globalAnimateObjs = core.status.globalAnimateObjs.filter(function (block) {return block.x!=x || block.y!=y;});
core.status.globalAnimateObjs = core.status.globalAnimateObjs.filter(function (block) {return block.x!=x || block.y!=y || block.name!=name;});
// 检查Autotile
if (core.isset(core.status.autotileAnimateObjs.blocks)) {
core.status.autotileAnimateObjs.blocks = core.status.autotileAnimateObjs.blocks.filter(function (block) {return block.x!=x || block.y!=y;});
core.status.autotileAnimateObjs.blocks = core.status.autotileAnimateObjs.blocks.filter(function (block) {return block.x!=x || block.y!=y || block.name!=name;});
core.status.autotileAnimateObjs.map[y][x] = 0;
}
@ -1286,6 +1351,7 @@ maps.prototype.drawAnimateFrame = function (animate, centerX, centerY, index) {
core.canvas.animate.drawImage(image, -realWidth/2 - core.bigmap.offsetX, -realHeight/2 - core.bigmap.offsetY, realWidth, realHeight);
core.loadCanvas('animate');
}
core.setAlpha('animate', 1);
})
}
@ -1338,7 +1404,8 @@ maps.prototype.setFloorImage = function (type, loc, floorId, callback) {
if (type!='show') type='hide';
if (typeof loc[0] == 'number' && typeof loc[1] == 'number')
loc = [loc];
floorId = floorId||core.status.floorId;
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) return;
if (loc.length==0) return;
loc.forEach(function (t) {
@ -1360,7 +1427,8 @@ maps.prototype.setBgFgMap = function (type, name, loc, floorId, callback) {
if (name!='fg') name='bg';
if (typeof loc[0] == 'number' && typeof loc[1] == 'number')
loc = [loc];
floorId = floorId||core.status.floorId;
floorId = floorId || core.status.floorId;
if (!core.isset(floorId)) return;
if (loc.length==0) return;
loc.forEach(function (t) {
@ -1379,7 +1447,8 @@ maps.prototype.setBgFgMap = function (type, name, loc, floorId, callback) {
}
maps.prototype.resetMap = function(floorId) {
var floorId = floorId||core.status.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 () {

View File

@ -144,7 +144,7 @@ ui.prototype.setAlpha = function (map, alpha) {
else core.canvas[map].globalAlpha = alpha;
}
////// 设置某个canvas的透明度 //////
////// 设置某个canvas的透明度尽量不要使用本函数而是全部换成setAlpha实现 //////
ui.prototype.setOpacity = function (map, opacity) {
if (map == 'all') {
for (var m in core.canvas) {
@ -186,10 +186,9 @@ ui.prototype.closePanel = function () {
////// 左上角绘制一段提示 //////
ui.prototype.drawTip = function (text, itemIcon) {
var textX, textY, width, height, hide = false, opacityVal = 0;
var textX, textY, width, height, hide = false, alpha = 0;
clearInterval(core.interval.tipAnimate);
core.setFont('data', "16px Arial");
core.setOpacity('data', 0);
core.canvas.data.textAlign = 'left';
if (!core.isset(itemIcon)) {
textX = 16;
@ -205,22 +204,22 @@ ui.prototype.drawTip = function (text, itemIcon) {
}
core.interval.tipAnimate = window.setInterval(function () {
if (hide) {
opacityVal -= 0.1;
alpha -= 0.1;
}
else {
opacityVal += 0.1;
alpha += 0.1;
}
core.setOpacity('data', opacityVal);
core.clearMap('data', 5, 5, 400, height);
core.clearMap('data', 5, 5, 416, height);
core.setAlpha('data', alpha);
core.fillRect('data', 5, 5, width, height, '#000');
if (core.isset(itemIcon)) {
core.canvas.data.drawImage(core.material.images.items, 0, itemIcon * 32, 32, 32, 10, 8, 32, 32);
}
core.fillText('data', text, textX + 5, textY + 15, '#fff');
if (opacityVal > 0.6 || opacityVal < 0) {
core.setAlpha('data', 1);
if (alpha > 0.6 || alpha < 0) {
if (hide) {
core.clearMap('data', 5, 5, 400, height);
core.setOpacity('data', 1);
core.clearMap('data', 5, 5, 416, height);
clearInterval(core.interval.tipAnimate);
return;
}
@ -231,8 +230,7 @@ ui.prototype.drawTip = function (text, itemIcon) {
core.timeout.getItemTipTimeout = null;
}, 750);
}
opacityVal = 0.6;
core.setOpacity('data', opacityVal);
alpha = 0.6;
}
}
}, 30);
@ -500,6 +498,20 @@ ui.prototype.drawTextBox = function(content, showAll) {
core.status.boxAnimateObjs = [];
core.clearMap('ui');
// drawImage
content = content.replace(/(\f|\\f)\[(.*?)]/g, function (text, sympol, str) {
var ss = str.split(",");
if (ss.length!=3 && ss.length!=5) return "";
var img = core.material.images.images[ss[0]];
if (!core.isset(img)) return "";
// 绘制
if (ss.length==3)
core.canvas.ui.drawImage(img, parseFloat(ss[1]), parseFloat(ss[2]));
else
core.canvas.ui.drawImage(img, 0, 0, img.width, img.height, parseFloat(ss[1]), parseFloat(ss[2]), parseFloat(ss[3]), parseFloat(ss[4]));
return "";
});
var globalFont = core.status.globalAttribute.font;
var font = textfont + 'px '+globalFont;
if (textAttribute.bold) font = "bold "+font;
@ -519,9 +531,13 @@ ui.prototype.drawTextBox = function(content, showAll) {
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;
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;
@ -541,20 +557,24 @@ ui.prototype.drawTextBox = function(content, showAll) {
else if (position=='up') {
if (px==null || py==null)
top = 5 + offset;
else
else {
top = 32 * py - height - ydelta - yoffset;
top -= core.bigmap.offsetY;
}
}
else if (position=='down') {
if (px==null || py==null)
top = 416 - height - 5 - offset;
else
else {
top = 32 * py + 32 + yoffset;
top -= core.bigmap.offsetY;
}
}
var bottom = top + height;
if (isWindowSkin) {
core.setAlpha('ui', alpha);
this.drawWindowSkin(background,'ui',left,top,width,height,position,px==null?null:px*32,py==null?null:py*32);
this.drawWindowSkin(background,'ui',left,top,width,height,position,px==null?null:px*32-core.bigmap.offsetX,py==null?null:py*32-core.bigmap.offsetY);
core.setAlpha('ui', 1);
}
else {
@ -569,17 +589,17 @@ ui.prototype.drawTextBox = function(content, showAll) {
canvas.moveTo(left,top);
// 上边缘
if (position=='down' && core.isset(px) && core.isset(py)) {
canvas.lineTo(32*px+xoffset, top);
canvas.lineTo(32*px+16, top-yoffset);
canvas.lineTo(32*(px+1)-xoffset, top);
canvas.lineTo(32*px+xoffset - core.bigmap.offsetX, top);
canvas.lineTo(32*px+16 - core.bigmap.offsetX, top-yoffset);
canvas.lineTo(32*(px+1)-xoffset - core.bigmap.offsetX, top);
}
canvas.lineTo(right, top);
canvas.lineTo(right, bottom);
// 下边缘
if (position=='up' && core.isset(px) && core.isset(py)) {
canvas.lineTo(32*(px+1)-xoffset, bottom);
canvas.lineTo(32*px+16, bottom+yoffset);
canvas.lineTo(32*px+xoffset, bottom);
canvas.lineTo(32*(px+1)-xoffset - core.bigmap.offsetX, bottom);
canvas.lineTo(32*px+16 - core.bigmap.offsetX, bottom+yoffset);
canvas.lineTo(32*px+xoffset - core.bigmap.offsetX, bottom);
}
canvas.lineTo(left, bottom);
canvas.closePath();
@ -911,7 +931,7 @@ ui.prototype.drawSettings = function () {
core.status.event.id = 'settings';
this.drawChoices(null, [
"系统设置", "虚拟键盘", "浏览地图", "绘图模式", "同步存档", "数据统计", "查看评论", "操作帮助", "关于本塔", "返回标题", "返回游戏"
"系统设置", "虚拟键盘", "浏览地图", "绘图模式", "同步存档", "游戏信息", "返回标题", "返回游戏"
]);
}
@ -1010,16 +1030,13 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) {
var top = (416-height)/2, bottom = height;
// var left = 97, top = 64, right = 416 - 2 * left, bottom = 416 - 2 * top;
core.setAlpha('ui', 0.85);
core.fillRect('ui', left, top, right, bottom, '#000000');
core.fillRect('ui', left, top, right, bottom, 'rgba(0,0,0,0.85)');
core.setAlpha('ui', 1);
core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2);
core.clearMap('data');
clearInterval(core.interval.tipAnimate);
core.setAlpha('data', 1);
core.setOpacity('data', 1);
core.status.boxAnimateObjs = [];
var globalFont = core.status.globalAttribute.font;
@ -1307,6 +1324,13 @@ ui.prototype.drawReplay = function () {
]);
}
ui.prototype.drawGameInfo = function () {
core.status.event.id = 'gameInfo';
this.drawChoices(null, [
"数据统计", "查看评论", "操作帮助", "关于本塔", "返回上级菜单"
]);
}
////// 绘制分页 //////
ui.prototype.drawPagination = function (page, totalPage, top) {
// if (totalPage<page) totalPage=page;
@ -1359,7 +1383,6 @@ ui.prototype.drawBook = function (index) {
clearInterval(core.interval.tipAnimate);
core.clearMap('data');
core.setOpacity('data', 1);
core.clearMap('ui');
core.setAlpha('ui', 1);
@ -1595,7 +1618,6 @@ ui.prototype.drawBookDetail = function (index) {
clearInterval(core.interval.tipAnimate);
core.clearMap('data');
core.setOpacity('data', 1);
var left=10, right=416-2*left;
var content_left = left + 25;
@ -1681,8 +1703,7 @@ ui.prototype.drawMaps = function (index, x, y) {
core.setAlpha('ui', 1);
core.clearMap('animate');
core.setOpacity('animate', 0.4);
core.fillRect('animate', 0, 0, 416, 416, '#000000');
core.fillRect('animate', 0, 0, 416, 416, 'rgba(0,0,0,0.4)');
core.strokeRect('ui', 66, 2, 284, 60, "#FFD700", 4);
core.strokeRect('ui', 2, 66, 60, 284);
@ -1723,7 +1744,6 @@ ui.prototype.drawMaps = function (index, x, y) {
}
core.clearMap('animate');
core.setOpacity('animate', 1);
var damage = (core.status.event.data||{}).damage, paint = (core.status.event.data||{}).paint;
var all = (core.status.event.data||{}).all;
@ -1764,17 +1784,14 @@ ui.prototype.drawMaps = function (index, x, y) {
}
core.clearMap('data');
core.setOpacity('data', 0.2);
core.canvas.data.textAlign = 'left';
core.setFont('data', '16px Arial');
var text = core.status.maps[floorId].title;
if (!all && (mw>13 || mh>13)) text+=" ["+(x-6)+","+(y-6)+"]";
var textX = 16, textY = 18, width = textX + core.canvas.data.measureText(text).width + 16, height = 42;
core.fillRect('data', 5, 5, width, height, '#000');
core.setOpacity('data', 0.4);
core.fillText('data', text, textX + 5, textY + 15, '#fff');
core.fillRect('data', 5, 5, width, height, 'rgba(0,0,0,0.4)');
core.fillText('data', text, textX + 5, textY + 15, 'rgba(255,255,255,0.6)');
}
////// 绘制道具栏 //////
@ -2574,7 +2591,6 @@ ui.prototype.drawPaint = function () {
core.clearMap('route');
core.setAlpha('route', 1);
core.setOpacity('route', 1);
// 将已有的内容绘制到route上
var value = core.paint[core.status.floorId];

118
main.js
View File

@ -98,7 +98,14 @@ function main() {
'shop': document.getElementById("img-shop"),
'save': document.getElementById("img-save"),
'load': document.getElementById("img-load"),
'settings': document.getElementById("img-settings")
'settings': document.getElementById("img-settings"),
'btn1': document.getElementById("img-btn1"),
'btn2': document.getElementById("img-btn2"),
'btn3': document.getElementById("img-btn3"),
'btn4': document.getElementById("img-btn4"),
'btn5': document.getElementById("img-btn5"),
'btn6': document.getElementById("img-btn6"),
'btn7': document.getElementById("img-btn7")
},
'icons': {
'floor': 0,
@ -132,6 +139,13 @@ function main() {
'erase': 27,
'empty': 28,
'exit': 29,
'btn1': 30,
'btn2': 31,
'btn3': 32,
'btn4': 33,
'btn5': 34,
'btn6': 35,
'btn7': 36
},
'floor': document.getElementById('floor'),
'name': document.getElementById('name'),
@ -386,7 +400,9 @@ main.dom.data.ontouchend = function (e) {
}
////// 点击状态栏中的怪物手册时 //////
main.statusBar.image.book.onclick = function () {
main.statusBar.image.book.onclick = function (e) {
e.stopPropagation();
if (core.isset(core.status.replay) && core.status.replay.replaying) {
core.triggerReplay();
return;
@ -402,7 +418,8 @@ main.statusBar.image.book.onclick = function () {
}
////// 点击状态栏中的楼层传送器/装备栏时 //////
main.statusBar.image.fly.onclick = function () {
main.statusBar.image.fly.onclick = function (e) {
e.stopPropagation();
// 播放录像时
if (core.isset(core.status.replay) && core.status.replay.replaying) {
@ -427,7 +444,8 @@ main.statusBar.image.fly.onclick = function () {
}
////// 点击状态栏中的工具箱时 //////
main.statusBar.image.toolbox.onclick = function () {
main.statusBar.image.toolbox.onclick = function (e) {
e.stopPropagation();
if (core.isset(core.status.replay) && core.status.replay.replaying) {
core.rewindReplay();
@ -445,7 +463,8 @@ main.statusBar.image.toolbox.onclick = function () {
}
////// 双击状态栏中的工具箱时 //////
main.statusBar.image.toolbox.ondblclick = function () {
main.statusBar.image.toolbox.ondblclick = function (e) {
e.stopPropagation();
if (core.isset(core.status.replay) && core.status.replay.replaying) {
core.rewindReplay();
@ -458,7 +477,8 @@ main.statusBar.image.toolbox.ondblclick = function () {
}
////// 点击状态栏中的快捷商店时 //////
main.statusBar.image.shop.onclick = function () {
main.statusBar.image.shop.onclick = function (e) {
e.stopPropagation();
if (core.isset(core.status.replay) && core.status.replay.replaying) {
core.bookReplay();
@ -470,7 +490,8 @@ main.statusBar.image.shop.onclick = function () {
}
////// 点击状态栏中的存档按钮时 //////
main.statusBar.image.save.onclick = function () {
main.statusBar.image.save.onclick = function (e) {
e.stopPropagation();
if (core.isset(core.status.replay) && core.status.replay.replaying) {
core.speedDownReplay();
@ -487,7 +508,8 @@ main.statusBar.image.save.onclick = function () {
}
////// 点击状态栏中的读档按钮时 //////
main.statusBar.image.load.onclick = function () {
main.statusBar.image.load.onclick = function (e) {
e.stopPropagation();
if (core.isset(core.status.replay) && core.status.replay.replaying) {
core.speedUpReplay();
@ -504,7 +526,8 @@ main.statusBar.image.load.onclick = function () {
}
////// 点击状态栏中的系统菜单时 //////
main.statusBar.image.settings.onclick = function () {
main.statusBar.image.settings.onclick = function (e) {
e.stopPropagation();
if (core.isset(core.status.replay) && core.status.replay.replaying) {
core.saveReplay();
@ -520,18 +543,53 @@ main.statusBar.image.settings.onclick = function () {
main.core.openSettings(true);
}
////// 点击工具栏时 //////
main.dom.toolBar.onclick = function () {
if (core.isset(core.status.replay) && core.status.replay.replaying)
return;
main.core.control.setToolbarButton(!core.domStyle.toolbarBtn);
}
////// 手机端的按钮1-7 //////
main.statusBar.image.btn1.onclick = function (e) {
e.stopPropagation();
main.core.onkeyUp({"keyCode": 49});
};
main.statusBar.image.btn2.onclick = function (e) {
e.stopPropagation();
main.core.onkeyUp({"keyCode": 50});
};
main.statusBar.image.btn3.onclick = function (e) {
e.stopPropagation();
main.core.onkeyUp({"keyCode": 51});
};
main.statusBar.image.btn4.onclick = function (e) {
e.stopPropagation();
main.core.onkeyUp({"keyCode": 52});
};
main.statusBar.image.btn5.onclick = function (e) {
e.stopPropagation();
main.core.onkeyUp({"keyCode": 53});
};
main.statusBar.image.btn6.onclick = function (e) {
e.stopPropagation();
main.core.onkeyUp({"keyCode": 54});
};
main.statusBar.image.btn7.onclick = function (e) {
e.stopPropagation();
main.core.onkeyUp({"keyCode": 55});
};
////// 点击“开始游戏”时 //////
main.dom.playGame.onclick = function () {
main.dom.startButtons.style.display='none';
if (main.core.isset(main.core.musicStatus) && main.core.musicStatus.startDirectly
&& main.core.musicStatus.bgmStatus) {
if (main.core.musicStatus.playingBgm==null
|| core.material.bgms[main.core.musicStatus.playingBgm].paused) {
main.core.musicStatus.playingBgm=null;
main.core.playBgm(main.core.bgms[0]);
}
}
main.core.control.checkBgm();
if (main.core.isset(main.core.flags.startDirectly) && main.core.flags.startDirectly) {
core.events.startGame("");
@ -543,32 +601,14 @@ main.dom.playGame.onclick = function () {
////// 点击“载入游戏”时 //////
main.dom.loadGame.onclick = function() {
if (main.core.isset(main.core.musicStatus) && main.core.musicStatus.startDirectly
&& main.core.musicStatus.bgmStatus) {
if (main.core.musicStatus.playingBgm==null
|| core.material.bgms[main.core.musicStatus.playingBgm].paused) {
main.core.musicStatus.playingBgm=null;
main.core.playBgm(main.core.bgms[0]);
}
}
main.core.control.checkBgm();
main.core.load();
}
////// 点击“录像回放”时 //////
main.dom.replayGame.onclick = function () {
if (main.core.isset(main.core.musicStatus) && main.core.musicStatus.startDirectly
&& main.core.musicStatus.bgmStatus) {
if (main.core.musicStatus.playingBgm==null
|| core.material.bgms[main.core.musicStatus.playingBgm].paused) {
main.core.musicStatus.playingBgm=null;
main.core.playBgm(main.core.bgms[0]);
}
}
core.chooseReplayFile();
main.core.control.checkBgm();
main.core.chooseReplayFile();
}

View File

@ -1,4 +1,4 @@
var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
{
"main": {
"floorIds": [
@ -103,6 +103,126 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"flags": {},
"steps": 0
},
"startCanvas": [
{
"type": "comment",
"text": "在这里可以用事件来自定义绘制标题界面的背景图等"
},
{
"type": "showImage",
"name": "bg.jpg",
"loc": [
0,
0
]
},
{
"type": "comment",
"text": "给用户提供选择项这里简单的使用了choices事件"
},
{
"type": "comment",
"text": "也可以贴按钮图然后使用循环处理+等待操作来完成"
},
{
"type": "choices",
"choices": [
{
"text": "开始游戏",
"action": [
{
"type": "comment",
"text": "检查bgm状态下同"
},
{
"type": "function",
"function": "function(){\ncore.control.checkBgm()\n}"
},
{
"type": "if",
"condition": "core.flags.startDirectly",
"true": [
{
"type": "comment",
"text": "直接开始游戏,设置初始化数据"
},
{
"type": "function",
"function": "function(){\ncore.events.setInitData('')\n}"
}
],
"false": [
{
"type": "comment",
"text": "动态生成难度选择项"
},
{
"type": "function",
"function": "function(){\nvar choices = [];\nmain.levelChoose.forEach(function (one) {\n\tchoices.push({\"text\": one[0], \"action\": [\n\t\t{\"type\": \"function\", \"function\": \"function() { core.status.hard = '\"+one[1]+\"'; core.events.setInitData('\"+one[1]+\"'); }\"}\n\t]});\n})\ncore.insertAction({\"type\": \"choices\", \"choices\": choices});\n}"
}
]
},
{
"type": "showImage"
},
{
"type": "comment",
"text": "成功选择难度"
}
]
},
{
"text": "读取存档",
"action": [
{
"type": "function",
"function": "function(){\ncore.control.checkBgm()\n}"
},
{
"type": "showImage"
},
{
"type": "comment",
"text": "这段代码会结束事件,打开读档页面,读取存档或重新开始"
},
{
"type": "function",
"function": "function(){\ncore.insertAction([{\"type\": \"exit\"}], null, null, function() {\n\tcore.status.played = false;\n\tcore.load();\n})\n}"
},
{
"type": "comment",
"text": "不管读档有没有成功,都会重新开始,这个地方不会被执行到"
}
]
},
{
"text": "回放录像",
"action": [
{
"type": "function",
"function": "function(){\ncore.control.checkBgm()\n}"
},
{
"type": "comment",
"text": "这段代码会结束事件,选择录像文件,播放录像或重新开始"
},
{
"type": "function",
"function": "function(){\ncore.insertAction([{\"type\": \"exit\"}], null, null, function() {\n\tcore.restart();\n\tcore.chooseReplayFile();\n})\n}"
},
{
"type": "comment",
"text": "不管录像有没有成功,都会重新开始,这个地方不会被执行到"
}
]
}
]
},
{
"type": "comment",
"text": "接下来会执行startText中的事件"
}
],
"startText": [
"Hi欢迎来到 HTML5 魔塔样板!\n\n本样板由艾之葵制作可以让你在不会写任何代码\n的情况下也能做出属于自己的H5魔塔",
"这里游戏开始时的剧情。\n定义在data.js的startText处。\n\n你可以在这里写上自己的内容。",
@ -217,7 +337,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"counterAttack": 0.1,
"purify": 3,
"hatred": 2,
"maxValidHp": null,
"moveSpeed": 100,
"animateSpeed": 300
},
"flags": {
@ -248,6 +368,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"hatredDecrease": true,
"betweenAttackCeil": false,
"useLoop": false,
"startUsingCanvas": false,
"startDirectly": false,
"canOpenBattleAnimate": true,
"showBattleAnimateConfirm": false,

View File

@ -1,4 +1,4 @@
var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
{
"events": {
"initGame": function() {
@ -59,7 +59,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
core.stopReplay();
core.waitHeroToStop(function() {
core.removeGlobalAnimate(0,0,true);
core.clearMap('all'); // 清空全地图
core.clearMap('all'); core.clearMap('curtain'); // 清空全地图
// 请注意:
// 成绩统计时是按照hp进行上传并排名因此光在这里改${status:hp}是无效的
// 如需按照其他的的分数统计方式请先将hp设置为你的得分
@ -93,6 +93,10 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
visited.push(floorId);
core.setFlag("__visited__", visited);
}
// 每次抵达楼层时执行的事件
if (!fromLoad) {
core.insertAction(core.floors[floorId].eachArrive);
}
},
"addPoint": function (enemy) {
// 加点事件

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.