Merge pull request #59 from zhaouv/dev-2.0-functions-20180227

Dev 2 0 functions 20180227
This commit is contained in:
Zhang Chen 2018-02-28 20:26:56 +08:00 committed by GitHub
commit 7148bc11e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 537 additions and 327 deletions

View File

@ -53,10 +53,12 @@ HTML5 canvas制作的魔塔样板支持全平台游戏
* [x] 同一个点的多事件处理(做法详见文档)。 * [x] 同一个点的多事件处理(做法详见文档)。
* [x] 增加新地图后可以接档而不用重新开始。 * [x] 增加新地图后可以接档而不用重新开始。
* [x] 增加可以接收用户输入的事件(type:input)。 * [x] 增加可以接收用户输入的事件(type:input)。
* [x] 滚动字幕;自动剧情文本。
* [x] 可以同时show/hide多个事件。 * [x] 可以同时show/hide多个事件。
* [x] 现在可以支持滑冰和推箱子事件了。 * [x] 现在可以支持滑冰和推箱子事件了。
* [x] 地图中每个块的可通行方向控制(悬崖效果)。 * [x] 地图中每个块的可通行方向控制(悬崖效果)。
* [x] 动画支持带旋转和翻转的帧。 * [x] 动画支持带旋转和翻转的帧。
* [x] 长按屏幕可跳过对话。
* [x] 现在可以允许用户丢弃道具了(例如不会再使用的装备)。 * [x] 现在可以允许用户丢弃道具了(例如不会再使用的装备)。
* [x] 修复行走时按键会发生动画抖动问题。 * [x] 修复行走时按键会发生动画抖动问题。
* [x] 修复无法打开战斗动画的Bug。 * [x] 修复无法打开战斗动画的Bug。

View File

@ -155,6 +155,7 @@ return code;
action action
: text_0_s : text_0_s
| text_1_s | text_1_s
| autoText_s
| setText_s | setText_s
| tip_s | tip_s
| setValue_s | setValue_s
@ -201,7 +202,7 @@ text_0_s
/* text_0_s /* text_0_s
tooltip : text显示一段文字剧情 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 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'; var code = '"'+EvalString_0+'",\n';
return code; return code;
*/ */
@ -213,7 +214,7 @@ text_1_s
/* text_1_s /* text_1_s
tooltip : text显示一段文字剧情,选项较多请右键点击帮助 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 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=''; var title='';
if (EvalString_0==''){ if (EvalString_0==''){
if (IdString_0=='')title=''; if (IdString_0=='')title='';
@ -230,14 +231,38 @@ var code = '"'+title+EvalString_1+EvalString_2+'",\n';
return code; 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 setText_s
: '设置剧情文本的属性' '位置' SetTextPosition_List BGNL? '标题颜色' EvalString? '正文颜色' EvalString? '背景色' EvalString? '粗体' B_List Newline : '设置剧情文本的属性' '位置' SetTextPosition_List BGNL? '标题颜色' EvalString? '正文颜色' EvalString? '背景色' EvalString? BGNL? '粗体' B_List '打字间隔' EvalString? Newline
; ;
/* setText_s /* 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 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+'"'; 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)?$/; 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) { 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'); if (!colorRe.test(EvalString_2))throw new Error('颜色格式错误,形如:0~255,0~255,0~255,0~1');
EvalString_2 = ', "background": ['+EvalString_2+']'; 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; 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; return code;
*/ */
@ -1117,7 +1146,7 @@ ActionParser.prototype.parseAction = function() {
// 如果是文字:显示 // 如果是文字:显示
if (typeof data == "string") { if (typeof data == "string") {
data={"type": "text", "data": data} data={"type": "text", "text": data}
} }
this.event.data.type=data.type; this.event.data.type=data.type;
switch (data.type) { switch (data.type) {
@ -1127,7 +1156,12 @@ ActionParser.prototype.parseAction = function() {
return; return;
case "text": // 文字/对话 case "text": // 文字/对话
this.next = MotaActionBlocks['text_0_s'].xmlText([ 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; break;
case "setText": // 设置剧情文本的属性 case "setText": // 设置剧情文本的属性
var setTextfunc = function(a){return a?JSON.stringify(a).slice(1,-1):null;} 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.text=setTextfunc(data.text);
data.background=setTextfunc(data.background); data.background=setTextfunc(data.background);
this.next = MotaActionBlocks['setText_s'].xmlText([ 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; break;
case "tip": case "tip":
this.next = MotaActionBlocks['tip_s'].xmlText([ this.next = MotaActionBlocks['tip_s'].xmlText([

View File

@ -53,6 +53,13 @@ initscript=String.raw`
'<label text="显示文字"></label>', '<label text="显示文字"></label>',
MotaActionBlocks['text_0_s'].xmlText(), MotaActionBlocks['text_0_s'].xmlText(),
MotaActionBlocks['text_1_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['setText_s'].xmlText(),
MotaActionBlocks['showImage_0_s'].xmlText(), MotaActionBlocks['showImage_0_s'].xmlText(),
MotaActionBlocks['showImage_1_s'].xmlText(), MotaActionBlocks['showImage_1_s'].xmlText(),
@ -372,6 +379,7 @@ editor_blockly.doubleClickBlock = function (blockId){
var textStringDict = { var textStringDict = {
'text_0_s':'EvalString_0', 'text_0_s':'EvalString_0',
'text_1_s':'EvalString_2', 'text_1_s':'EvalString_2',
'autoText_s':'EvalString_2',
'choices_s':'EvalString_0', 'choices_s':'EvalString_0',
'function_s':'RawEvalString_0', 'function_s':'RawEvalString_0',
} }

View File

@ -150,14 +150,14 @@
### text显示一段文字剧情 ### text显示一段文字剧情
使用`{"type": "text"}`可以显示一段文字。后面`"data"`可以指定文字内容。 使用`{"type": "text"}`可以显示一段文字。后面`"text"`可以指定文字内容。
``` js ``` js
"events": { // 该楼的所有可能事件列表 "events": { // 该楼的所有可能事件列表
// 如果大括号里只有"data"项(没有"action"或"enable"),则可以省略到只剩下中括号 // 如果大括号里只有"data"项(没有"action"或"enable"),则可以省略到只剩下中括号
"x,y": [ // 实际执行的事件列表 "x,y": [ // 实际执行的事件列表
{"type": "text", "data": "在界面上的一段文字"}, // 显示文字事件 {"type": "text", "text": "在界面上的一段文字"}, // 显示文字事件
{"type": "text", "data": "这是第二段文字"}, // 显示第二个文字事件 {"type": "text", "text": "这是第二段文字"}, // 显示第二个文字事件
// ... // ...
// 按顺序写事件,直到结束 // 按顺序写事件,直到结束
] ]
@ -171,7 +171,7 @@
// 如果大括号里只有"data"项(没有"action"或"enable"),则可以省略到只剩下中括号 // 如果大括号里只有"data"项(没有"action"或"enable"),则可以省略到只剩下中括号
"x,y": [ // 实际执行的事件列表 "x,y": [ // 实际执行的事件列表
"在界面上的一段文字",// 直接简写,和下面写法完全等价 "在界面上的一段文字",// 直接简写,和下面写法完全等价
{"type": "text", "data": "这是第二段文字"}, // 显示第二个文字事件 {"type": "text", "text": "这是第二段文字"}, // 显示第二个文字事件
// ... // ...
// 按顺序写事件,直到结束 // 按顺序写事件,直到结束
] ]
@ -261,26 +261,49 @@
![调试](./img/eventdebug.png) ![调试](./img/eventdebug.png)
### autoText自动剧情文本
使用`{"type": "autoText"}`可以使用剧情文本。
``` js
"x,y": [ // 实际执行的事件列表
{"type": "autoText", "text": "一段自动显示的剧情文字", "time": 5000}
]
```
text为文本正文内容和上面的写法完全一致。
time为可选项代表该自动文本的时间。可以不指定不指定默认为3000毫秒。
用户无法跳过自动剧情文本只能等待time时间结束后自动过。
回放录像时将忽略自动剧情文本的显示。
!> 由于用户无法跳过自动剧情文本,因此对于大段剧情文本请自行添加“是否跳过剧情”的提示,否则可能会非常不友好。
### setText设置剧情文本的属性 ### setText设置剧情文本的属性
使用`{"type": "setText"}`可以设置剧情文本的各项属性。 使用`{"type": "setText"}`可以设置剧情文本的各项属性。
``` js ``` js
"x,y": [ // 实际执行的事件列表 "x,y": [ // 实际执行的事件列表
{"type": "setText", "position": "up", "title": [255,0,0], "text": [255,255,0], "background": [0,0,255,0.3], "bold": true}, {"type": "setText", "title": [255,0,0], "text": [255,255,0], "background": [0,0,255,0.3]},
"这段话将显示在上方标题为红色正文为黄色粗体背景为透明度0.3的蓝色" {"type": "setText", "position": "up", "bold": true, "time": 70},
"这段话将显示在上方标题为红色正文为黄色粗体背景为透明度0.3的蓝色70毫秒速度打字机效果"
] ]
``` ```
position为可选项表示设置文字显示位置。只能为upcenter和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为可选项表示设置文字显示位置。只能为upcenter和down三者。 默认值: `center`
bold为可选项如果设置则为true或false表示正文是否使用粗体。 bold为可选项如果设置则为true或false表示正文是否使用粗体。 默认值:`false`
time为可选项表示文字添加的速度。若此项设置为0将直接全部显示若大于0则会设置为相邻字符依次显示的时间间隔。 默认值:`0`
### tip显示一段提示文字 ### tip显示一段提示文字

View File

@ -6,7 +6,9 @@
<link rel="shortcut icon" type="image/png" href="./img/logo.png"> <link rel="shortcut icon" type="image/png" href="./img/logo.png">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="description" content="Description"> <meta name="description" content="Description">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" 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"> <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"> <link href="https://cdn.bootcss.com/docsify/4.5.5/themes/vue.css" rel="stylesheet">
</head> </head>

View File

@ -192,20 +192,15 @@
</div> </div>
<p id='startTopLoadTips'>资源即将开始加载</p> <p id='startTopLoadTips'>资源即将开始加载</p>
</div> </div>
<img id='startBackground' src='project/images/bg.png'> <img id='startBackground'>
<!-- 标题界面可以改style的color使标题改变颜色 --> <p id='startLogo'></p>
<p id='startLogo' style="color: black"></p>
<div id='startButtonGroup'> <div id='startButtonGroup'>
<div id='startButtons'> <div id='startButtons'>
<span class='startButton' id='playGame'>开始游戏</span> <span class='startButton' id='playGame'>开始游戏</span>
<span class='startButton' id='loadGame'>载入游戏</span> <span class='startButton' id='loadGame'>载入游戏</span>
<span class='startButton' id='replayGame'>录像回放</span> <span class='startButton' id='replayGame'>录像回放</span>
</div> </div>
<div id='levelChooseButtons'> <div id='levelChooseButtons'></div>
<span class='startButton' id='easyLevel'>简单</span>
<span class='startButton' id='normalLevel'>普通</span>
<span class='startButton' id='hardLevel'>困难</span>
</div>
</div> </div>
</div> </div>
<div id='floorMsgGroup'> <div id='floorMsgGroup'>

View File

@ -25,20 +25,15 @@
</div> </div>
<p id='startTopLoadTips'>资源即将开始加载</p> <p id='startTopLoadTips'>资源即将开始加载</p>
</div> </div>
<img id='startBackground' src='project/images/bg.png'> <img id='startBackground'>
<!-- 标题界面可以改style的color使标题改变颜色 --> <p id='startLogo'></p>
<p id='startLogo' style="color: black"></p>
<div id='startButtonGroup'> <div id='startButtonGroup'>
<div id='startButtons'> <div id='startButtons'>
<span class='startButton' id='playGame'>开始游戏</span> <span class='startButton' id='playGame'>开始游戏</span>
<span class='startButton' id='loadGame'>载入游戏</span> <span class='startButton' id='loadGame'>载入游戏</span>
<span class='startButton' id='replayGame'>录像回放</span> <span class='startButton' id='replayGame'>录像回放</span>
</div> </div>
<div id='levelChooseButtons'> <div id='levelChooseButtons'></div>
<span class='startButton' id='easyLevel'>简单</span>
<span class='startButton' id='normalLevel'>普通</span>
<span class='startButton' id='hardLevel'>困难</span>
</div>
</div> </div>
</div> </div>
<div id='floorMsgGroup'> <div id='floorMsgGroup'>

View File

@ -17,12 +17,14 @@ function core() {
this.timeout = { this.timeout = {
'getItemTipTimeout': null, 'getItemTipTimeout': null,
'turnHeroTimeout': null, 'turnHeroTimeout': null,
'onDownTimeout': null,
} }
this.interval = { this.interval = {
'heroMoveInterval': null, 'heroMoveInterval': null,
"tipAnimate": null, "tipAnimate": null,
'openDoorAnimate': null, 'openDoorAnimate': null,
'animateInterval': null, 'animateInterval': null,
'onDownInterval': null,
} }
this.animateFrame = { this.animateFrame = {
'background': null, 'background': null,
@ -124,6 +126,7 @@ function core() {
'data': null, 'data': null,
'selection': null, 'selection': null,
'ui': null, 'ui': null,
'interval': null,
}, },
'textAttribute': { 'textAttribute': {
'position': "center", 'position': "center",
@ -131,6 +134,7 @@ function core() {
"background": [0,0,0,0.85], "background": [0,0,0,0.85],
"text": [255,255,255,1], "text": [255,255,255,1],
"bold": false, "bold": false,
"time": 0,
}, },
'curtainColor': null, 'curtainColor': null,
'usingCenterFly':false, 'usingCenterFly':false,
@ -775,8 +779,13 @@ core.prototype.clearStatus = function() {
core.prototype.resetStatus = function(hero, hard, floorId, route, maps) { core.prototype.resetStatus = function(hero, hard, floorId, route, maps) {
// 停止各个Timeout和Interval // 停止各个Timeout和Interval
for (var i in core.timeout) {
clearTimeout(core.timeout[i]);
core.timeout[i] = null;
}
for (var i in core.interval) { for (var i in core.interval) {
clearInterval(core.interval[i]); clearInterval(core.interval[i]);
core.interval[i] = null;
} }
// 初始化status // 初始化status
@ -1229,6 +1238,18 @@ core.prototype.ondown = function (x ,y) {
if (core.isset(core.status.replay)&&core.status.replay.replaying) return; if (core.isset(core.status.replay)&&core.status.replay.replaying) return;
if (!core.status.played || core.status.lockControl) { if (!core.status.played || core.status.lockControl) {
core.onclick(x, y, []); 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; return;
} }
@ -1271,6 +1292,12 @@ core.prototype.onmove = function (x ,y) {
////// 当点击(触摸)事件放开时 ////// ////// 当点击(触摸)事件放开时 //////
core.prototype.onup = function () { core.prototype.onup = function () {
if (core.isset(core.status.replay)&&core.status.replay.replaying) return; 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; // core.status.holdingPath=0;
if(core.status.stepPostfix.length>0){ if(core.status.stepPostfix.length>0){
var stepPostfix = []; 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) { 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 { else {
//posx,posy是寻路的目标点,stepPostfix是后续的移动 //posx,posy是寻路的目标点,stepPostfix是后续的移动

View File

@ -1,7 +1,7 @@
function events() { function events() {
} }
var eventdata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.events;
////// 初始化 ////// ////// 初始化 //////
events.prototype.init = function () { events.prototype.init = function () {
this.events = { this.events = {
@ -105,52 +105,16 @@ events.prototype.startGame = function (hard) {
} }
////// 不同难度分别设置初始属性 ////// ////// 不同难度分别设置初始属性 //////
events.prototype.setInitData = function (hard) { events.prototype.setInitData = eventdata.setInitData
if (hard=='Easy') { // 简单难度 // function (hard)
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.win = function(reason) { events.prototype.win = eventdata.win
core.ui.closePanel(); // function(reason)
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.lose = function(reason) { events.prototype.lose = eventdata.lose
core.ui.closePanel(); // function(reason)
var replaying = core.status.replay.replaying;
core.stopReplay();
core.waitHeroToStop(function() {
core.drawText([
"\t[结局1]你死了。\n如题。"
], function () {
core.events.gameOver(null, replaying);
});
})
}
////// 游戏结束 ////// ////// 游戏结束 //////
events.prototype.gameOver = function (ending, fromReplay) { events.prototype.gameOver = function (ending, fromReplay) {
@ -230,20 +194,8 @@ events.prototype.gameOver = function (ending, fromReplay) {
} }
////// 转换楼层结束的事件 ////// ////// 转换楼层结束的事件 //////
events.prototype.afterChangeFloor = function (floorId) { events.prototype.afterChangeFloor = eventdata.afterChangeFloor
if (core.isset(core.status.event.id)) return; // 当前存在事件 // function (floorId)
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.doEvents = function (list, x, y, callback) { events.prototype.doEvents = function (list, x, y, callback) {
@ -266,6 +218,8 @@ events.prototype.doEvents = function (list, x, y, callback) {
events.prototype.doAction = function() { events.prototype.doAction = function() {
// 清空boxAnimate和UI层 // 清空boxAnimate和UI层
core.status.boxAnimateObjs = []; core.status.boxAnimateObjs = [];
clearInterval(core.status.event.interval);
core.clearMap('ui', 0, 0, 416, 416); core.clearMap('ui', 0, 0, 416, 416);
core.setAlpha('ui', 1.0); core.setAlpha('ui', 1.0);
@ -301,7 +255,17 @@ events.prototype.doAction = function() {
if (core.status.replay.replaying) if (core.status.replay.replaying)
core.events.doAction(); core.events.doAction();
else 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; break;
case "setText": // 设置文本状态 case "setText": // 设置文本状态
if (data.position=='up'||data.position=='down'||data.position=='center') { if (data.position=='up'||data.position=='down'||data.position=='center') {
@ -316,6 +280,9 @@ events.prototype.doAction = function() {
if (core.isset(data.bold)) { if (core.isset(data.bold)) {
core.status.textAttribute.bold=data.bold; core.status.textAttribute.bold=data.bold;
} }
if (core.isset(data.time)) {
core.status.textAttribute.time=data.time;
}
core.events.doAction(); core.events.doAction();
break; break;
case "tip": case "tip":
@ -777,124 +744,16 @@ events.prototype.useItem = function(itemId) {
} }
////// 加点事件 ////// ////// 加点事件 //////
events.prototype.addPoint = function (enemy) { events.prototype.addPoint = eventdata.addPoint
var point = enemy.point; // function (enemy)
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.afterBattle = function(enemyId,x,y,callback) { events.prototype.afterBattle = eventdata.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.afterOpenDoor = function(doorId,x,y,callback) { events.prototype.afterOpenDoor = eventdata.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.passNet = function (data) { 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) { events.prototype.ski = function (direction) {
@ -1024,54 +882,20 @@ events.prototype.pushBox = function (data) {
} }
////// 推箱子后的事件 ////// ////// 推箱子后的事件 //////
events.prototype.afterPushBox = function () { events.prototype.afterPushBox = eventdata.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.afterUseBomb = function () { events.prototype.afterUseBomb = eventdata.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.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 () { events.prototype.longClick = function () {
core.waitHeroToStop(function () { if (core.status.event.id=='text') {
// 绘制快捷键 core.drawText();
core.ui.drawKeyBoard(); return true;
}); }
if (core.status.event.id=='action' && core.status.event.data.type=='text') {
this.doAction();
return true;
}
return false;
} }
////// 按下Ctrl键时快捷跳过对话 ////// ////// 按下Ctrl键时快捷跳过对话 //////
@ -2302,3 +2131,4 @@ events.prototype.clickAbout = function () {
core.showStartAnimate(); core.showStartAnimate();
} }
delete(eventdata);

View File

@ -4,7 +4,7 @@
* 自动寻路怪物手册楼传器存读档菜单栏NPC对话事件等等 * 自动寻路怪物手册楼传器存读档菜单栏NPC对话事件等等
*/ */
function ui() {} function ui() {}
var uidata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.ui;
// 初始化UI // 初始化UI
ui.prototype.init = function () { ui.prototype.init = function () {
} }
@ -15,6 +15,7 @@ main.instance.ui = new ui();
////// 结束一切事件和绘制关闭UI窗口返回游戏进程 ////// ////// 结束一切事件和绘制关闭UI窗口返回游戏进程 //////
ui.prototype.closePanel = function () { ui.prototype.closePanel = function () {
core.status.boxAnimateObjs = []; core.status.boxAnimateObjs = [];
clearInterval(core.status.event.interval);
core.clearMap('ui', 0, 0, 416, 416); core.clearMap('ui', 0, 0, 416, 416);
core.setAlpha('ui', 1.0); core.setAlpha('ui', 1.0);
core.unLockControl(); core.unLockControl();
@ -22,11 +23,14 @@ ui.prototype.closePanel = function () {
core.status.event.id = null; core.status.event.id = null;
core.status.event.selection = null; core.status.event.selection = null;
core.status.event.ui = null; core.status.event.ui = null;
core.status.event.interval = null;
} }
////// 绘制一个对话框 ////// ////// 绘制一个对话框 //////
ui.prototype.drawTextBox = function(content) { ui.prototype.drawTextBox = function(content) {
clearInterval(core.status.event.interval);
// 获得name, image, icon // 获得name, image, icon
var id=null, name=null, image=null, icon=null; var id=null, name=null, image=null, icon=null;
if (content.indexOf("\t[")==0 || content.indexOf("\\t[")==0) { 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; var top;
if (position=='center') { if (position=='center') {
top = (416 - height) / 2; top = parseInt((416 - height) / 2);
} }
else if (position=='up') { else if (position=='up') {
if (px==null || py==null) { 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++) { var drawContent = function (content) {
core.fillText('ui', contents[i], content_left, content_top, null, font);
content_top+=21; 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); 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 top = 140 - (lines-1)*30;
var right = 416 - 2 * left, bottom = 416 - 140 - top; 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; var len=core.canvas.ui.measureText("确定").width;
if (core.status.event.selection==0) { 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) { 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 text_length = core.canvas.ui.measureText(text).width;
var right = Math.max(text_length+50, 220); 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.fillRect('ui', left, top, right, bottom, background);
core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2); 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; var length = core.canvas.ui.measureText(page + " / " + page).width;
core.canvas.ui.textAlign = 'left'; 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'; core.canvas.ui.textAlign = 'center';
if (page > 1) if (page > 1)
@ -1231,7 +1250,7 @@ ui.prototype.drawSLPanel = function(index) {
core.setAlpha('ui', 1); core.setAlpha('ui', 1);
core.canvas.ui.textAlign = 'center'; core.canvas.ui.textAlign = 'center';
var u=416/6, size=117; var u=416/6, size=118;
var name=core.status.event.id=='save'?"存档":"读档"; var name=core.status.event.id=='save'?"存档":"读档";
for (var i=0;i<6;i++) { for (var i=0;i<6;i++) {
@ -1371,33 +1390,7 @@ ui.prototype.drawKeyBoard = function () {
} }
////// 绘制“关于”界面 ////// ////// 绘制“关于”界面 //////
ui.prototype.drawAbout = function() { ui.prototype.drawAbout = uidata.drawAbout
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.drawHelp = function () { ui.prototype.drawHelp = function () {
@ -1424,6 +1417,8 @@ ui.prototype.drawHelp = function () {
"点任意块并拖动: 指定寻路路线\n"+ "点任意块并拖动: 指定寻路路线\n"+
"单击勇士: 转向\n"+ "单击勇士: 转向\n"+
"双击勇士: 轻按(仅在轻按开关打开时有效)\n"+ "双击勇士: 轻按(仅在轻按开关打开时有效)\n"+
"长按任意位置:打开虚拟键盘" "长按任意位置:跳过剧情对话或打开虚拟键盘\n"
]); ]);
} }
delete(uidata)

35
main.js
View File

@ -17,6 +17,7 @@ function main() {
'startTopProgress': document.getElementById('startTopProgress'), 'startTopProgress': document.getElementById('startTopProgress'),
'startTopLoadTips': document.getElementById('startTopLoadTips'), 'startTopLoadTips': document.getElementById('startTopLoadTips'),
'startBackground': document.getElementById('startBackground'), 'startBackground': document.getElementById('startBackground'),
'startLogo': document.getElementById('startLogo'),
'startButtonGroup': document.getElementById('startButtonGroup'), 'startButtonGroup': document.getElementById('startButtonGroup'),
'floorMsgGroup': document.getElementById('floorMsgGroup'), 'floorMsgGroup': document.getElementById('floorMsgGroup'),
'logoLabel': document.getElementById('logoLabel'), 'logoLabel': document.getElementById('logoLabel'),
@ -33,9 +34,6 @@ function main() {
'loadGame': document.getElementById('loadGame'), 'loadGame': document.getElementById('loadGame'),
'replayGame': document.getElementById('replayGame'), 'replayGame': document.getElementById('replayGame'),
'levelChooseButtons': document.getElementById('levelChooseButtons'), 'levelChooseButtons': document.getElementById('levelChooseButtons'),
'easyLevel': document.getElementById('easyLevel'),
'normalLevel': document.getElementById('normalLevel'),
'hardLevel': document.getElementById('hardLevel'),
'data': document.getElementById('data'), 'data': document.getElementById('data'),
'statusLabels': document.getElementsByClassName('statusLabel'), 'statusLabels': document.getElementsByClassName('statusLabel'),
'floorCol': document.getElementById('floorCol'), 'floorCol': document.getElementById('floorCol'),
@ -52,7 +50,7 @@ function main() {
'items', 'icons', 'maps', 'enemys', 'events', 'data', 'ui', 'core' 'items', 'icons', 'maps', 'enemys', 'events', 'data', 'ui', 'core'
]; ];
this.pureData = [ this.pureData = [
"data","enemys","icons","maps","items" "data","enemys","icons","maps","items","functions"
]; ];
this.images = [ this.images = [
'animates', 'enemys', 'hero', 'items', 'npcs', 'terrains' 'animates', 'enemys', 'hero', 'items', 'npcs', 'terrains'
@ -128,6 +126,21 @@ main.prototype.init = function (mode) {
main.loadPureData(function(){ main.loadPureData(function(){
var mainData = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main; var mainData = data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main;
for(var ii in mainData)main[ii]=mainData[ii]; 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 () { main.loaderJs(function () {
var coreData = {}; var coreData = {};
for (i = 0; i < main.loadList.length; i++) { 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 }//listen end

View File

@ -7,7 +7,10 @@ data_comment_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"animates": " 在此存放所有可能使用的动画必须是animate格式在这里不写后缀名 \n 动画必须放在animates目录下文件名不能使用中文不能带空格或特殊字符 \n \"jianji\", \"thunder\" \n 根据需求自行添加 \n$leaf(true)$end", "animates": " 在此存放所有可能使用的动画必须是animate格式在这里不写后缀名 \n 动画必须放在animates目录下文件名不能使用中文不能带空格或特殊字符 \n \"jianji\", \"thunder\" \n 根据需求自行添加 \n$leaf(true)$end",
"bgms": " 在此存放所有的bgm和文件名一致。第一项为默认播放项 \n 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 \n$leaf(true)$end", "bgms": " 在此存放所有的bgm和文件名一致。第一项为默认播放项 \n 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 \n$leaf(true)$end",
"sounds": " 在此存放所有的SE和文件名一致 \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": { "firstData": {
"title": " 游戏名,将显示在标题页面以及切换楼层的界面中 ", "title": " 游戏名,将显示在标题页面以及切换楼层的界面中 ",

View File

@ -33,6 +33,10 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
// 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 // 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好
], ],
"bgmRemote" : false, // 是否使用远程的背景音乐;此项一般不要开启 "bgmRemote" : false, // 是否使用远程的背景音乐;此项一般不要开启
"startBackground" : "bg.png",// 标题界面的背景,建议使用jpg格式以压缩背景图空间
"startLogoStyle" : "color: black",// 标题样式:可以改变颜色,也可以隐藏标题(如果背景图自带)
"levelChoose" : [["简单","Easy"],["普通","Normal"],["困难","Hard"],["噩梦","Hell"]],
//难度选择:每个数组的第一个是其在标题界面显示的难度,第二个是在游戏内部传输的字符串,会显示在状态栏,修改此处后需要在project/functions中作相应更改
}, },
"firstData" : { "firstData" : {
"title": "魔塔样板", // 游戏名,将显示在标题页面以及切换楼层的界面中 "title": "魔塔样板", // 游戏名,将显示在标题页面以及切换楼层的界面中

View 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
View 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像素即可
}
}
}

View File

@ -4,10 +4,12 @@
同一个点的多事件处理(做法详见文档)。 同一个点的多事件处理(做法详见文档)。
增加新地图后可以接档而不用重新开始。 增加新地图后可以接档而不用重新开始。
增加可以接收用户输入的事件(type:input)。 增加可以接收用户输入的事件(type:input)。
滚动字幕;自动剧情文本。
可以同时show/hide多个事件。 可以同时show/hide多个事件。
现在可以支持滑冰和推箱子事件了。 现在可以支持滑冰和推箱子事件了。
地图中每个块的可通行方向控制(悬崖效果)。 地图中每个块的可通行方向控制(悬崖效果)。
动画支持带旋转和翻转的帧。 动画支持带旋转和翻转的帧。
长按屏幕可跳过对话。
现在可以允许用户丢弃道具了(例如不会再使用的装备)。 现在可以允许用户丢弃道具了(例如不会再使用的装备)。
修复行走时按键会发生动画抖动问题。 修复行走时按键会发生动画抖动问题。
修复无法打开战斗动画的Bug。 修复无法打开战斗动画的Bug。