Merge pull request #59 from zhaouv/dev-2.0-functions-20180227
Dev 2 0 functions 20180227
This commit is contained in:
commit
7148bc11e5
@ -53,10 +53,12 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
|
||||
* [x] 同一个点的多事件处理(做法详见文档)。
|
||||
* [x] 增加新地图后可以接档而不用重新开始。
|
||||
* [x] 增加可以接收用户输入的事件(type:input)。
|
||||
* [x] 滚动字幕;自动剧情文本。
|
||||
* [x] 可以同时show/hide多个事件。
|
||||
* [x] 现在可以支持滑冰和推箱子事件了。
|
||||
* [x] 地图中每个块的可通行方向控制(悬崖效果)。
|
||||
* [x] 动画支持带旋转和翻转的帧。
|
||||
* [x] 长按屏幕可跳过对话。
|
||||
* [x] 现在可以允许用户丢弃道具了(例如不会再使用的装备)。
|
||||
* [x] 修复行走时按键会发生动画抖动问题。
|
||||
* [x] 修复无法打开战斗动画的Bug。
|
||||
|
||||
@ -155,6 +155,7 @@ return code;
|
||||
action
|
||||
: text_0_s
|
||||
| text_1_s
|
||||
| autoText_s
|
||||
| setText_s
|
||||
| tip_s
|
||||
| setValue_s
|
||||
@ -201,7 +202,7 @@ text_0_s
|
||||
/* text_0_s
|
||||
tooltip : text:显示一段文字(剧情)
|
||||
helpUrl : https://ckcz123.github.io/mota-js/#/event?id=text%ef%bc%9a%e6%98%be%e7%a4%ba%e4%b8%80%e6%ae%b5%e6%96%87%e5%ad%97%ef%bc%88%e5%89%a7%e6%83%85%ef%bc%89
|
||||
default : ["欢迎使用事件编辑器"]
|
||||
default : ["欢迎使用事件编辑器(双击方块进入多行编辑)"]
|
||||
var code = '"'+EvalString_0+'",\n';
|
||||
return code;
|
||||
*/
|
||||
@ -213,7 +214,7 @@ text_1_s
|
||||
/* text_1_s
|
||||
tooltip : text:显示一段文字(剧情),选项较多请右键点击帮助
|
||||
helpUrl : https://ckcz123.github.io/mota-js/#/event?id=text%ef%bc%9a%e6%98%be%e7%a4%ba%e4%b8%80%e6%ae%b5%e6%96%87%e5%ad%97%ef%bc%88%e5%89%a7%e6%83%85%ef%bc%89
|
||||
default : ["小妖精","fairy","","欢迎使用事件编辑器"]
|
||||
default : ["小妖精","fairy","","欢迎使用事件编辑器(双击方块进入多行编辑)"]
|
||||
var title='';
|
||||
if (EvalString_0==''){
|
||||
if (IdString_0=='')title='';
|
||||
@ -230,14 +231,38 @@ var code = '"'+title+EvalString_1+EvalString_2+'",\n';
|
||||
return code;
|
||||
*/
|
||||
|
||||
autoText_s
|
||||
: '自动剧情文本: 标题' EvalString? '图像' IdString? '对话框效果' EvalString? '时间' Int BGNL? EvalString Newline
|
||||
;
|
||||
|
||||
/* autoText_s
|
||||
tooltip : autoText:自动剧情文本,用户无法跳过自动剧情文本,大段剧情文本请添加“是否跳过剧情”的提示
|
||||
helpUrl : https://ckcz123.github.io/mota-js/#/event?id=autotext%ef%bc%9a%e8%87%aa%e5%8a%a8%e5%89%a7%e6%83%85%e6%96%87%e6%9c%ac
|
||||
default : ["小妖精","fairy","",3000,"双击方块进入多行编辑\\n自动剧情文本\\n自动剧情文本\\n自动剧情文本"]
|
||||
var title='';
|
||||
if (EvalString_0==''){
|
||||
if (IdString_0=='')title='';
|
||||
else title='\\t['+IdString_0+']';
|
||||
} else {
|
||||
if (IdString_0=='')title='\\t['+EvalString_0+']';
|
||||
else title='\\t['+EvalString_0+','+IdString_0+']';
|
||||
}
|
||||
if(EvalString_1 && !(/^(up|down)(,hero)?(,([+-]?\d+),([+-]?\d+))?$/.test(EvalString_1))) {
|
||||
throw new Error('对话框效果的用法请右键点击帮助');
|
||||
}
|
||||
EvalString_1 = EvalString_1 && ('\\b['+EvalString_1+']');
|
||||
var code = '{"type": "autoText", "text": "'+title+EvalString_1+EvalString_2+'", "time" :'+Int_0+'},\n';
|
||||
return code;
|
||||
*/
|
||||
|
||||
setText_s
|
||||
: '设置剧情文本的属性' '位置' SetTextPosition_List BGNL? '标题颜色' EvalString? '正文颜色' EvalString? '背景色' EvalString? '粗体' B_List Newline
|
||||
: '设置剧情文本的属性' '位置' SetTextPosition_List BGNL? '标题颜色' EvalString? '正文颜色' EvalString? '背景色' EvalString? BGNL? '粗体' B_List '打字间隔' EvalString? Newline
|
||||
;
|
||||
|
||||
/* setText_s
|
||||
tooltip : setText:设置剧情文本的属性,颜色为RGB三元组或RGBA四元组
|
||||
tooltip : setText:设置剧情文本的属性,颜色为RGB三元组或RGBA四元组,打字间隔为剧情文字添加的时间间隔,为整数或不填
|
||||
helpUrl : https://ckcz123.github.io/mota-js/#/event?id=settext%ef%bc%9a%e8%ae%be%e7%bd%ae%e5%89%a7%e6%83%85%e6%96%87%e6%9c%ac%e7%9a%84%e5%b1%9e%e6%80%a7
|
||||
default : [[['不改变','null'],['上','up'],['中','center'],['下','down']],"255,215,0,1","255,255,255,1","0,0,0,0.85",[['不改变','null'],['设为粗体','true'],['取消粗体','false']]]
|
||||
default : [[['不改变','null'],['上','up'],['中','center'],['下','down']],"","","",[['不改变','null'],['设为粗体','true'],['取消粗体','false']],'']
|
||||
SetTextPosition_List_0 =SetTextPosition_List_0==='null'?'': ', "position": "'+SetTextPosition_List_0+'"';
|
||||
var colorRe = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/;
|
||||
if (EvalString_0) {
|
||||
@ -252,8 +277,12 @@ if (EvalString_2) {
|
||||
if (!colorRe.test(EvalString_2))throw new Error('颜色格式错误,形如:0~255,0~255,0~255,0~1');
|
||||
EvalString_2 = ', "background": ['+EvalString_2+']';
|
||||
}
|
||||
if (EvalString_3) {
|
||||
if (!/^\d+$/.test(EvalString_3))throw new Error('打字时间间隔必须是整数或不填');
|
||||
EvalString_3 = ', "time": '+EvalString_3;
|
||||
}
|
||||
B_List_0 = ', "bold": '+B_List_0;
|
||||
var code = '{"type": "setText"'+SetTextPosition_List_0+EvalString_0+EvalString_1+EvalString_2+B_List_0+'},\n';
|
||||
var code = '{"type": "setText"'+SetTextPosition_List_0+EvalString_0+EvalString_1+EvalString_2+B_List_0+EvalString_3+'},\n';
|
||||
return code;
|
||||
*/
|
||||
|
||||
@ -1117,7 +1146,7 @@ ActionParser.prototype.parseAction = function() {
|
||||
|
||||
// 如果是文字:显示
|
||||
if (typeof data == "string") {
|
||||
data={"type": "text", "data": data}
|
||||
data={"type": "text", "text": data}
|
||||
}
|
||||
this.event.data.type=data.type;
|
||||
switch (data.type) {
|
||||
@ -1127,7 +1156,12 @@ ActionParser.prototype.parseAction = function() {
|
||||
return;
|
||||
case "text": // 文字/对话
|
||||
this.next = MotaActionBlocks['text_0_s'].xmlText([
|
||||
this.EvalString(data.data),this.next]);
|
||||
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 "setText": // 设置剧情文本的属性
|
||||
var setTextfunc = function(a){return a?JSON.stringify(a).slice(1,-1):null;}
|
||||
@ -1135,7 +1169,7 @@ ActionParser.prototype.parseAction = function() {
|
||||
data.text=setTextfunc(data.text);
|
||||
data.background=setTextfunc(data.background);
|
||||
this.next = MotaActionBlocks['setText_s'].xmlText([
|
||||
data.position,data.title,data.text,data.background,data.bold,this.next]);
|
||||
data.position,data.title,data.text,data.background,data.bold,data.time,this.next]);
|
||||
break;
|
||||
case "tip":
|
||||
this.next = MotaActionBlocks['tip_s'].xmlText([
|
||||
|
||||
@ -53,6 +53,13 @@ initscript=String.raw`
|
||||
'<label text="显示文字"></label>',
|
||||
MotaActionBlocks['text_0_s'].xmlText(),
|
||||
MotaActionBlocks['text_1_s'].xmlText(),
|
||||
MotaActionFunctions.actionParser.parseList({"type": "choices", "text": "是否跳过剧情", "choices": [
|
||||
{"text": "是", "action": []},
|
||||
{"text": "否", "action": [
|
||||
{"type": "autoText", "text": "\\t[小妖精,fairy]双击方块进入多行编辑\\n用户无法跳过自动剧情文本,大段剧情文本请添加“是否跳过剧情”的提示\\n自动剧情文本\\n自动剧情文本\\n自动剧情文本", "time" :3000},
|
||||
{"type": "autoText", "text": "(可以右键方块后点复制)", "time" :3000},
|
||||
]},
|
||||
]}),
|
||||
MotaActionBlocks['setText_s'].xmlText(),
|
||||
MotaActionBlocks['showImage_0_s'].xmlText(),
|
||||
MotaActionBlocks['showImage_1_s'].xmlText(),
|
||||
@ -372,6 +379,7 @@ editor_blockly.doubleClickBlock = function (blockId){
|
||||
var textStringDict = {
|
||||
'text_0_s':'EvalString_0',
|
||||
'text_1_s':'EvalString_2',
|
||||
'autoText_s':'EvalString_2',
|
||||
'choices_s':'EvalString_0',
|
||||
'function_s':'RawEvalString_0',
|
||||
}
|
||||
|
||||
@ -150,14 +150,14 @@
|
||||
|
||||
### text:显示一段文字(剧情)
|
||||
|
||||
使用`{"type": "text"}`可以显示一段文字。后面`"data"`可以指定文字内容。
|
||||
使用`{"type": "text"}`可以显示一段文字。后面`"text"`可以指定文字内容。
|
||||
|
||||
``` js
|
||||
"events": { // 该楼的所有可能事件列表
|
||||
// 如果大括号里只有"data"项(没有"action"或"enable"),则可以省略到只剩下中括号
|
||||
"x,y": [ // 实际执行的事件列表
|
||||
{"type": "text", "data": "在界面上的一段文字"}, // 显示文字事件
|
||||
{"type": "text", "data": "这是第二段文字"}, // 显示第二个文字事件
|
||||
{"type": "text", "text": "在界面上的一段文字"}, // 显示文字事件
|
||||
{"type": "text", "text": "这是第二段文字"}, // 显示第二个文字事件
|
||||
// ...
|
||||
// 按顺序写事件,直到结束
|
||||
]
|
||||
@ -171,7 +171,7 @@
|
||||
// 如果大括号里只有"data"项(没有"action"或"enable"),则可以省略到只剩下中括号
|
||||
"x,y": [ // 实际执行的事件列表
|
||||
"在界面上的一段文字",// 直接简写,和下面写法完全等价
|
||||
{"type": "text", "data": "这是第二段文字"}, // 显示第二个文字事件
|
||||
{"type": "text", "text": "这是第二段文字"}, // 显示第二个文字事件
|
||||
// ...
|
||||
// 按顺序写事件,直到结束
|
||||
]
|
||||
@ -261,26 +261,49 @@
|
||||
|
||||

|
||||
|
||||
### autoText:自动剧情文本
|
||||
|
||||
使用`{"type": "autoText"}`可以使用剧情文本。
|
||||
|
||||
``` js
|
||||
"x,y": [ // 实际执行的事件列表
|
||||
{"type": "autoText", "text": "一段自动显示的剧情文字", "time": 5000}
|
||||
]
|
||||
```
|
||||
|
||||
text为文本正文内容,和上面的写法完全一致。
|
||||
|
||||
time为可选项,代表该自动文本的时间。可以不指定,不指定默认为3000毫秒。
|
||||
|
||||
用户无法跳过自动剧情文本,只能等待time时间结束后自动过。
|
||||
|
||||
回放录像时将忽略自动剧情文本的显示。
|
||||
|
||||
!> 由于用户无法跳过自动剧情文本,因此对于大段剧情文本请自行添加“是否跳过剧情”的提示,否则可能会非常不友好。
|
||||
|
||||
### setText:设置剧情文本的属性
|
||||
|
||||
使用`{"type": "setText"}`可以设置剧情文本的各项属性。
|
||||
|
||||
``` js
|
||||
"x,y": [ // 实际执行的事件列表
|
||||
{"type": "setText", "position": "up", "title": [255,0,0], "text": [255,255,0], "background": [0,0,255,0.3], "bold": true},
|
||||
"这段话将显示在上方,标题为红色,正文为黄色粗体,背景为透明度0.3的蓝色"
|
||||
{"type": "setText", "title": [255,0,0], "text": [255,255,0], "background": [0,0,255,0.3]},
|
||||
{"type": "setText", "position": "up", "bold": true, "time": 70},
|
||||
"这段话将显示在上方,标题为红色,正文为黄色粗体,背景为透明度0.3的蓝色,70毫秒速度打字机效果"
|
||||
]
|
||||
```
|
||||
|
||||
position为可选项,表示设置文字显示位置。只能为up(上),center(中)和down(下)三者。
|
||||
title为可选项,如果设置则为一个RGB三元组或RGBA四元组,表示标题(名字)颜色。 默认值:`[255,215,0,1]`
|
||||
|
||||
title为可选项,如果设置则为一个RGB三元组或RGBA四元组,表示标题(名字)颜色。
|
||||
text为可选项,如果设置则为一个RGB三元组或RGBA四元组,表示正文颜色。 默认值:`[255,255,255,1]`
|
||||
|
||||
text为可选项,如果设置则为一个RGB三元组或RGBA四元组,表示正文颜色。
|
||||
background为可选项,如果设置则为一个RGB三元组或RGBA四元组,表示背景色。 默认值:`[0,0,0,0.85]`
|
||||
|
||||
background为可选项,如果设置则为一个RGB三元组或RGBA四元组,表示背景色。
|
||||
position为可选项,表示设置文字显示位置。只能为up(上),center(中)和down(下)三者。 默认值: `center`
|
||||
|
||||
bold为可选项,如果设置则为true或false,表示正文是否使用粗体。
|
||||
bold为可选项,如果设置则为true或false,表示正文是否使用粗体。 默认值:`false`
|
||||
|
||||
time为可选项,表示文字添加的速度。若此项设置为0将直接全部显示,若大于0则会设置为相邻字符依次显示的时间间隔。 默认值:`0`
|
||||
|
||||
### tip:显示一段提示文字
|
||||
|
||||
|
||||
@ -6,7 +6,9 @@
|
||||
<link rel="shortcut icon" type="image/png" href="./img/logo.png">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="description" content="Description">
|
||||
<meta http-equiv="pragma" content="no-cache">
|
||||
<meta http-equiv="cache-control" content="no-cache">
|
||||
<meta http-equiv="expires" content="0">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<link href="https://cdn.bootcss.com/docsify/4.5.5/themes/vue.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
11
editor.html
11
editor.html
@ -192,20 +192,15 @@
|
||||
</div>
|
||||
<p id='startTopLoadTips'>资源即将开始加载</p>
|
||||
</div>
|
||||
<img id='startBackground' src='project/images/bg.png'>
|
||||
<!-- 标题界面;可以改style的color使标题改变颜色 -->
|
||||
<p id='startLogo' style="color: black"></p>
|
||||
<img id='startBackground'>
|
||||
<p id='startLogo'></p>
|
||||
<div id='startButtonGroup'>
|
||||
<div id='startButtons'>
|
||||
<span class='startButton' id='playGame'>开始游戏</span>
|
||||
<span class='startButton' id='loadGame'>载入游戏</span>
|
||||
<span class='startButton' id='replayGame'>录像回放</span>
|
||||
</div>
|
||||
<div id='levelChooseButtons'>
|
||||
<span class='startButton' id='easyLevel'>简单</span>
|
||||
<span class='startButton' id='normalLevel'>普通</span>
|
||||
<span class='startButton' id='hardLevel'>困难</span>
|
||||
</div>
|
||||
<div id='levelChooseButtons'></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id='floorMsgGroup'>
|
||||
|
||||
11
index.html
11
index.html
@ -25,20 +25,15 @@
|
||||
</div>
|
||||
<p id='startTopLoadTips'>资源即将开始加载</p>
|
||||
</div>
|
||||
<img id='startBackground' src='project/images/bg.png'>
|
||||
<!-- 标题界面;可以改style的color使标题改变颜色 -->
|
||||
<p id='startLogo' style="color: black"></p>
|
||||
<img id='startBackground'>
|
||||
<p id='startLogo'></p>
|
||||
<div id='startButtonGroup'>
|
||||
<div id='startButtons'>
|
||||
<span class='startButton' id='playGame'>开始游戏</span>
|
||||
<span class='startButton' id='loadGame'>载入游戏</span>
|
||||
<span class='startButton' id='replayGame'>录像回放</span>
|
||||
</div>
|
||||
<div id='levelChooseButtons'>
|
||||
<span class='startButton' id='easyLevel'>简单</span>
|
||||
<span class='startButton' id='normalLevel'>普通</span>
|
||||
<span class='startButton' id='hardLevel'>困难</span>
|
||||
</div>
|
||||
<div id='levelChooseButtons'></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id='floorMsgGroup'>
|
||||
|
||||
32
libs/core.js
32
libs/core.js
@ -17,12 +17,14 @@ function core() {
|
||||
this.timeout = {
|
||||
'getItemTipTimeout': null,
|
||||
'turnHeroTimeout': null,
|
||||
'onDownTimeout': null,
|
||||
}
|
||||
this.interval = {
|
||||
'heroMoveInterval': null,
|
||||
"tipAnimate": null,
|
||||
'openDoorAnimate': null,
|
||||
'animateInterval': null,
|
||||
'onDownInterval': null,
|
||||
}
|
||||
this.animateFrame = {
|
||||
'background': null,
|
||||
@ -124,6 +126,7 @@ function core() {
|
||||
'data': null,
|
||||
'selection': null,
|
||||
'ui': null,
|
||||
'interval': null,
|
||||
},
|
||||
'textAttribute': {
|
||||
'position': "center",
|
||||
@ -131,6 +134,7 @@ function core() {
|
||||
"background": [0,0,0,0.85],
|
||||
"text": [255,255,255,1],
|
||||
"bold": false,
|
||||
"time": 0,
|
||||
},
|
||||
'curtainColor': null,
|
||||
'usingCenterFly':false,
|
||||
@ -775,8 +779,13 @@ core.prototype.clearStatus = function() {
|
||||
core.prototype.resetStatus = function(hero, hard, floorId, route, maps) {
|
||||
|
||||
// 停止各个Timeout和Interval
|
||||
for (var i in core.timeout) {
|
||||
clearTimeout(core.timeout[i]);
|
||||
core.timeout[i] = null;
|
||||
}
|
||||
for (var i in core.interval) {
|
||||
clearInterval(core.interval[i]);
|
||||
core.interval[i] = null;
|
||||
}
|
||||
|
||||
// 初始化status
|
||||
@ -1229,6 +1238,18 @@ core.prototype.ondown = function (x ,y) {
|
||||
if (core.isset(core.status.replay)&&core.status.replay.replaying) return;
|
||||
if (!core.status.played || core.status.lockControl) {
|
||||
core.onclick(x, y, []);
|
||||
if (core.timeout.onDownTimeout==null) {
|
||||
core.timeout.onDownTimeout = setTimeout(function () {
|
||||
if (core.interval.onDownInterval == null) {
|
||||
core.interval.onDownInterval = setInterval(function () {
|
||||
if (!core.events.longClick()) {
|
||||
clearInterval(core.interval.onDownInterval);
|
||||
core.interval.onDownInterval = null;
|
||||
}
|
||||
}, 40)
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1271,6 +1292,12 @@ core.prototype.onmove = function (x ,y) {
|
||||
////// 当点击(触摸)事件放开时 //////
|
||||
core.prototype.onup = function () {
|
||||
if (core.isset(core.status.replay)&&core.status.replay.replaying) return;
|
||||
|
||||
clearTimeout(core.timeout.onDownTimeout);
|
||||
core.timeout.onDownTimeout = null;
|
||||
clearInterval(core.interval.onDownInterval);
|
||||
core.interval.onDownInterval = null;
|
||||
|
||||
// core.status.holdingPath=0;
|
||||
if(core.status.stepPostfix.length>0){
|
||||
var stepPostfix = [];
|
||||
@ -1290,7 +1317,10 @@ core.prototype.onup = function () {
|
||||
|
||||
// 长按
|
||||
if (!core.status.lockControl && stepPostfix.length==0 && core.status.downTime!=null && new Date()-core.status.downTime>=1000) {
|
||||
core.events.longClick();
|
||||
core.waitHeroToStop(function () {
|
||||
// 绘制快捷键
|
||||
core.ui.drawKeyBoard();
|
||||
});
|
||||
}
|
||||
else {
|
||||
//posx,posy是寻路的目标点,stepPostfix是后续的移动
|
||||
|
||||
272
libs/events.js
272
libs/events.js
@ -1,7 +1,7 @@
|
||||
function events() {
|
||||
|
||||
}
|
||||
|
||||
var eventdata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.events;
|
||||
////// 初始化 //////
|
||||
events.prototype.init = function () {
|
||||
this.events = {
|
||||
@ -105,52 +105,16 @@ events.prototype.startGame = function (hard) {
|
||||
}
|
||||
|
||||
////// 不同难度分别设置初始属性 //////
|
||||
events.prototype.setInitData = function (hard) {
|
||||
if (hard=='Easy') { // 简单难度
|
||||
core.setFlag('hard', 1); // 可以用flag:hard来获得当前难度
|
||||
// 可以在此设置一些初始福利,比如设置初始生命值可以调用:
|
||||
// core.setStatus("hp", 10000);
|
||||
// 赠送一把黄钥匙可以调用
|
||||
// core.setItem("yellowKey", 1);
|
||||
}
|
||||
if (hard=='Normal') { // 普通难度
|
||||
core.setFlag('hard', 2); // 可以用flag:hard来获得当前难度
|
||||
}
|
||||
if (hard=='Hard') { // 困难难度
|
||||
core.setFlag('hard', 3); // 可以用flag:hard来获得当前难度
|
||||
}
|
||||
this.afterLoadData();
|
||||
}
|
||||
events.prototype.setInitData = eventdata.setInitData
|
||||
// function (hard)
|
||||
|
||||
////// 游戏获胜事件 //////
|
||||
events.prototype.win = function(reason) {
|
||||
core.ui.closePanel();
|
||||
var replaying = core.status.replay.replaying;
|
||||
core.stopReplay();
|
||||
core.waitHeroToStop(function() {
|
||||
core.removeGlobalAnimate(0,0,true);
|
||||
core.clearMap('all'); // 清空全地图
|
||||
core.drawText([
|
||||
"\t[恭喜通关]你的分数是${status:hp}。"
|
||||
], function () {
|
||||
core.events.gameOver('', replaying);
|
||||
})
|
||||
});
|
||||
}
|
||||
events.prototype.win = eventdata.win
|
||||
// function(reason)
|
||||
|
||||
////// 游戏失败事件 //////
|
||||
events.prototype.lose = function(reason) {
|
||||
core.ui.closePanel();
|
||||
var replaying = core.status.replay.replaying;
|
||||
core.stopReplay();
|
||||
core.waitHeroToStop(function() {
|
||||
core.drawText([
|
||||
"\t[结局1]你死了。\n如题。"
|
||||
], function () {
|
||||
core.events.gameOver(null, replaying);
|
||||
});
|
||||
})
|
||||
}
|
||||
events.prototype.lose = eventdata.lose
|
||||
// function(reason)
|
||||
|
||||
////// 游戏结束 //////
|
||||
events.prototype.gameOver = function (ending, fromReplay) {
|
||||
@ -230,20 +194,8 @@ events.prototype.gameOver = function (ending, fromReplay) {
|
||||
}
|
||||
|
||||
////// 转换楼层结束的事件 //////
|
||||
events.prototype.afterChangeFloor = function (floorId) {
|
||||
if (core.isset(core.status.event.id)) return; // 当前存在事件
|
||||
|
||||
if (!core.hasFlag("visited_"+floorId)) {
|
||||
this.doEvents(core.floors[floorId].firstArrive, null, null, function () {
|
||||
//core.autosave();
|
||||
});
|
||||
core.setFlag("visited_"+floorId, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// 自动存档
|
||||
//core.autosave();
|
||||
}
|
||||
events.prototype.afterChangeFloor = eventdata.afterChangeFloor
|
||||
// function (floorId)
|
||||
|
||||
////// 开始执行一系列自定义事件 //////
|
||||
events.prototype.doEvents = function (list, x, y, callback) {
|
||||
@ -266,6 +218,8 @@ events.prototype.doEvents = function (list, x, y, callback) {
|
||||
events.prototype.doAction = function() {
|
||||
// 清空boxAnimate和UI层
|
||||
core.status.boxAnimateObjs = [];
|
||||
clearInterval(core.status.event.interval);
|
||||
|
||||
core.clearMap('ui', 0, 0, 416, 416);
|
||||
core.setAlpha('ui', 1.0);
|
||||
|
||||
@ -301,7 +255,17 @@ events.prototype.doAction = function() {
|
||||
if (core.status.replay.replaying)
|
||||
core.events.doAction();
|
||||
else
|
||||
core.ui.drawTextBox(data.data);
|
||||
core.ui.drawTextBox(data.text);
|
||||
break;
|
||||
case "autoText":
|
||||
if (core.status.replay.replaying)
|
||||
core.events.doAction();
|
||||
else {
|
||||
core.ui.drawTextBox(data.text);
|
||||
setTimeout(function () {
|
||||
core.events.doAction();
|
||||
}, data.time || 3000);
|
||||
}
|
||||
break;
|
||||
case "setText": // 设置文本状态
|
||||
if (data.position=='up'||data.position=='down'||data.position=='center') {
|
||||
@ -316,6 +280,9 @@ events.prototype.doAction = function() {
|
||||
if (core.isset(data.bold)) {
|
||||
core.status.textAttribute.bold=data.bold;
|
||||
}
|
||||
if (core.isset(data.time)) {
|
||||
core.status.textAttribute.time=data.time;
|
||||
}
|
||||
core.events.doAction();
|
||||
break;
|
||||
case "tip":
|
||||
@ -777,124 +744,16 @@ events.prototype.useItem = function(itemId) {
|
||||
}
|
||||
|
||||
////// 加点事件 //////
|
||||
events.prototype.addPoint = function (enemy) {
|
||||
var point = enemy.point;
|
||||
if (!core.isset(point) || point<=0) return [];
|
||||
|
||||
// 加点,返回一个choices事件
|
||||
return [
|
||||
{"type": "choices",
|
||||
"choices": [
|
||||
{"text": "攻击+"+(1*point), "action": [
|
||||
{"type": "setValue", "name": "status:atk", "value": "status:atk+"+(1*point)}
|
||||
]},
|
||||
{"text": "防御+"+(2*point), "action": [
|
||||
{"type": "setValue", "name": "status:def", "value": "status:def+"+(2*point)}
|
||||
]},
|
||||
{"text": "生命+"+(200*point), "action": [
|
||||
{"type": "setValue", "name": "status:hp", "value": "status:hp+"+(200*point)}
|
||||
]},
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
events.prototype.addPoint = eventdata.addPoint
|
||||
// function (enemy)
|
||||
|
||||
////// 战斗结束后触发的事件 //////
|
||||
events.prototype.afterBattle = function(enemyId,x,y,callback) {
|
||||
|
||||
var enemy = core.material.enemys[enemyId];
|
||||
|
||||
// 毒衰咒的处理
|
||||
var special = enemy.special;
|
||||
// 中毒
|
||||
if (core.enemys.hasSpecial(special, 12) && !core.hasFlag('poison')) {
|
||||
core.setFlag('poison', true);
|
||||
}
|
||||
// 衰弱
|
||||
if (core.enemys.hasSpecial(special, 13) && !core.hasFlag('weak')) {
|
||||
core.setFlag('weak', true);
|
||||
core.status.hero.atk-=core.values.weakValue;
|
||||
core.status.hero.def-=core.values.weakValue;
|
||||
}
|
||||
// 诅咒
|
||||
if (core.enemys.hasSpecial(special, 14) && !core.hasFlag('curse')) {
|
||||
core.setFlag('curse', true);
|
||||
}
|
||||
// 仇恨属性:减半
|
||||
if (core.flags.hatredDecrease && core.enemys.hasSpecial(special, 17)) {
|
||||
core.setFlag('hatred', parseInt(core.getFlag('hatred', 0)/2));
|
||||
}
|
||||
// 自爆
|
||||
if (core.enemys.hasSpecial(special, 19)) {
|
||||
core.status.hero.hp = 1;
|
||||
}
|
||||
// 退化
|
||||
if (core.enemys.hasSpecial(special, 21)) {
|
||||
core.status.hero.atk -= (enemy.atkValue||0);
|
||||
core.status.hero.def -= (enemy.defValue||0);
|
||||
if (core.status.hero.atk<0) core.status.hero.atk=0;
|
||||
if (core.status.hero.def<0) core.status.hero.def=0;
|
||||
}
|
||||
// 增加仇恨值
|
||||
core.setFlag('hatred', core.getFlag('hatred',0)+core.values.hatred);
|
||||
core.updateStatusBar();
|
||||
|
||||
|
||||
// 事件的处理
|
||||
var todo = [];
|
||||
// 如果不为阻击,且该点存在,且有事件
|
||||
if (!core.enemys.hasSpecial(special, 18) && core.isset(x) && core.isset(y)) {
|
||||
var event = core.floors[core.status.floorId].afterBattle[x+","+y];
|
||||
if (core.isset(event)) {
|
||||
// 插入事件
|
||||
core.unshift(todo, event);
|
||||
}
|
||||
}
|
||||
// 如果有加点
|
||||
var point = core.material.enemys[enemyId].point;
|
||||
if (core.isset(point) && point>0) {
|
||||
core.unshift(todo, core.events.addPoint(core.material.enemys[enemyId]));
|
||||
}
|
||||
|
||||
// 如果事件不为空,将其插入
|
||||
if (todo.length>0) {
|
||||
this.insertAction(todo,x,y);
|
||||
}
|
||||
|
||||
// 如果已有事件正在处理中
|
||||
if (core.status.event.id == null) {
|
||||
core.continueAutomaticRoute();
|
||||
}
|
||||
else {
|
||||
core.clearContinueAutomaticRoute();
|
||||
}
|
||||
if (core.isset(callback)) callback();
|
||||
|
||||
}
|
||||
events.prototype.afterBattle = eventdata.afterBattle
|
||||
// function(enemyId,x,y,callback)
|
||||
|
||||
////// 开一个门后触发的事件 //////
|
||||
events.prototype.afterOpenDoor = function(doorId,x,y,callback) {
|
||||
|
||||
var todo = [];
|
||||
if (core.isset(x) && core.isset(y)) {
|
||||
var event = core.floors[core.status.floorId].afterOpenDoor[x+","+y];
|
||||
if (core.isset(event)) {
|
||||
core.unshift(todo, event);
|
||||
}
|
||||
}
|
||||
|
||||
if (todo.length>0) {
|
||||
this.insertAction(todo,x,y);
|
||||
}
|
||||
|
||||
if (core.status.event.id == null) {
|
||||
core.continueAutomaticRoute();
|
||||
}
|
||||
else {
|
||||
core.clearContinueAutomaticRoute();
|
||||
}
|
||||
if (core.isset(callback)) callback();
|
||||
}
|
||||
events.prototype.afterOpenDoor = eventdata.afterOpenDoor
|
||||
// function(doorId,x,y,callback)
|
||||
|
||||
////// 经过一个路障 //////
|
||||
events.prototype.passNet = function (data) {
|
||||
@ -945,9 +804,8 @@ events.prototype.changeLight = function(x, y) {
|
||||
}
|
||||
|
||||
////// 改变亮灯之后,可以触发的事件 //////
|
||||
events.prototype.afterChangeLight = function(x,y) {
|
||||
|
||||
}
|
||||
events.prototype.afterChangeLight = eventdata.afterChangeLight
|
||||
// function(x,y)
|
||||
|
||||
////// 滑冰 //////
|
||||
events.prototype.ski = function (direction) {
|
||||
@ -1024,54 +882,20 @@ events.prototype.pushBox = function (data) {
|
||||
}
|
||||
|
||||
////// 推箱子后的事件 //////
|
||||
events.prototype.afterPushBox = function () {
|
||||
|
||||
var noBoxLeft = function () {
|
||||
// 地图上是否还存在未推到的箱子,如果不存在则返回true,存在则返回false
|
||||
for (var i=0;i<core.status.thisMap.blocks.length;i++) {
|
||||
var block=core.status.thisMap.blocks[i];
|
||||
if (core.isset(block.event) && block.event.id=='box') return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (noBoxLeft()) {
|
||||
// 可以通过if语句来进行开门操作
|
||||
/*
|
||||
if (core.status.floorId=='xxx') { // 在某个楼层
|
||||
core.insertAction([ // 插入一条事件
|
||||
{"type": "openDoor", "loc": [x,y]} // 开门
|
||||
])
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
events.prototype.afterPushBox = eventdata.afterPushBox
|
||||
// function ()
|
||||
|
||||
////// 使用炸弹/圣锤后的事件 //////
|
||||
events.prototype.afterUseBomb = function () {
|
||||
|
||||
// 这是一个使用炸弹也能开门的例子
|
||||
/*
|
||||
if (core.status.floorId=='xxx' && core.terrainExists(x0,y0,'specialDoor') // 某个楼层,该机关门存在
|
||||
&& !core.enemyExists(x1,y1) && !core.enemyExists(x2,y2)) // 且守门的怪物都不存在
|
||||
{
|
||||
core.insertAction([ // 插入事件
|
||||
{"type": "openDoor", "loc": [x0,y0]} // 开门
|
||||
])
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
events.prototype.afterUseBomb = eventdata.afterUseBomb
|
||||
// function ()
|
||||
|
||||
////// 即将存档前可以执行的操作 //////
|
||||
events.prototype.beforeSaveData = function(data) {
|
||||
|
||||
}
|
||||
events.prototype.beforeSaveData = eventdata.beforeSaveData
|
||||
// function(data)
|
||||
|
||||
////// 读档事件后,载入事件前,可以执行的操作 //////
|
||||
events.prototype.afterLoadData = function(data) {
|
||||
|
||||
}
|
||||
events.prototype.afterLoadData = eventdata.afterLoadData
|
||||
// function(data)
|
||||
|
||||
|
||||
/****************************************/
|
||||
@ -1080,10 +904,15 @@ events.prototype.afterLoadData = function(data) {
|
||||
|
||||
////// 长按 //////
|
||||
events.prototype.longClick = function () {
|
||||
core.waitHeroToStop(function () {
|
||||
// 绘制快捷键
|
||||
core.ui.drawKeyBoard();
|
||||
});
|
||||
if (core.status.event.id=='text') {
|
||||
core.drawText();
|
||||
return true;
|
||||
}
|
||||
if (core.status.event.id=='action' && core.status.event.data.type=='text') {
|
||||
this.doAction();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////// 按下Ctrl键时(快捷跳过对话) //////
|
||||
@ -2302,3 +2131,4 @@ events.prototype.clickAbout = function () {
|
||||
core.showStartAnimate();
|
||||
}
|
||||
|
||||
delete(eventdata);
|
||||
95
libs/ui.js
95
libs/ui.js
@ -4,7 +4,7 @@
|
||||
* 自动寻路、怪物手册、楼传器、存读档、菜单栏、NPC对话事件、等等
|
||||
*/
|
||||
function ui() {}
|
||||
|
||||
var uidata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.ui;
|
||||
// 初始化UI
|
||||
ui.prototype.init = function () {
|
||||
}
|
||||
@ -15,6 +15,7 @@ main.instance.ui = new ui();
|
||||
////// 结束一切事件和绘制,关闭UI窗口,返回游戏进程 //////
|
||||
ui.prototype.closePanel = function () {
|
||||
core.status.boxAnimateObjs = [];
|
||||
clearInterval(core.status.event.interval);
|
||||
core.clearMap('ui', 0, 0, 416, 416);
|
||||
core.setAlpha('ui', 1.0);
|
||||
core.unLockControl();
|
||||
@ -22,11 +23,14 @@ ui.prototype.closePanel = function () {
|
||||
core.status.event.id = null;
|
||||
core.status.event.selection = null;
|
||||
core.status.event.ui = null;
|
||||
core.status.event.interval = null;
|
||||
}
|
||||
|
||||
////// 绘制一个对话框 //////
|
||||
ui.prototype.drawTextBox = function(content) {
|
||||
|
||||
clearInterval(core.status.event.interval);
|
||||
|
||||
// 获得name, image, icon
|
||||
var id=null, name=null, image=null, icon=null;
|
||||
if (content.indexOf("\t[")==0 || content.indexOf("\\t[")==0) {
|
||||
@ -97,13 +101,6 @@ ui.prototype.drawTextBox = function(content) {
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
if (ss.length==3) {
|
||||
px=parseInt(ss[1]);
|
||||
py=parseInt(ss[2]);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,7 +128,7 @@ ui.prototype.drawTextBox = function(content) {
|
||||
|
||||
var top;
|
||||
if (position=='center') {
|
||||
top = (416 - height) / 2;
|
||||
top = parseInt((416 - height) / 2);
|
||||
}
|
||||
else if (position=='up') {
|
||||
if (px==null || py==null) {
|
||||
@ -227,15 +224,37 @@ ui.prototype.drawTextBox = function(content) {
|
||||
}
|
||||
}
|
||||
|
||||
core.setAlpha('ui', textAttribute.text[3]);
|
||||
core.setFillStyle('ui', core.arrayToRGB(textAttribute.text));
|
||||
|
||||
for (var i=0;i<contents.length;i++) {
|
||||
core.fillText('ui', contents[i], content_left, content_top, null, font);
|
||||
content_top+=21;
|
||||
var drawContent = function (content) {
|
||||
|
||||
core.clearMap("ui", content_left, content_top - 18, validWidth, top + height - content_top + 10);
|
||||
core.setAlpha('ui', textAttribute.background[3]);
|
||||
core.setFillStyle('ui', core.arrayToRGB(textAttribute.background));
|
||||
core.fillRect("ui", content_left, content_top - 18, validWidth, top + height - content_top + 10);
|
||||
|
||||
core.setAlpha('ui', textAttribute.text[3]);
|
||||
core.setFillStyle('ui', core.arrayToRGB(textAttribute.text));
|
||||
var contents = core.splitLines("ui", content, validWidth, font);
|
||||
|
||||
for (var i=0;i<contents.length;i++) {
|
||||
core.fillText('ui', contents[i], content_left, content_top + 21*i, null, font);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (textAttribute.time<=0 || core.status.event.id!='action') {
|
||||
drawContent(content);
|
||||
}
|
||||
else {
|
||||
var index=0;
|
||||
core.status.event.interval = setInterval(function () {
|
||||
drawContent(content.substring(0, ++index));
|
||||
if (index==content.length) {
|
||||
clearInterval(core.status.event.interval);
|
||||
}
|
||||
}, textAttribute.time);
|
||||
}
|
||||
|
||||
// core.fillText('ui', '<点击任意位置继续>', 270, top+height-13, '#CCCCCC', '13px Verdana');
|
||||
}
|
||||
|
||||
////// 绘制一个选项界面 //////
|
||||
@ -400,7 +419,7 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) {
|
||||
max_length = Math.max(max_length, core.canvas.ui.measureText(contents[i]).width);
|
||||
}
|
||||
|
||||
var left = Math.min(208 - 40 - max_length / 2, 100);
|
||||
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;
|
||||
|
||||
@ -418,10 +437,10 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) {
|
||||
|
||||
var len=core.canvas.ui.measureText("确定").width;
|
||||
if (core.status.event.selection==0) {
|
||||
core.strokeRect('ui', 208-38-len/2-5, top+bottom-35-20, len+10, 28, "#FFD700", 2);
|
||||
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-len/2-5, top+bottom-35-20, len+10, 28, "#FFD700", 2);
|
||||
core.strokeRect('ui', 208+38-parseInt(len/2)-5, top+bottom-35-20, len+10, 28, "#FFD700", 2);
|
||||
}
|
||||
|
||||
}
|
||||
@ -776,7 +795,7 @@ ui.prototype.drawWaiting = function(text) {
|
||||
var text_length = core.canvas.ui.measureText(text).width;
|
||||
|
||||
var right = Math.max(text_length+50, 220);
|
||||
var left = 208-right/2, top = 208 - 32 - 16, bottom = 416 - 2 * top;
|
||||
var left = 208-parseInt(right/2), top = 208 - 32 - 16, bottom = 416 - 2 * top;
|
||||
|
||||
core.fillRect('ui', left, top, right, bottom, background);
|
||||
core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2);
|
||||
@ -822,7 +841,7 @@ ui.prototype.drawPagination = function (page, totalPage) {
|
||||
var length = core.canvas.ui.measureText(page + " / " + page).width;
|
||||
|
||||
core.canvas.ui.textAlign = 'left';
|
||||
core.fillText('ui', page + " / " + totalPage, (416 - length) / 2, 403);
|
||||
core.fillText('ui', page + " / " + totalPage, parseInt((416 - length) / 2), 403);
|
||||
|
||||
core.canvas.ui.textAlign = 'center';
|
||||
if (page > 1)
|
||||
@ -1231,7 +1250,7 @@ ui.prototype.drawSLPanel = function(index) {
|
||||
core.setAlpha('ui', 1);
|
||||
core.canvas.ui.textAlign = 'center';
|
||||
|
||||
var u=416/6, size=117;
|
||||
var u=416/6, size=118;
|
||||
|
||||
var name=core.status.event.id=='save'?"存档":"读档";
|
||||
for (var i=0;i<6;i++) {
|
||||
@ -1371,33 +1390,7 @@ ui.prototype.drawKeyBoard = function () {
|
||||
}
|
||||
|
||||
////// 绘制“关于”界面 //////
|
||||
ui.prototype.drawAbout = function() {
|
||||
|
||||
if (!core.isPlaying()) {
|
||||
core.status.event = {'id': null, 'data': null};
|
||||
core.dom.startPanel.style.display = 'none';
|
||||
}
|
||||
core.lockControl();
|
||||
core.status.event.id = 'about';
|
||||
|
||||
core.clearMap('ui', 0, 0, 416, 416);
|
||||
var left = 48, top = 36, right = 416 - 2 * left, bottom = 416 - 2 * top;
|
||||
|
||||
core.setAlpha('ui', 0.85);
|
||||
core.fillRect('ui', left, top, right, bottom, '#000000');
|
||||
core.setAlpha('ui', 1);
|
||||
core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2);
|
||||
|
||||
var text_start = left + 24;
|
||||
|
||||
// 名称
|
||||
core.canvas.ui.textAlign = "left";
|
||||
core.fillText('ui', "HTML5 魔塔样板", text_start, top+35, "#FFD700", "bold 22px Verdana");
|
||||
core.fillText('ui', "版本: "+core.firstData.version, text_start, top + 80, "#FFFFFF", "bold 17px Verdana");
|
||||
core.fillText('ui', "作者: 艾之葵", text_start, top + 112);
|
||||
core.fillText('ui', 'HTML5魔塔交流群:539113091', text_start, top+112+32);
|
||||
// TODO: 写自己的“关于”页面,每次增加32像素即可
|
||||
}
|
||||
ui.prototype.drawAbout = uidata.drawAbout
|
||||
|
||||
////// 绘制帮助页面 //////
|
||||
ui.prototype.drawHelp = function () {
|
||||
@ -1424,6 +1417,8 @@ ui.prototype.drawHelp = function () {
|
||||
"点任意块并拖动: 指定寻路路线\n"+
|
||||
"单击勇士: 转向\n"+
|
||||
"双击勇士: 轻按(仅在轻按开关打开时有效)\n"+
|
||||
"长按任意位置:打开虚拟键盘"
|
||||
"长按任意位置:跳过剧情对话或打开虚拟键盘\n"
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
delete(uidata)
|
||||
35
main.js
35
main.js
@ -17,6 +17,7 @@ function main() {
|
||||
'startTopProgress': document.getElementById('startTopProgress'),
|
||||
'startTopLoadTips': document.getElementById('startTopLoadTips'),
|
||||
'startBackground': document.getElementById('startBackground'),
|
||||
'startLogo': document.getElementById('startLogo'),
|
||||
'startButtonGroup': document.getElementById('startButtonGroup'),
|
||||
'floorMsgGroup': document.getElementById('floorMsgGroup'),
|
||||
'logoLabel': document.getElementById('logoLabel'),
|
||||
@ -33,9 +34,6 @@ function main() {
|
||||
'loadGame': document.getElementById('loadGame'),
|
||||
'replayGame': document.getElementById('replayGame'),
|
||||
'levelChooseButtons': document.getElementById('levelChooseButtons'),
|
||||
'easyLevel': document.getElementById('easyLevel'),
|
||||
'normalLevel': document.getElementById('normalLevel'),
|
||||
'hardLevel': document.getElementById('hardLevel'),
|
||||
'data': document.getElementById('data'),
|
||||
'statusLabels': document.getElementsByClassName('statusLabel'),
|
||||
'floorCol': document.getElementById('floorCol'),
|
||||
@ -52,7 +50,7 @@ function main() {
|
||||
'items', 'icons', 'maps', 'enemys', 'events', 'data', 'ui', 'core'
|
||||
];
|
||||
this.pureData = [
|
||||
"data","enemys","icons","maps","items"
|
||||
"data","enemys","icons","maps","items","functions"
|
||||
];
|
||||
this.images = [
|
||||
'animates', 'enemys', 'hero', 'items', 'npcs', 'terrains'
|
||||
@ -128,6 +126,21 @@ main.prototype.init = function (mode) {
|
||||
main.loadPureData(function(){
|
||||
var mainData = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main;
|
||||
for(var ii in mainData)main[ii]=mainData[ii];
|
||||
|
||||
main.dom.startBackground.src="project/images/"+main.startBackground;
|
||||
main.dom.startLogo.style=main.startLogoStyle;
|
||||
main.levelChoose.forEach(function(value){
|
||||
var span = document.createElement('span');
|
||||
span.setAttribute('class','startButton');
|
||||
span.innerText=value[0];
|
||||
(function(span,str_){
|
||||
span.onclick = function () {
|
||||
core.events.startGame(str_);
|
||||
}
|
||||
})(span,value[1]);
|
||||
main.dom.levelChooseButtons.appendChild(span);
|
||||
});
|
||||
|
||||
main.loaderJs(function () {
|
||||
var coreData = {};
|
||||
for (i = 0; i < main.loadList.length; i++) {
|
||||
@ -454,20 +467,6 @@ main.dom.replayGame.onclick = function () {
|
||||
})
|
||||
}
|
||||
|
||||
////// 点击“简单难度”时 //////
|
||||
main.dom.easyLevel.onclick = function() {
|
||||
core.events.startGame('Easy');
|
||||
}
|
||||
|
||||
////// 点击“普通难度”时 //////
|
||||
main.dom.normalLevel.onclick = function () {
|
||||
core.events.startGame('Normal');
|
||||
}
|
||||
|
||||
////// 点击“困难难度”时 //////
|
||||
main.dom.hardLevel.onclick = function () {
|
||||
core.events.startGame('Hard');
|
||||
}
|
||||
|
||||
}//listen end
|
||||
|
||||
|
||||
@ -7,7 +7,10 @@ data_comment_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
||||
"animates": " 在此存放所有可能使用的动画,必须是animate格式,在这里不写后缀名 \n 动画必须放在animates目录下;文件名不能使用中文,不能带空格或特殊字符 \n \"jianji\", \"thunder\" \n 根据需求自行添加 \n$leaf(true)$end",
|
||||
"bgms": " 在此存放所有的bgm,和文件名一致。第一项为默认播放项 \n 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 \n$leaf(true)$end",
|
||||
"sounds": " 在此存放所有的SE,和文件名一致 \n 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 \n$leaf(true)$end",
|
||||
"bgmRemote" : " 是否使用远程的背景音乐;此项一般不要开启 \n$select({\"values\":[false]})$end"
|
||||
"bgmRemote" : " 是否使用远程的背景音乐;此项一般不要开启 \n$select({\"values\":[false]})$end",
|
||||
"startBackground" : "标题界面的背景,建议使用jpg格式以压缩背景图空间",
|
||||
"startLogoStyle" : "标题样式:可以改变颜色,也可以隐藏标题(如果背景图自带)",
|
||||
"levelChoose" : " 难度选择:每个数组的第一个是其在标题界面显示的难度,第二个是在游戏内部传输的字符串,会显示在状态栏,修改此处后需要在project/functions中作相应更改 \n$leaf(true)$end"
|
||||
},
|
||||
"firstData": {
|
||||
"title": " 游戏名,将显示在标题页面以及切换楼层的界面中 ",
|
||||
|
||||
@ -33,6 +33,10 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
|
||||
// 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
|
||||
],
|
||||
"bgmRemote" : false, // 是否使用远程的背景音乐;此项一般不要开启
|
||||
"startBackground" : "bg.png",// 标题界面的背景,建议使用jpg格式以压缩背景图空间
|
||||
"startLogoStyle" : "color: black",// 标题样式:可以改变颜色,也可以隐藏标题(如果背景图自带)
|
||||
"levelChoose" : [["简单","Easy"],["普通","Normal"],["困难","Hard"],["噩梦","Hell"]],
|
||||
//难度选择:每个数组的第一个是其在标题界面显示的难度,第二个是在游戏内部传输的字符串,会显示在状态栏,修改此处后需要在project/functions中作相应更改
|
||||
},
|
||||
"firstData" : {
|
||||
"title": "魔塔样板", // 游戏名,将显示在标题页面以及切换楼层的界面中
|
||||
|
||||
21
project/functions.comment.js
Normal file
21
project/functions.comment.js
Normal file
@ -0,0 +1,21 @@
|
||||
functions_comment_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
{
|
||||
"events" : {
|
||||
"setInitData" : "不同难度分别设置初始属性",
|
||||
"win" : "游戏获胜事件",
|
||||
"lose" : "游戏失败事件",
|
||||
"afterChangeFloor":"转换楼层结束的事件",
|
||||
"addPoint":"加点事件",
|
||||
"afterBattle" : "战斗结束后触发的事件",
|
||||
"afterOpenDoor" : "开一个门后触发的事件",
|
||||
"afterChangeLight" : "改变亮灯之后,可以触发的事件",
|
||||
"afterPushBox" : "推箱子后的事件",
|
||||
"afterUseBomb" : "使用炸弹/圣锤后的事件",
|
||||
"beforeSaveData" : "即将存档前可以执行的操作",
|
||||
"afterLoadData" : "读档事件后,载入事件前,可以执行的操作"
|
||||
|
||||
},
|
||||
"ui" : {
|
||||
"drawAbout" : "绘制“关于”界面"
|
||||
}
|
||||
}
|
||||
267
project/functions.js
Normal file
267
project/functions.js
Normal file
@ -0,0 +1,267 @@
|
||||
functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
{
|
||||
"events":{
|
||||
////// 不同难度分别设置初始属性 //////
|
||||
"setInitData":function (hard) {
|
||||
if (hard=='Easy') { // 简单难度
|
||||
core.setFlag('hard', 1); // 可以用flag:hard来获得当前难度
|
||||
// 可以在此设置一些初始福利,比如设置初始生命值可以调用:
|
||||
// core.setStatus("hp", 10000);
|
||||
// 赠送一把黄钥匙可以调用
|
||||
// core.setItem("yellowKey", 1);
|
||||
}
|
||||
if (hard=='Normal') { // 普通难度
|
||||
core.setFlag('hard', 2); // 可以用flag:hard来获得当前难度
|
||||
}
|
||||
if (hard=='Hard') { // 困难难度
|
||||
core.setFlag('hard', 3); // 可以用flag:hard来获得当前难度
|
||||
}
|
||||
if (hard=='Hell') { // 噩梦难度
|
||||
core.setFlag('hard', 4); // 可以用flag:hard来获得当前难度
|
||||
}
|
||||
this.afterLoadData();
|
||||
},
|
||||
////// 游戏获胜事件 //////
|
||||
"win" : function(reason) {
|
||||
core.ui.closePanel();
|
||||
var replaying = core.status.replay.replaying;
|
||||
core.stopReplay();
|
||||
core.waitHeroToStop(function() {
|
||||
core.removeGlobalAnimate(0,0,true);
|
||||
core.clearMap('all'); // 清空全地图
|
||||
core.drawText([
|
||||
"\t[恭喜通关]你的分数是${status:hp}。"
|
||||
], function () {
|
||||
core.events.gameOver('', replaying);
|
||||
})
|
||||
});
|
||||
},
|
||||
////// 游戏失败事件 //////
|
||||
"lose" : function(reason) {
|
||||
core.ui.closePanel();
|
||||
var replaying = core.status.replay.replaying;
|
||||
core.stopReplay();
|
||||
core.waitHeroToStop(function() {
|
||||
core.drawText([
|
||||
"\t[结局1]你死了。\n如题。"
|
||||
], function () {
|
||||
core.events.gameOver(null, replaying);
|
||||
});
|
||||
})
|
||||
},
|
||||
////// 转换楼层结束的事件 //////
|
||||
"afterChangeFloor" : function (floorId) {
|
||||
if (core.isset(core.status.event.id)) return; // 当前存在事件
|
||||
|
||||
if (!core.hasFlag("visited_"+floorId)) {
|
||||
this.doEvents(core.floors[floorId].firstArrive, null, null, function () {
|
||||
//core.autosave();
|
||||
});
|
||||
core.setFlag("visited_"+floorId, true);
|
||||
return;
|
||||
}
|
||||
|
||||
// 自动存档
|
||||
//core.autosave();
|
||||
},
|
||||
////// 加点事件 //////
|
||||
"addPoint" : function (enemy) {
|
||||
var point = enemy.point;
|
||||
if (!core.isset(point) || point<=0) return [];
|
||||
|
||||
// 加点,返回一个choices事件
|
||||
return [
|
||||
{"type": "choices",
|
||||
"choices": [
|
||||
{"text": "攻击+"+(1*point), "action": [
|
||||
{"type": "setValue", "name": "status:atk", "value": "status:atk+"+(1*point)}
|
||||
]},
|
||||
{"text": "防御+"+(2*point), "action": [
|
||||
{"type": "setValue", "name": "status:def", "value": "status:def+"+(2*point)}
|
||||
]},
|
||||
{"text": "生命+"+(200*point), "action": [
|
||||
{"type": "setValue", "name": "status:hp", "value": "status:hp+"+(200*point)}
|
||||
]},
|
||||
]
|
||||
}
|
||||
];
|
||||
},
|
||||
////// 战斗结束后触发的事件 //////
|
||||
"afterBattle" : function(enemyId,x,y,callback) {
|
||||
|
||||
var enemy = core.material.enemys[enemyId];
|
||||
|
||||
// 毒衰咒的处理
|
||||
var special = enemy.special;
|
||||
// 中毒
|
||||
if (core.enemys.hasSpecial(special, 12) && !core.hasFlag('poison')) {
|
||||
core.setFlag('poison', true);
|
||||
}
|
||||
// 衰弱
|
||||
if (core.enemys.hasSpecial(special, 13) && !core.hasFlag('weak')) {
|
||||
core.setFlag('weak', true);
|
||||
core.status.hero.atk-=core.values.weakValue;
|
||||
core.status.hero.def-=core.values.weakValue;
|
||||
}
|
||||
// 诅咒
|
||||
if (core.enemys.hasSpecial(special, 14) && !core.hasFlag('curse')) {
|
||||
core.setFlag('curse', true);
|
||||
}
|
||||
// 仇恨属性:减半
|
||||
if (core.flags.hatredDecrease && core.enemys.hasSpecial(special, 17)) {
|
||||
core.setFlag('hatred', parseInt(core.getFlag('hatred', 0)/2));
|
||||
}
|
||||
// 自爆
|
||||
if (core.enemys.hasSpecial(special, 19)) {
|
||||
core.status.hero.hp = 1;
|
||||
}
|
||||
// 退化
|
||||
if (core.enemys.hasSpecial(special, 21)) {
|
||||
core.status.hero.atk -= (enemy.atkValue||0);
|
||||
core.status.hero.def -= (enemy.defValue||0);
|
||||
if (core.status.hero.atk<0) core.status.hero.atk=0;
|
||||
if (core.status.hero.def<0) core.status.hero.def=0;
|
||||
}
|
||||
// 增加仇恨值
|
||||
core.setFlag('hatred', core.getFlag('hatred',0)+core.values.hatred);
|
||||
core.updateStatusBar();
|
||||
|
||||
|
||||
// 事件的处理
|
||||
var todo = [];
|
||||
// 如果不为阻击,且该点存在,且有事件
|
||||
if (!core.enemys.hasSpecial(special, 18) && core.isset(x) && core.isset(y)) {
|
||||
var event = core.floors[core.status.floorId].afterBattle[x+","+y];
|
||||
if (core.isset(event)) {
|
||||
// 插入事件
|
||||
core.unshift(todo, event);
|
||||
}
|
||||
}
|
||||
// 如果有加点
|
||||
var point = core.material.enemys[enemyId].point;
|
||||
if (core.isset(point) && point>0) {
|
||||
core.unshift(todo, core.events.addPoint(core.material.enemys[enemyId]));
|
||||
}
|
||||
|
||||
// 如果事件不为空,将其插入
|
||||
if (todo.length>0) {
|
||||
this.insertAction(todo,x,y);
|
||||
}
|
||||
|
||||
// 如果已有事件正在处理中
|
||||
if (core.status.event.id == null) {
|
||||
core.continueAutomaticRoute();
|
||||
}
|
||||
else {
|
||||
core.clearContinueAutomaticRoute();
|
||||
}
|
||||
if (core.isset(callback)) callback();
|
||||
|
||||
},
|
||||
////// 开一个门后触发的事件 //////
|
||||
"afterOpenDoor" : function(doorId,x,y,callback) {
|
||||
|
||||
var todo = [];
|
||||
if (core.isset(x) && core.isset(y)) {
|
||||
var event = core.floors[core.status.floorId].afterOpenDoor[x+","+y];
|
||||
if (core.isset(event)) {
|
||||
core.unshift(todo, event);
|
||||
}
|
||||
}
|
||||
|
||||
if (todo.length>0) {
|
||||
this.insertAction(todo,x,y);
|
||||
}
|
||||
|
||||
if (core.status.event.id == null) {
|
||||
core.continueAutomaticRoute();
|
||||
}
|
||||
else {
|
||||
core.clearContinueAutomaticRoute();
|
||||
}
|
||||
if (core.isset(callback)) callback();
|
||||
},
|
||||
////// 改变亮灯之后,可以触发的事件 //////
|
||||
"afterChangeLight" : function(x,y) {
|
||||
|
||||
},
|
||||
////// 推箱子后的事件 //////
|
||||
"afterPushBox" : function () {
|
||||
|
||||
var noBoxLeft = function () {
|
||||
// 地图上是否还存在未推到的箱子,如果不存在则返回true,存在则返回false
|
||||
for (var i=0;i<core.status.thisMap.blocks.length;i++) {
|
||||
var block=core.status.thisMap.blocks[i];
|
||||
if (core.isset(block.event) && block.event.id=='box') return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (noBoxLeft()) {
|
||||
// 可以通过if语句来进行开门操作
|
||||
/*
|
||||
if (core.status.floorId=='xxx') { // 在某个楼层
|
||||
core.insertAction([ // 插入一条事件
|
||||
{"type": "openDoor", "loc": [x,y]} // 开门
|
||||
])
|
||||
}
|
||||
*/
|
||||
}
|
||||
},
|
||||
////// 使用炸弹/圣锤后的事件 //////
|
||||
"afterUseBomb" : function () {
|
||||
|
||||
// 这是一个使用炸弹也能开门的例子
|
||||
/*
|
||||
if (core.status.floorId=='xxx' && core.terrainExists(x0,y0,'specialDoor') // 某个楼层,该机关门存在
|
||||
&& !core.enemyExists(x1,y1) && !core.enemyExists(x2,y2)) // 且守门的怪物都不存在
|
||||
{
|
||||
core.insertAction([ // 插入事件
|
||||
{"type": "openDoor", "loc": [x0,y0]} // 开门
|
||||
])
|
||||
}
|
||||
*/
|
||||
|
||||
},
|
||||
////// 即将存档前可以执行的操作 //////
|
||||
"beforeSaveData" : function(data) {
|
||||
|
||||
},
|
||||
////// 读档事件后,载入事件前,可以执行的操作 //////
|
||||
"afterLoadData" : function(data) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
"ui":{
|
||||
////// 绘制“关于”界面 //////
|
||||
"drawAbout" : function() {
|
||||
|
||||
if (!core.isPlaying()) {
|
||||
core.status.event = {'id': null, 'data': null};
|
||||
core.dom.startPanel.style.display = 'none';
|
||||
}
|
||||
core.lockControl();
|
||||
core.status.event.id = 'about';
|
||||
|
||||
core.clearMap('ui', 0, 0, 416, 416);
|
||||
var left = 48, top = 36, right = 416 - 2 * left, bottom = 416 - 2 * top;
|
||||
|
||||
core.setAlpha('ui', 0.85);
|
||||
core.fillRect('ui', left, top, right, bottom, '#000000');
|
||||
core.setAlpha('ui', 1);
|
||||
core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2);
|
||||
|
||||
var text_start = left + 24;
|
||||
|
||||
// 名称
|
||||
core.canvas.ui.textAlign = "left";
|
||||
core.fillText('ui', "HTML5 魔塔样板", text_start, top+35, "#FFD700", "bold 22px Verdana");
|
||||
core.fillText('ui', "版本: "+core.firstData.version, text_start, top + 80, "#FFFFFF", "bold 17px Verdana");
|
||||
core.fillText('ui', "作者: 艾之葵", text_start, top + 112);
|
||||
core.fillText('ui', 'HTML5魔塔交流群:539113091', text_start, top+112+32);
|
||||
// TODO: 写自己的“关于”页面,每次增加32像素即可
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user