diff --git a/.idea/mota-js.iml b/.idea/mota-js.xml
similarity index 100%
rename from .idea/mota-js.iml
rename to .idea/mota-js.xml
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 00000000..e145e12f
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,29 @@
+BSD 3-Clause License
+
+Copyright (c) 2018, Zhang Chen
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+* Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
index db47a83d..66428b22 100644
--- a/README.md
+++ b/README.md
@@ -45,6 +45,12 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
## 更新说明
+### 2018.1.12 V1.3.1
+
+* [x] 增加虚拟键盘
+* [x] 增加自动存档(回退),A键可快速读档
+* [x] 修复几处较为严重的Bug
+
### 2018.1.1 V1.3
* [x] 支持全键盘操作。
diff --git a/docs/api.md b/docs/api.md
index ebd28f99..092ad862 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -93,6 +93,7 @@ core.setAutoHeroMove // 设置勇士的自动行走路线
core.autoHeroMove // 让勇士开始自动行走
core.setHeroMoveInterval // 设置行走的效果动画
core.setHeroMoveTriggerInterval // 设置勇士行走过程中对事件的触发检测
+core.moveAction // 实际每一步的行走过程
* core.turnHero(direction) // 设置勇士的方向(转向)
core.canMoveHero // 勇士能否前往某方向
core.moveHero // 让勇士开始移动
@@ -178,16 +179,21 @@ core.clone // 深拷贝一个对象
core.formatDate // 格式化时间为字符串
core.setTwoDigits // 两位数显示
core.debug // 进入Debug模式,攻防血和钥匙都调成很高的数值
+core.replay // 开始回放
core.checkStatus // 判断当前能否进入某个事件
core.openBook // 点击怪物手册时的打开操作
core.useFly // 点击楼层传送器时的打开操作
core.openToolbox // 点击工具栏时的打开操作
+core.openQuickShop // 点击快捷商店时的打开操作
core.save // 点击保存按钮时的打开操作
core.load // 点击读取按钮时的打开操作
+core.openSettings // 点击设置按钮时的打开操作
core.doSL // 实际进行存读档事件
core.syncSave // 存档同步操作
core.saveData // 存档到本地
core.loadData // 从本地读档
+core.encodeRoute // 将路线压缩
+core.decodeRoute // 将路线解压缩
* core.setStatus // 设置勇士属性
* core.getStatus // 获得勇士属性
core.getLvName // 获得某个等级的名称
@@ -260,6 +266,7 @@ core.events.changeLight // 改变亮灯(感叹号)的事件
* core.events.afterLoadData // 读档事件后,载入事件前,可以执行的操作
// ------ 点击事件和键盘事件的处理 ------
+core.events.longClick // 长按
core.events.keyDownCtrl // 按下Ctrl键时(快捷跳过对话)
core.events.clickConfirmBox // 确认框界面时的点击操作
core.events.keyUpConfirmBox // 确认框界面时,放开某个键的操作
@@ -295,6 +302,7 @@ core.events.keyUpSettings // 系统菜单栏界面时,放开某个键的操作
core.events.clickSyncSave // 同步存档界面时的点击操作
core.events.keyDownSyncSave // 同步存档界面时,按下某个键的操作
core.events.keyUpSyncSave // 同步存档界面时,放开某个键的操作
+core.events.clickKeyBoard // 虚拟键盘界面时的点击操作
core.events.clickAbout // “关于”界面时的点击操作
```
diff --git a/docs/element.md b/docs/element.md
index ef764af5..21df84a9 100644
--- a/docs/element.md
+++ b/docs/element.md
@@ -142,10 +142,6 @@ floorId指定的是目标楼层的唯一标识符(ID)。
可以指定time,指定后切换动画时长为指定的数值。
-楼梯和传送门默认可`"穿透"`。所谓穿透,就是当寻路穿过一个楼梯/传送门后,不会触发楼层传送事件,而是继续前进。通过系统Flag可以指定是否穿透,你也可以对每个传送点单独设置该项。
-
-
-
## 背景音乐
本塔支持BGM和SE的播放。
@@ -190,12 +186,14 @@ this.sounds = [ // 在此存放所有的SE,和文件名一致
- **点任意块并拖动:** 指定寻路路线
- **单击勇士:** 转向
- **双击勇士:** 轻按(仅在轻按开关打开时有效)
+- **长按任意位置:** 打开虚拟键盘
键盘操作快捷键如下:
- **[CTRL]** 跳过对话
- **[X]** 打开/关闭怪物手册
- **[G]** 打开/关闭楼层传送器
+- **[A]** 读取自动存档
- **[S/D]** 打开/关闭存/读档页面
- **[K]** 打开/关闭快捷商店选择列表
- **[T]** 打开/关闭工具栏
diff --git a/docs/event.md b/docs/event.md
index 58d0917e..a694f731 100644
--- a/docs/event.md
+++ b/docs/event.md
@@ -465,6 +465,8 @@ direction为可选的,指定的话将使勇士的朝向变成该方向
time为可选的,指定的话将作为楼层切换动画的时间。
+**time也可以置为0,如果为0则没有楼层切换动画。**
+
!> **changeFloor到达一个新的楼层,将不会执行firstArrive事件!如有需求请在到达点设置自定义事件,然后使用type: trigger立刻调用之。**
### changePos: 当前位置切换/勇士转向
@@ -844,8 +846,9 @@ events.prototype.addPoint = function (enemy) {
全局商店定义在`data.js`中,找到shops一项。
``` js
-"shops": { // 定义全局商店(即快捷商店)
- "moneyShop1": { // 商店唯一ID
+"shops": [ // 定义全局商店(即快捷商店)
+ {
+ "id": "moneyShop1", // 商店唯一ID
"name": "贪婪之神", // 商店名称(标题)
"icon": "blueShop", // 商店图标,blueShop为蓝色商店,pinkShop为粉色商店
"textInList": "1F金币商店", // 在快捷商店栏中显示的名称
@@ -870,7 +873,8 @@ events.prototype.addPoint = function (enemy) {
// "status:hp+=2*(status:atk+status:def)" 将生命提升攻防和的数值的两倍
]
},
- "expShop1": { // 商店唯一ID
+ {
+ "id": "expShop1", // 商店唯一ID
"name": "经验之神",
"icon": "pinkShop",
"textInList": "1F经验商店",
@@ -885,15 +889,15 @@ events.prototype.addPoint = function (enemy) {
{"text": "攻击+5", "need": "30", "effect": "status:atk+=5"},
{"text": "防御+5", "need": "30", "effect": "status:def+=5"},
]
- },
-},
+ }
+],
```
-全局商店全部定义在`data.js`中的shops一项里。
-每个全局商店有一个唯一标识符(ID),然后是一系列对该商店的定义。
+全局商店全部定义在`data.js`中的shops一项里。商店以数组形式存放,每一个商店都是其中的一个对象。
+- id 为商店的唯一标识符(ID),请确保任何两个商店的id都不相同
- name 为商店的名称(打开商店后的标题)
-- icon 为商店的图标,blueShop为蓝色商店,pinkShop为粉色商店
+- icon 为商店的图标,在icons.js的npcs中定义。如woman可代表一个商人。
- textInList 为其在快捷商店栏中显示的名称,如"3楼金币商店"等
- use 为消耗的类型,是金币(money)还是经验(experience)。
- need 是一个表达式,计算商店所需要用到的数值。
diff --git a/images/terrains.png b/images/terrains.png
index 31ff78cf..15d492c3 100644
Binary files a/images/terrains.png and b/images/terrains.png differ
diff --git a/images/常用素材:如需使用请直接替换目录中的对应文件/animates0:经典.png b/images/常用素材:如需使用请直接替换目录中的对应文件/animates0:经典.png
new file mode 100644
index 00000000..c1c1cb1a
Binary files /dev/null and b/images/常用素材:如需使用请直接替换目录中的对应文件/animates0:经典.png differ
diff --git a/images/常用素材:如需使用请直接替换目录中的对应文件/animates1:旋转门.png b/images/常用素材:如需使用请直接替换目录中的对应文件/animates1:旋转门.png
new file mode 100644
index 00000000..3a6cdbb5
Binary files /dev/null and b/images/常用素材:如需使用请直接替换目录中的对应文件/animates1:旋转门.png differ
diff --git a/images/常用素材:如需使用请直接替换目录中的对应文件/items1:圆形宝石.png b/images/常用素材:如需使用请直接替换目录中的对应文件/items1:圆形宝石.png
deleted file mode 100644
index 7150fe9f..00000000
Binary files a/images/常用素材:如需使用请直接替换目录中的对应文件/items1:圆形宝石.png and /dev/null differ
diff --git a/images/常用素材:如需使用请直接替换目录中的对应文件/items1:方块宝石.png b/images/常用素材:如需使用请直接替换目录中的对应文件/items1:方块宝石.png
new file mode 100644
index 00000000..189b98eb
Binary files /dev/null and b/images/常用素材:如需使用请直接替换目录中的对应文件/items1:方块宝石.png differ
diff --git a/images/常用素材:如需使用请直接替换目录中的对应文件/宝石1.png b/images/常用素材:如需使用请直接替换目录中的对应文件/宝石1.png
new file mode 100644
index 00000000..d930ea4e
Binary files /dev/null and b/images/常用素材:如需使用请直接替换目录中的对应文件/宝石1.png differ
diff --git a/images/常用素材:如需使用请直接替换目录中的对应文件/宝石2.png b/images/常用素材:如需使用请直接替换目录中的对应文件/宝石2.png
new file mode 100644
index 00000000..4749c79d
Binary files /dev/null and b/images/常用素材:如需使用请直接替换目录中的对应文件/宝石2.png differ
diff --git a/images/常用素材:如需使用请直接替换目录中的对应文件/宝石3.png b/images/常用素材:如需使用请直接替换目录中的对应文件/宝石3.png
new file mode 100644
index 00000000..6a1d977a
Binary files /dev/null and b/images/常用素材:如需使用请直接替换目录中的对应文件/宝石3.png differ
diff --git a/images/常用素材:如需使用请直接替换目录中的对应文件/宝石4.png b/images/常用素材:如需使用请直接替换目录中的对应文件/宝石4.png
new file mode 100644
index 00000000..612e1efa
Binary files /dev/null and b/images/常用素材:如需使用请直接替换目录中的对应文件/宝石4.png differ
diff --git a/images/常用素材:如需使用请直接替换目录中的对应文件/旋转机关门.png b/images/常用素材:如需使用请直接替换目录中的对应文件/旋转机关门.png
new file mode 100644
index 00000000..ce9bc323
Binary files /dev/null and b/images/常用素材:如需使用请直接替换目录中的对应文件/旋转机关门.png differ
diff --git a/index.html b/index.html
index ae063d97..60b85214 100644
--- a/index.html
+++ b/index.html
@@ -32,7 +32,7 @@
开始游戏
载入游戏
- 关于本塔
+ 录像回放
简单
diff --git a/libs/core.js b/libs/core.js
index 145c6b9b..c53ecf52 100644
--- a/libs/core.js
+++ b/libs/core.js
@@ -45,6 +45,21 @@ function core() {
'playingBgm': null, // 正在播放的BGM
'isPlaying': false,
}
+ this.platform = {
+ 'isOnline': true, // 是否http
+ 'isPC': true, // 是否是PC
+ 'isAndroid': false, // 是否是Android
+ 'isIOS': false, // 是否是iOS
+ 'isWeChat': false, // 是否是微信
+ 'isQQ': false, // 是否是QQ
+ 'isChrome': false, // 是否是Chrome
+ 'supportCopy': false, // 是否支持复制到剪切板
+
+ 'fileInput': null, // FileInput
+ 'fileReader': null, // 是否支持FileReader
+ 'successCallback': null, // 读取成功
+ 'errorCallback': null, // 读取失败
+ }
// 样式
this.domStyle = {
styles: [],
@@ -78,8 +93,17 @@ function core() {
'stepPostfix': [],
'mouseOutCheck': 1,
'moveStepBeforeStop': [],
+ 'downTime': null,
- // 勇士状态;中心对称飞行器
+ // 路线&回放
+ 'route': [],
+ 'replay': {
+ 'replaying': false,
+ 'pausing': false,
+ 'animate': false, // 正在某段动画中
+ 'toReplay': [],
+ 'totalList': []
+ },
// event事件
'saveIndex': null,
@@ -129,7 +153,12 @@ core.prototype.init = function (dom, statusBar, canvas, images, pngs, bgms, soun
}
core.values = core.clone(core.data.values);
core.firstData = core.data.getFirstData();
- core.initStatus.shops = core.firstData.shops;
+
+ // core.initStatus.shops = core.firstData.shops;
+ core.firstData.shops.forEach(function (t) {
+ core.initStatus.shops[t.id] = t;
+ })
+
core.dom.versionLabel.innerHTML = core.firstData.version;
core.dom.logoLabel.innerHTML = core.firstData.title;
document.title = core.firstData.title + " - HTML5魔塔";
@@ -140,7 +169,8 @@ core.prototype.init = function (dom, statusBar, canvas, images, pngs, bgms, soun
core.material.icons = core.icons.getIcons();
core.material.events = core.events.getEvents();
- if (location.protocol.indexOf("http")==0) {
+ core.platform.isOnline = location.protocol.indexOf("http")==0;
+ if (core.platform.isOnline) {
window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext;
try {
core.musicStatus.audioContext = new window.AudioContext();
@@ -150,12 +180,55 @@ core.prototype.init = function (dom, statusBar, canvas, images, pngs, bgms, soun
}
}
- // 音效设置部分
- var isPC = true;
["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"].forEach(function (t) {
- if (navigator.userAgent.indexOf(t)>=0) isPC=false;
+ if (navigator.userAgent.indexOf(t)>=0) {
+ if (t=='iPhone' || t=='iPad' || t=='iPod') core.platform.isIOS = true;
+ if (t=='Android') core.platform.isAndroid=true;
+ core.platform.isPC=false;
+ }
});
- if (isPC) {
+
+ try {
+ core.platform.supportCopy = document.queryCommandSupported("copy");
+ }
+ catch (e) {
+ core.platform.supportCopy = false;
+ }
+
+ var chrome=/Chrome\/(\d+)\./.exec(navigator.userAgent);
+ if (core.isset(chrome) && parseInt(chrome[1])>=50)
+ core.platform.isChrome = true;
+ core.platform.isSafari = /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent);
+ core.platform.isQQ = /QQ/.test(navigator.userAgent);
+ core.platform.isWeChat = /MicroMessenger/.test(navigator.userAgent);
+
+ if (window.FileReader) {
+ core.platform.fileReader = new FileReader();
+ core.platform.fileReader.onload = function () {
+ var content=core.platform.fileReader.result;
+ var obj=null;
+ try {
+ obj=JSON.parse(content);
+ if (core.isset(obj)) {
+ if (core.isset(core.platform.successCallback))
+ core.platform.successCallback(obj);
+ return;
+ }
+ }
+ catch (e) {}
+ alert("不是有效的JSON文件!");
+
+ if (core.isset(core.platform.errorCallback))
+ core.platform.errorCallback();
+
+ };
+ core.platform.fileReader.onerror = function () {
+ if (core.isset(core.platform.errorCallback))
+ core.platform.errorCallback();
+ }
+ }
+
+ if (core.platform.isPC) {
// 如果是PC端直接加载
core.musicStatus.startDirectly = true;
}
@@ -174,7 +247,6 @@ core.prototype.init = function (dom, statusBar, canvas, images, pngs, bgms, soun
core.musicStatus.soundStatus = core.getLocalStorage('soundStatus', true);
core.setLocalStorage('soundStatus', core.musicStatus.soundStatus);
-
// switchs
core.flags.battleAnimate = core.getLocalStorage('battleAnimate', core.flags.battleAnimate);
core.flags.displayEnemyDamage = core.getLocalStorage('enemyDamage', core.flags.displayEnemyDamage);
@@ -442,7 +514,7 @@ core.prototype.clearStatus = function() {
}
////// 重置游戏状态和初始数据 //////
-core.prototype.resetStatus = function(hero, hard, floorId, maps) {
+core.prototype.resetStatus = function(hero, hard, floorId, route, maps) {
// 停止各个Timeout和Interval
for (var i in core.interval) {
@@ -460,8 +532,11 @@ core.prototype.resetStatus = function(hero, hard, floorId, maps) {
// 初始化人物属性
core.status.hero = core.clone(hero);
core.status.hard = hard;
+ // 初始化路线
+ if (core.isset(route))
+ core.status.route = route;
// 保存的Index
- core.status.saveIndex = core.getLocalStorage('saveIndex', 1);
+ core.status.saveIndex = core.getLocalStorage('saveIndex2', 1);
core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight);
}
@@ -470,12 +545,30 @@ core.prototype.resetStatus = function(hero, hard, floorId, maps) {
core.prototype.startGame = function (hard, callback) {
console.log('开始游戏');
- core.resetStatus(core.firstData.hero, hard, core.firstData.floorId, core.initStatus.maps);
+ core.resetStatus(core.firstData.hero, hard, core.firstData.floorId, null, core.initStatus.maps);
core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() {
core.setHeroMoveTriggerInterval();
if (core.isset(callback)) callback();
});
+
+
+ setTimeout(function () {
+ // Upload
+ var formData = new FormData();
+ formData.append('type', 'people');
+ formData.append('name', core.firstData.name);
+ formData.append('version', core.firstData.version);
+ formData.append('platform', core.platform.isPC?"PC":core.platform.isAndroid?"Android":core.platform.isIOS?"iOS":"");
+ formData.append('hard', hard);
+ formData.append('hardCode', core.getFlag('hard', 0));
+
+ var xhr = new XMLHttpRequest();
+ xhr.open("POST", "/games/upload.php");
+ xhr.send(formData);
+
+ })
+
}
////// 重新开始游戏;此函数将回到标题页面 //////
@@ -492,6 +585,7 @@ core.prototype.restart = function() {
////// 按下某个键时 //////
core.prototype.onkeyDown = function(e) {
+ if (core.isset(core.status.replay)&&core.status.replay.replaying) return;
if (!core.isset(core.status.holdingKeys))core.status.holdingKeys=[];
var isArrow={37:true,38:true,39:true,40:true}[e.keyCode]
if(isArrow && !core.status.lockControl){
@@ -509,6 +603,7 @@ core.prototype.onkeyDown = function(e) {
////// 放开某个键时 //////
core.prototype.onkeyUp = function(e) {
+ if (core.isset(core.status.replay)&&core.status.replay.replaying) return;
var isArrow={37:true,38:true,39:true,40:true}[e.keyCode]
if(isArrow && !core.status.lockControl){
for(var ii =0;ii0){
var stepPostfix = [];
@@ -842,8 +972,16 @@ core.prototype.onup = function () {
core.status.stepPostfix=[];
core.canvas.ui.clearRect(0, 0, 416,416);
core.canvas.ui.restore();
- core.onclick(posx,posy,stepPostfix);
- //posx,posy是寻路的目标点,stepPostfix是后续的移动
+
+ // 长按
+ if (!core.status.lockControl && stepPostfix.length==0 && core.status.downTime!=null && new Date()-core.status.downTime>=1000) {
+ core.events.longClick();
+ }
+ else {
+ //posx,posy是寻路的目标点,stepPostfix是后续的移动
+ core.onclick(posx,posy,stepPostfix);
+ }
+ core.status.downTime=null;
}
}
@@ -874,6 +1012,7 @@ core.prototype.getClickLoc = function (x, y) {
////// 具体点击屏幕上(x,y)点时,执行的操作 //////
core.prototype.onclick = function (x, y, stepPostfix) {
+ if (core.isset(core.status.replay)&&core.status.replay.replaying) return;
// console.log("Click: (" + x + "," + y + ")");
// 非游戏屏幕内
@@ -921,6 +1060,12 @@ core.prototype.onclick = function (x, y, stepPostfix) {
return;
}
+ // 查看地图
+ if (core.status.event.id == 'viewMaps') {
+ core.events.clickViewMaps(x,y);
+ return;
+ }
+
// 开关
if (core.status.event.id == 'switchs') {
core.events.clickSwitchs(x,y);
@@ -963,6 +1108,11 @@ core.prototype.onclick = function (x, y, stepPostfix) {
return;
}
+ if (core.status.event.id == 'keyBoard') {
+ core.events.clickKeyBoard(x,y);
+ return;
+ }
+
// 关于
if (core.status.event.id == 'about') {
core.events.clickAbout(x,y);
@@ -990,6 +1140,7 @@ core.prototype.onclick = function (x, y, stepPostfix) {
////// 滑动鼠标滚轮时的操作 //////
core.prototype.onmousewheel = function (direct) {
+ if (core.isset(core.status.replay)&&core.status.replay.replaying) return;
// 向下滚动是 -1 ,向上是 1
// 楼层飞行器
@@ -1001,15 +1152,15 @@ core.prototype.onmousewheel = function (direct) {
// 怪物手册
if (core.status.lockControl && core.status.event.id == 'book') {
- if (direct==1) core.ui.drawBook(core.status.event.data - 1);
- if (direct==-1) core.ui.drawBook(core.status.event.data + 1);
+ if (direct==1) core.ui.drawBook(core.status.event.data - 6);
+ if (direct==-1) core.ui.drawBook(core.status.event.data + 6);
return;
}
// 存读档
if (core.status.lockControl && (core.status.event.id == 'save' || core.status.event.id == 'load')) {
- if (direct==1) core.ui.drawSLPanel(core.status.event.data - 6);
- if (direct==-1) core.ui.drawSLPanel(core.status.event.data + 6);
+ if (direct==1) core.ui.drawSLPanel(core.status.event.data - 10);
+ if (direct==-1) core.ui.drawSLPanel(core.status.event.data + 10);
return;
}
}
@@ -1313,7 +1464,7 @@ core.prototype.stopAutoHeroMove = function () {
}
////// 设置勇士的自动行走路线 //////
-core.prototype.setAutoHeroMove = function (steps, start) {
+core.prototype.setAutoHeroMove = function (steps) {
if (steps.length == 0) {
return;
}
@@ -1366,6 +1517,8 @@ core.prototype.setHeroMoveInterval = function (direction, x, y, callback) {
core.moveOneStep();
if (core.status.heroStop)
core.drawHero(direction, core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');
+ clearInterval(core.interval.heroMoveInterval);
+ core.status.heroMoving = false;
if (core.isset(callback)) callback();
}
}, 12.5);
@@ -1373,73 +1526,80 @@ core.prototype.setHeroMoveInterval = function (direction, x, y, callback) {
////// 设置勇士行走过程中对事件的触发检测 //////
core.prototype.setHeroMoveTriggerInterval = function () {
- var direction, x, y;
+ core.interval.heroMoveTriggerInterval = window.setInterval(function () {
+ if (!core.status.heroStop) {
+ core.moveAction();
+ }
+ }, 50);
+}
+
+////// 实际每一步的行走过程 //////
+core.prototype.moveAction = function (callback) {
+ if (core.interval.openDoorAnimate!=null) return; // 开门判断
var scan = {
'up': {'x': 0, 'y': -1},
'left': {'x': -1, 'y': 0},
'down': {'x': 0, 'y': 1},
'right': {'x': 1, 'y': 0}
};
- core.interval.heroMoveTriggerInterval = window.setInterval(function () {
- if (!core.status.heroStop) {
- direction = core.getHeroLoc('direction');
- x = core.getHeroLoc('x');
- y = core.getHeroLoc('y');
- var noPass = core.noPass(x + scan[direction].x, y + scan[direction].y), canMove = core.canMoveHero();
- if (noPass || !canMove) {
- if (canMove) // 非箭头:触发
- core.trigger(x + scan[direction].x, y + scan[direction].y);
- core.drawHero(direction, x, y, 'stop');
- if (core.status.autoHeroMove) {
- core.status.movedStep++;
- if (core.status.destStep == core.status.movedStep) {
- core.status.autoHeroMove = false;
- core.status.destStep = 0;
- core.status.movedStep = 0;
- core.status.moveStepBeforeStop=[];
- core.stopAutomaticRoute();
- }
- }
- else {
- core.status.heroStop = true;
- }
- return;
+ var direction = core.getHeroLoc('direction');
+ var x = core.getHeroLoc('x');
+ var y = core.getHeroLoc('y');
+ var noPass = core.noPass(x + scan[direction].x, y + scan[direction].y), canMove = core.canMoveHero();
+ if (noPass || !canMove) {
+ core.status.route.push(direction);
+ if (canMove) // 非箭头:触发
+ core.trigger(x + scan[direction].x, y + scan[direction].y);
+ core.drawHero(direction, x, y, 'stop');
+ if (core.status.autoHeroMove) {
+ core.status.movedStep++;
+ if (core.status.destStep == core.status.movedStep) {
+ core.status.autoHeroMove = false;
+ core.status.destStep = 0;
+ core.status.movedStep = 0;
+ core.status.moveStepBeforeStop=[];
+ core.stopAutomaticRoute();
}
- core.setHeroMoveInterval(direction, x, y, function () {
- if (core.status.autoHeroMove) {
- core.status.movedStep++;
- if (core.status.destStep == core.status.movedStep) {
- core.status.autoHeroMove = false;
- core.status.destStep = 0;
- core.status.movedStep = 0;
- core.stopHero();
- core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');
- }
- }
- else if (core.status.heroStop) {
+ }
+ else {
+ core.status.heroStop = true;
+ }
+ if (core.isset(callback))
+ callback();
+ }
+ else {
+ core.setHeroMoveInterval(direction, x, y, function () {
+ if (core.status.autoHeroMove) {
+ core.status.movedStep++;
+ if (core.status.destStep == core.status.movedStep) {
+ core.status.autoHeroMove = false;
+ core.status.destStep = 0;
+ core.status.movedStep = 0;
+ core.stopHero();
core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');
}
- core.trigger(core.getHeroLoc('x'), core.getHeroLoc('y'));
- clearInterval(core.interval.heroMoveInterval);
- core.status.heroMoving = false;
- core.checkBlock();
- });
- }
- }, 50);
+ }
+ else if (core.status.heroStop) {
+ core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');
+ }
+ core.status.route.push(direction);
+ core.trigger(core.getHeroLoc('x'), core.getHeroLoc('y'));
+ core.checkBlock();
+ if (core.isset(callback)) callback();
+ });
+ }
}
-////// 设置勇士的方向(转向) //////
-core.prototype.turnHero = function(direction) {
- if (core.isset(direction)) {
- core.status.hero.loc.direction = direction;
- }
- else if (core.status.hero.loc.direction == 'up') core.status.hero.loc.direction = 'right';
+////// 转向 //////
+core.prototype.turnHero = function() {
+ if (core.status.hero.loc.direction == 'up') core.status.hero.loc.direction = 'right';
else if (core.status.hero.loc.direction == 'right') core.status.hero.loc.direction = 'down';
else if (core.status.hero.loc.direction == 'down') core.status.hero.loc.direction = 'left';
else if (core.status.hero.loc.direction == 'left') core.status.hero.loc.direction = 'up';
core.drawHero(core.status.hero.loc.direction, core.status.hero.loc.x, core.status.hero.loc.y, 'stop', 0, 0);
core.status.automaticRoutingTemp = {'destX': 0, 'destY': 0, 'moveStep': []};
core.canvas.ui.clearRect(0, 0, 416, 416);
+ core.status.route.push("turn");
}
////// 勇士能否前往某方向 //////
@@ -1452,8 +1612,6 @@ core.prototype.canMoveHero = function() {
if(nowIsArrow){
var nowArrow = nowId.slice(5).toLowerCase();
if (direction != nowArrow) {
- // core.status.heroStop = true;
- // core.turnHero(direction);
return false;
}
}
@@ -1472,8 +1630,6 @@ core.prototype.canMoveHero = function() {
if(isArrow){
var nextArrow = nextId.slice(5).toLowerCase();
if ( (scan[direction].x + scan[nextArrow].x) == 0 && (scan[direction].y + scan[nextArrow].y) == 0 ) {
- // core.status.heroStop = true;
- // core.turnHero(direction);
return false;
}
}
@@ -1482,9 +1638,17 @@ core.prototype.canMoveHero = function() {
}
////// 让勇士开始移动 //////
-core.prototype.moveHero = function (direction) {
- core.setHeroLoc('direction', direction);
- core.status.heroStop = false;
+core.prototype.moveHero = function (direction, callback) {
+ if (core.isset(direction))
+ core.setHeroLoc('direction', direction);
+ if (!core.isset(callback)) { // 如果不存在回调函数,则使用heroMoveTrigger
+ core.status.heroStop = false;
+ }
+ else { // 否则,只向某个方向移动一步,然后调用callback
+ core.moveAction(function () {
+ callback();
+ })
+ }
}
/////// 使用事件让勇士移动。这个函数将不会触发任何事件 //////
@@ -1521,11 +1685,14 @@ core.prototype.eventMoveHero = function(steps, time, callback) {
'right': {'x': 1, 'y': 0}
};
+ core.status.replay.animate=true;
+
var animate=window.setInterval(function() {
var x=core.getHeroLoc('x'), y=core.getHeroLoc('y');
if (moveSteps.length==0) {
clearInterval(animate);
core.drawHero(core.getHeroLoc('direction'), x, y, 'stop');
+ core.status.replay.animate=false;
if (core.isset(callback)) callback();
}
else {
@@ -1550,6 +1717,7 @@ core.prototype.eventMoveHero = function(steps, time, callback) {
////// 每移动一格后执行的事件 //////
core.prototype.moveOneStep = function() {
+ core.status.hero.steps++;
// 中毒状态
if (core.hasFlag('poison')) {
core.status.hero.hp -= core.values.poisonDamage;
@@ -1568,8 +1736,10 @@ core.prototype.waitHeroToStop = function(callback) {
core.stopAutomaticRoute();
core.clearContinueAutomaticRoute();
if (core.isset(callback)) {
+ core.status.replay.animate=true;
core.lockControl();
setTimeout(function(){
+ core.status.replay.animate=false;
core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');
callback();
}, 30);
@@ -1665,7 +1835,6 @@ core.prototype.openDoor = function (id, x, y, needKey, callback) {
core.drawTip("你没有" + core.material.items[key].name);
else core.drawTip("无法开启此门");
core.clearContinueAutomaticRoute();
- if (core.isset(callback)) callback();
return;
}
}
@@ -1678,12 +1847,14 @@ core.prototype.openDoor = function (id, x, y, needKey, callback) {
speed=100;
}
var door = core.material.icons.animates[doorId];
+ core.status.replay.animate=true;
core.interval.openDoorAnimate = window.setInterval(function () {
state++;
if (state == 4) {
clearInterval(core.interval.openDoorAnimate);
core.interval.openDoorAnimate=null;
core.removeBlock(x, y);
+ core.status.replay.animate=false;
core.events.afterOpenDoor(id,x,y,callback);
return;
}
@@ -1708,7 +1879,7 @@ core.prototype.battle = function (id, x, y, force, callback) {
core.clearContinueAutomaticRoute();
return;
}
- if (core.flags.battleAnimate) {
+ if (core.flags.battleAnimate&&!core.status.replay.replaying) {
core.waitHeroToStop(function() {
core.ui.drawBattleAnimate(id, function() {
core.afterBattle(id, x, y, callback);
@@ -1767,12 +1938,14 @@ core.prototype.trigger = function (x, y) {
if (core.isset(mapBlocks[b].event) && core.isset(mapBlocks[b].event.trigger)) {
var trigger = mapBlocks[b].event.trigger;
// 转换楼层能否穿透
+ /*
if (trigger=='changeFloor' && (core.status.autoHeroMove || core.status.autoStep1)
- core.status.checkBlock.damage[13*x+y] += parseInt((leftHp+1)/2);
+ core.status.checkBlock.damage[13*x+y] += parseInt((leftHp+(core.flags.betweenAttackCeil?0:1))/2);
}
}
}
@@ -2665,107 +2865,119 @@ core.prototype.checkBlock = function () {
////// 阻击事件(动画效果) //////
core.prototype.snipe = function (snipes) {
- core.waitHeroToStop(function() {
- core.lockControl();
- var scan = {
- 'up': {'x': 0, 'y': -1},
- 'left': {'x': -1, 'y': 0},
- 'down': {'x': 0, 'y': 1},
- 'right': {'x': 1, 'y': 0}
- };
+ var scan = {
+ 'up': {'x': 0, 'y': -1},
+ 'left': {'x': -1, 'y': 0},
+ 'down': {'x': 0, 'y': 1},
+ 'right': {'x': 1, 'y': 0}
+ };
- snipes.forEach(function (snipe) {
- var x=snipe.x, y=snipe.y, direction = snipe.direction;
- snipe.nx = x+scan[snipe.direction].x;
- snipe.ny = y+scan[snipe.direction].y;
+ snipes.forEach(function (snipe) {
+ var x=snipe.x, y=snipe.y, direction = snipe.direction;
+ snipe.nx = x+scan[snipe.direction].x;
+ snipe.ny = y+scan[snipe.direction].y;
- core.removeGlobalAnimate(x, y);
+ core.removeGlobalAnimate(x, y);
- var block = core.getBlock(x,y).block;
+ var block = core.getBlock(x,y).block;
- snipe.blockIcon = core.material.icons[block.event.cls][block.event.id];
- snipe.blockImage = core.material.images[block.event.cls];
- var damage = core.enemys.getDamage(block.event.id);
+ snipe.blockIcon = core.material.icons[block.event.cls][block.event.id];
+ snipe.blockImage = core.material.images[block.event.cls];
+ var damage = core.enemys.getDamage(block.event.id);
- var color = "#000000";
- if (damage <= 0) color = '#00FF00';
- else if (damage < core.status.hero.hp / 3) color = '#FFFFFF';
- else if (damage < core.status.hero.hp * 2 / 3) color = '#FFFF00';
- else if (damage < core.status.hero.hp) color = '#FF7F00';
- else color = '#FF0000';
+ var color = "#000000";
+ if (damage <= 0) color = '#00FF00';
+ else if (damage < core.status.hero.hp / 3) color = '#FFFFFF';
+ else if (damage < core.status.hero.hp * 2 / 3) color = '#FFFF00';
+ else if (damage < core.status.hero.hp) color = '#FF7F00';
+ else color = '#FF0000';
- if (damage >= 999999999) damage = "???";
- else if (damage > 100000) damage = (damage / 10000).toFixed(1) + "w";
+ if (damage >= 999999999) damage = "???";
+ else if (damage > 100000) damage = (damage / 10000).toFixed(1) + "w";
- snipe.damage = damage;
- snipe.color = color;
- snipe.block = core.clone(block);
- })
+ snipe.damage = damage;
+ snipe.color = color;
+ snipe.block = core.clone(block);
+ })
- var time = 500, step = 0;
+ var finishSnipe = function () {
+ snipes.forEach(function (t) {
+ core.removeBlock(t.x, t.y);
+ var nBlock = core.clone(t.block);
+ nBlock.x = t.nx; nBlock.y = t.ny;
+ core.status.thisMap.blocks.push(nBlock);
+ core.addGlobalAnimate(2, 32*t.nx, 32*t.ny, t.blockIcon, t.blockImage);
+ core.canvas.event.drawImage(t.blockImage, 0, t.blockIcon*32, 32, 32, 32*t.nx, 32*t.ny, 32, 32);
+ });
+ core.syncGlobalAnimate();
+ core.updateStatusBar();
+ return;
+ }
- var animateValue = 2;
- var animateCurrent = 0;
- var animateTime = 0;
+ if (core.status.replay.replaying) {
+ finishSnipe();
+ }
+ else {
+ core.waitHeroToStop(function() {
- core.canvas.fg.textAlign = 'left';
+ core.lockControl();
- var animate=window.setInterval(function() {
+ var time = 500, step = 0;
- step++;
- animateTime += time / 16;
- if (animateTime >= core.values.animateSpeed * 2 / animateValue) {
- animateCurrent++;
- animateTime = 0;
- if (animateCurrent>=animateValue) animateCurrent=0;
- }
+ var animateValue = 2;
+ var animateCurrent = 0;
+ var animateTime = 0;
- snipes.forEach(function (snipe) {
- var x=snipe.x, y=snipe.y, direction = snipe.direction;
+ core.canvas.fg.textAlign = 'left';
- var nowX=32*x+scan[direction].x*2*step, nowY=32*y+scan[direction].y*2*step;
+ var animate=window.setInterval(function() {
- // 清空上一次
- core.clearMap('event', nowX-2*scan[direction].x, nowY-2*scan[direction].y, 32, 32);
- core.clearMap('fg', nowX-2*scan[direction].x, nowY-2*scan[direction].y, 32, 32);
-
- core.canvas.event.drawImage(snipe.blockImage, animateCurrent*32, snipe.blockIcon*32, 32, 32, nowX, nowY, 32, 32);
-
- if (core.hasItem('book')) {
- // drawFG
- core.setFillStyle('fg', '#000000');
- core.canvas.fg.fillText(snipe.damage, nowX + 2, nowY + 30);
- core.canvas.fg.fillText(snipe.damage, nowX, nowY + 30);
- core.canvas.fg.fillText(snipe.damage, nowX + 2, nowY + 32);
- core.canvas.fg.fillText(snipe.damage, nowX, nowY + 32);
-
- core.setFillStyle('fg', snipe.color);
- core.canvas.fg.fillText(snipe.damage, nowX + 1, nowY + 31);
+ step++;
+ animateTime += time / 16;
+ if (animateTime >= core.values.animateSpeed * 2 / animateValue) {
+ animateCurrent++;
+ animateTime = 0;
+ if (animateCurrent>=animateValue) animateCurrent=0;
}
- })
+ snipes.forEach(function (snipe) {
+ var x=snipe.x, y=snipe.y, direction = snipe.direction;
- if (step==16) { // 移动完毕
- clearInterval(animate);
- snipes.forEach(function (t) {
- core.removeBlock(t.x, t.y);
- var nBlock = core.clone(t.block);
- nBlock.x = t.nx; nBlock.y = t.ny;
- core.status.thisMap.blocks.push(nBlock);
- core.addGlobalAnimate(animateValue, 32*t.nx, 32*t.ny, t.blockIcon, t.blockImage);
- });
- core.syncGlobalAnimate();
- core.updateStatusBar();
- // 不存在自定义事件
- if (core.status.event.id==null)
- core.unLockControl();
- }
- }, time/16);
+ var nowX=32*x+scan[direction].x*2*step, nowY=32*y+scan[direction].y*2*step;
+
+ // 清空上一次
+ core.clearMap('event', nowX-2*scan[direction].x, nowY-2*scan[direction].y, 32, 32);
+ core.clearMap('fg', nowX-2*scan[direction].x, nowY-2*scan[direction].y, 32, 32);
+
+ core.canvas.event.drawImage(snipe.blockImage, animateCurrent*32, snipe.blockIcon*32, 32, 32, nowX, nowY, 32, 32);
+
+ if (core.hasItem('book')) {
+ // drawFG
+ core.setFillStyle('fg', '#000000');
+ core.canvas.fg.fillText(snipe.damage, nowX + 2, nowY + 30);
+ core.canvas.fg.fillText(snipe.damage, nowX, nowY + 30);
+ core.canvas.fg.fillText(snipe.damage, nowX + 2, nowY + 32);
+ core.canvas.fg.fillText(snipe.damage, nowX, nowY + 32);
+
+ core.setFillStyle('fg', snipe.color);
+ core.canvas.fg.fillText(snipe.damage, nowX + 1, nowY + 31);
+ }
+
+ })
+
+ if (step==16) { // 移动完毕
+ clearInterval(animate);
+ finishSnipe();
+ // 不存在自定义事件
+ if (core.status.event.id==null)
+ core.unLockControl();
+ }
+ }, time/16);
+ });
+ }
-
- });
}
////// 更改画面色调 //////
@@ -2799,6 +3011,7 @@ core.prototype.setFg = function(color, time, callback) {
}
var step=0;
+ core.status.replay.animate=true;
var changeAnimate = setInterval(function() {
step++;
@@ -2817,6 +3030,7 @@ core.prototype.setFg = function(color, time, callback) {
if (step>=25) {
clearInterval(changeAnimate);
core.status.curtainColor = color;
+ core.status.replay.animate=false;
if (core.isset(callback)) callback();
}
}, time/25);
@@ -2936,8 +3150,8 @@ core.prototype.removeItem = function (itemId) {
}
////// 使用某个物品 //////
-core.prototype.useItem = function (itemId) {
- core.items.useItem(itemId);
+core.prototype.useItem = function (itemId, callback) {
+ core.items.useItem(itemId, callback);
return;
}
@@ -2969,6 +3183,7 @@ core.prototype.getNextItem = function() {
if (block==null) return;
if (block.block.event.trigger=='getItem') {
core.getItem(block.block.event.id, 1, nextX, nextY);
+ core.status.route.push("getNext");
}
}
@@ -3053,6 +3268,13 @@ core.prototype.drawTip = function (text, itemIcon) {
////// 地图中间绘制一段文字 //////
core.prototype.drawText = function (contents, callback) {
if (core.isset(contents)) {
+
+ // 合并
+ if (core.isset(core.status.event)&&core.status.event.id=='action') {
+ core.insertAction(contents,null,null,callback);
+ return;
+ }
+
if (typeof contents == 'string') {
contents = [{'content': contents}];
}
@@ -3232,6 +3454,13 @@ core.prototype.formatDate = function(date) {
+core.setTwoDigits(date.getHours())+":"+core.setTwoDigits(date.getMinutes())+":"+core.setTwoDigits(date.getSeconds());
}
+////// 格式化时间为最简字符串 //////
+core.prototype.formatDate2 = function (date) {
+ if (!core.isset(date)) return "";
+ return date.getFullYear()+core.setTwoDigits(date.getMonth()+1)+core.setTwoDigits(date.getDate())
+ +core.setTwoDigits(date.getHours())+core.setTwoDigits(date.getMinutes())+core.setTwoDigits(date.getSeconds());
+}
+
////// 两位数显示 //////
core.prototype.setTwoDigits = function (x) {
return parseInt(x)<10?"0"+x:x;
@@ -3257,6 +3486,121 @@ core.prototype.debug = function() {
core.drawTip("作弊成功");
}
+////// 回放 //////
+core.prototype.replay = function (list) {
+
+ if (core.isset(list) && (list instanceof Array)) {
+ core.status.replay.replaying=true;
+ core.status.replay.toReplay = core.clone(list);
+ this.replay();
+ return;
+ }
+
+ if (!core.status.replay.replaying) return; // 没有回放
+ if (core.status.replay.pausing) return; // 暂停状态
+ if (core.status.replay.animate) return; // 正在某段动画中
+
+ if (core.status.replay.toReplay.length==0) { // 回放完毕
+ core.status.replay.replaying=false;
+ core.insertAction("录像回放完毕!");
+ return;
+ }
+
+ var action=core.status.replay.toReplay.shift();
+
+ if (action=='up' || action=='down' || action=='left' || action=='right') {
+ core.moveHero(action, function () {
+ core.replay();
+ });
+ return;
+ }
+ else if (action.indexOf("item:")==0) {
+ var itemId = action.substring(5);
+ if (core.canUseItem(itemId)) {
+ var tools = Object.keys(core.status.hero.items.tools).sort();
+ var constants = Object.keys(core.status.hero.items.constants).sort();
+ var index;
+ if ((index=tools.indexOf(itemId))>=0 || (index=constants.indexOf(itemId)+100)>=100) {
+ core.ui.drawToolbox(index);
+ setTimeout(function () {
+ core.ui.closePanel();
+ core.useItem(itemId, function () {
+ core.replay();
+ });
+ }, 500);
+ }
+ return;
+ }
+ }
+ else if (action.indexOf("fly:")==0) {
+ var floorId=action.substring(4);
+ var toIndex=core.status.hero.flyRange.indexOf(floorId);
+ var nowIndex=core.status.hero.flyRange.indexOf(core.status.floorId);
+ if (core.hasItem('fly') && toIndex>=0 && nowIndex>=0) {
+ core.ui.drawFly(toIndex);
+ setTimeout(function () {
+ core.ui.closePanel();
+ var stair=toIndex0) {
+ var shop=core.status.shops[shopId];
+ if (core.isset(shop) && shop.visited) { // 商店可用
+ var choices = shop.choices;
+ var topIndex = 6 - parseInt(choices.length / 2);
+ core.events.openShop(shopId, false);
+ var shopInterval = setInterval(function () {
+ if (selections.length==0) {
+ clearInterval(shopInterval);
+ core.events.clickShop(6, topIndex+choices.length);
+ core.replay();
+ return;
+ }
+ var selection = parseInt(selections.shift());
+ if (isNaN(selection) || selection<0 || selection>=choices.length || !core.events.clickShop(6, topIndex+selection)) {
+ clearInterval(shopInterval);
+ core.status.replay.replaying=false;
+ core.drawTip("录像文件出错");
+ return;
+ }
+ }, 500);
+ return;
+ }
+ }
+ }
+ else if (action=='turn') {
+ core.turnHero();
+ core.replay();
+ return;
+ }
+ else if (action=='getNext') {
+ if (core.flags.enableGentleClick && core.getBlock(core.nextX(), core.nextY())!=null) {
+ var nextX = core.nextX(), nextY = core.nextY();
+ var block = core.getBlock(nextX, nextY);
+ if (block!=null && block.block.event.trigger=='getItem') {
+ core.getItem(block.block.event.id, 1, nextX, nextY);
+ core.status.route.push("getNext");
+ core.replay();
+ return;
+ }
+ }
+ }
+
+ core.status.replay.replaying=false;
+ core.insertAction("录像文件出错");
+
+}
+
////// 判断当前能否进入某个事件 //////
core.prototype.checkStatus = function (name, need, item) {
if (need && core.status.event.id == name) {
@@ -3282,6 +3626,7 @@ core.prototype.checkStatus = function (name, need, item) {
////// 点击怪物手册时的打开操作 //////
core.prototype.openBook = function (need) {
+ if (core.isset(core.status.replay)&&core.status.replay.replaying) return;
if (!core.checkStatus('book', need, true))
return;
core.useItem('book');
@@ -3289,6 +3634,7 @@ core.prototype.openBook = function (need) {
////// 点击楼层传送器时的打开操作 //////
core.prototype.useFly = function (need) {
+ if (core.isset(core.status.replay)&&core.status.replay.replaying) return;
if (!core.checkStatus('fly', need, true))
return;
if (core.flags.flyNearStair && !core.nearStair()) {
@@ -3311,43 +3657,80 @@ core.prototype.useFly = function (need) {
////// 点击工具栏时的打开操作 //////
core.prototype.openToolbox = function (need) {
+ if (core.isset(core.status.replay)&&core.status.replay.replaying) return;
if (!core.checkStatus('toolbox', need))
return;
core.ui.drawToolbox();
}
+////// 点击快捷商店按钮时的打开操作 //////
+core.prototype.openQuickShop = function (need) {
+ if (core.isset(core.status.replay)&&core.status.replay.replaying) return;
+ if (!core.checkStatus('selectShop', need))
+ return;
+ core.ui.drawQuickShop();
+}
+
////// 点击保存按钮时的打开操作 //////
core.prototype.save = function(need) {
+ if (core.isset(core.status.replay)&&core.status.replay.replaying) return;
if (!core.checkStatus('save', need))
return;
- core.ui.drawSLPanel(core.status.saveIndex);
+
+ var saveIndex = core.status.saveIndex;
+ var page=parseInt((saveIndex-1)/5), offset=saveIndex-5*page;
+
+ core.ui.drawSLPanel(10*page+offset);
}
////// 点击读取按钮时的打开操作 //////
core.prototype.load = function (need) {
+ if (core.isset(core.status.replay)&&core.status.replay.replaying) return;
+
+ var saveIndex = core.getLocalStorage('saveIndex2', 1);
+ var page=parseInt((saveIndex-1)/5), offset=saveIndex-5*page;
// 游戏开始前读档
if (!core.isPlaying()) {
core.status.event = {'id': 'load', 'data': null};
core.status.lockControl = true;
core.dom.startPanel.style.display = 'none';
- core.ui.drawSLPanel(core.getLocalStorage('saveIndex', 1));
+ core.ui.drawSLPanel(10*page+offset);
return;
}
if (!core.checkStatus('load', need))
return;
- core.ui.drawSLPanel(core.status.saveIndex);
+ core.ui.drawSLPanel(10*page+offset);
+}
+
+////// 点击设置按钮时的操作 //////
+core.prototype.openSettings = function (need) {
+ if (core.isset(core.status.replay)&&core.status.replay.replaying) return;
+ if (!core.checkStatus('settings', need))
+ return;
+ core.ui.drawSettings();
+}
+
+////// 自动存档 //////
+core.prototype.autosave = function () {
+ core.saveData("autoSave");
}
////// 实际进行存读档事件 //////
core.prototype.doSL = function (id, type) {
- core.status.saveIndex=id;
if (type=='save') {
+ if (id=='autoSave') {
+ core.drawTip('不能覆盖自动存档!');
+ return;
+ }
if (core.saveData("save"+id)) {
core.ui.closePanel();
core.drawTip('存档成功!');
- core.setLocalStorage('saveIndex', core.status.saveIndex);
+ if (id!="autoSave") {
+ core.status.saveIndex=id;
+ core.setLocalStorage('saveIndex2', core.status.saveIndex);
+ }
}
else {
core.drawTip('存储空间不足,请覆盖已有的存档或在菜单栏中进行清理');
@@ -3355,7 +3738,7 @@ core.prototype.doSL = function (id, type) {
return;
}
else if (type=='load') {
- var data = core.getLocalStorage("save"+id, null);
+ var data = core.getLocalStorage(id=='autoSave'?id:"save"+id, null);
if (!core.isset(data)) {
core.drawTip("无效的存档");
return;
@@ -3366,9 +3749,11 @@ core.prototype.doSL = function (id, type) {
}
core.ui.closePanel();
core.loadData(data, function() {
- core.status.saveIndex=id;
- core.setLocalStorage('saveIndex', core.status.saveIndex);
core.drawTip("读档成功");
+ if (id!="autoSave") {
+ core.status.saveIndex=id;
+ core.setLocalStorage('saveIndex2', core.status.saveIndex);
+ }
});
return;
}
@@ -3386,7 +3771,7 @@ core.prototype.syncSave = function(type) {
formData.append('type', 'save');
formData.append('name', core.firstData.name);
var saves = [];
- for (var i=1;i<=180;i++) {
+ for (var i=1;i<=150;i++) {
var data = core.getLocalStorage("save"+i, null);
if (core.isset(data)) {
saves.push(data);
@@ -3413,13 +3798,11 @@ core.prototype.syncSave = function(type) {
core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:HTTP "+xhr.status);
}
};
- xhr.ontimeout = function(e) {
- console.log(e);
- core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:"+e);
+ xhr.ontimeout = function() {
+ core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:Timeout");
}
- xhr.onerror = function(e) {
- console.log(e);
- core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:"+e);
+ xhr.onerror = function() {
+ core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:XHR Error");
}
xhr.send(formData);
}, function() {
@@ -3458,7 +3841,7 @@ core.prototype.syncSave = function(type) {
// 成功
var data=JSON.parse(response.msg);
// console.log(data);
- for (var i=1;i<=180;i++) {
+ for (var i=1;i<=150;i++) {
if (i<=data.length) {
core.setLocalStorage("save"+i, data[i-1]);
}
@@ -3483,11 +3866,11 @@ core.prototype.syncSave = function(type) {
core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:HTTP "+xhr.status);
}
};
- xhr.ontimeout = function(e) {
- core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:"+e);
+ xhr.ontimeout = function() {
+ core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:Timeout");
}
- xhr.onerror = function(e) {
- core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:"+e);
+ xhr.onerror = function() {
+ core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:XHR Error");
}
xhr.send(formData);
}, function() {
@@ -3505,6 +3888,7 @@ core.prototype.saveData = function(dataId) {
'hero': core.clone(core.status.hero),
'hard': core.status.hard,
'maps': core.maps.save(core.status.maps),
+ 'route': core.encodeRoute(core.status.route),
'shops': {},
'version': core.firstData.version,
"time": new Date().getTime()
@@ -3524,7 +3908,7 @@ core.prototype.saveData = function(dataId) {
////// 从本地读档 //////
core.prototype.loadData = function (data, callback) {
- core.resetStatus(data.hero, data.hard, data.floorId, core.maps.load(data.maps));
+ core.resetStatus(data.hero, data.hard, data.floorId, core.decodeRoute(data.route), core.maps.load(data.maps));
// load shop times
for (var shop in core.status.shops) {
@@ -3534,12 +3918,96 @@ core.prototype.loadData = function (data, callback) {
core.events.afterLoadData(data);
- core.changeFloor(data.floorId, null, data.hero.loc, null, function() {
+ core.changeFloor(data.floorId, null, data.hero.loc, 0, function() {
core.setHeroMoveTriggerInterval();
if (core.isset(callback)) callback();
});
}
+////// 加密路线 //////
+core.prototype.encodeRoute = function (route) {
+ var ans="";
+ var lastMove = "", cnt=0;
+
+ var items=Object.keys(core.material.items).sort();
+ var shops=Object.keys(core.initStatus.shops).sort();
+ route.forEach(function (t) {
+ if (t=='up' || t=='down' || t=='left' || t=='right') {
+ if (t!=lastMove && cnt>0) {
+ ans+=lastMove.substring(0,1).toUpperCase();
+ if (cnt>1) ans+=cnt;
+ cnt=0;
+ }
+ lastMove=t;
+ cnt++;
+ }
+ else {
+ if (cnt>0) {
+ ans+=lastMove.substring(0,1).toUpperCase();
+ if (cnt>1) ans+=cnt;
+ cnt=0;
+ }
+ if (t.indexOf('item:')==0)
+ ans+="I"+items.indexOf(t.substring(5));
+ else if (t.indexOf('fly:')==0)
+ ans+="F"+core.floorIds.indexOf(t.substring(4));
+ else if (t.indexOf('choices:')==0)
+ ans+="C"+t.substring(8);
+ else if (t.indexOf('shop:')==0) {
+ var sp=t.substring(5).split(":");
+ ans+="S"+shops.indexOf(sp[0])+":"+sp[1];
+ }
+ else if (t=='turn')
+ ans+='T';
+ else if (t=='getNext')
+ ans+='G';
+ }
+ });
+ if (cnt>0) {
+ ans+=lastMove.substring(0,1).toUpperCase();
+ if (cnt>1) ans+=cnt;
+ }
+ return ans;
+}
+
+////// 解密路线 //////
+core.prototype.decodeRoute = function (route) {
+
+ if (!core.isset(route)) return route;
+
+ var ans=[], index=0;
+
+ var getNumber = function (noparse) {
+ var num="";
+ while (index=0) && index= 5 && x <= 7) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
if (y>=topIndex && y0) {
if (keycode==38) {
core.status.event.selection--;
- if (core.status.event.selection<0) core.status.event.selection=0;
core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices);
}
if (keycode==40) {
core.status.event.selection++;
- if (core.status.event.selection>=choices.length) core.status.event.selection=choices.length-1;
core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices);
}
}
@@ -794,6 +948,7 @@ events.prototype.keyUpAction = function (keycode) {
var choices = data.choices;
if (choices.length>0) {
if (keycode==13 || keycode==32 || keycode==67) {
+ core.status.route.push("choices:"+core.status.event.selection);
this.insertAction(choices[core.status.event.selection].action);
this.doAction();
}
@@ -870,6 +1025,7 @@ events.prototype.clickFly = function(x,y) {
var index=core.status.hero.flyRange.indexOf(core.status.floorId);
var stair=core.status.event.data=8) {
+ core.ui.drawMaps(core.status.event.data-1);
+ }
+ else {
+ core.clearMap('data', 0, 0, 416, 416);
+ core.setOpacity('data', 1);
+ core.ui.closePanel();
+ }
+}
+
+////// 查看地图界面时,按下某个键的操作 //////
+events.prototype.keyDownViewMaps = function (keycode) {
+ if (keycode==37 || keycode==38) core.ui.drawMaps(core.status.event.data+1);
+ else if (keycode==39 || keycode==40) core.ui.drawMaps(core.status.event.data-1);
+ return;
+}
+
+////// 查看地图界面时,放开某个键的操作 //////
+events.prototype.keyUpViewMaps = function (keycode) {
+ if (keycode==27 || keycode==88 || keycode==13 || keycode==32 || keycode==67) {
+ core.clearMap('data', 0, 0, 416, 416);
+ core.setOpacity('data', 1);
+ core.ui.closePanel();
+ }
+ return;
+}
+
////// 商店界面时的点击操作 //////
events.prototype.clickShop = function(x,y) {
var shop = core.status.event.data.shop;
@@ -899,6 +1087,9 @@ events.prototype.clickShop = function(x,y) {
if (x >= 5 && x <= 7) {
var topIndex = 6 - parseInt(choices.length / 2);
if (y>=topIndex && y eval(use)) {
core.drawTip("你的"+use_text+"不足");
- return;
+ return false;
}
- eval(use+'-='+need);
+ core.status.event.data.actions.push(y-topIndex);
+ eval(use+'-='+need);
core.setStatus('money', money);
core.setStatus('experience', experience);
@@ -930,27 +1122,29 @@ events.prototype.clickShop = function(x,y) {
}
// 离开
else if (y==topIndex+choices.length) {
+ if (core.status.event.data.actions.length>0) {
+ core.status.route.push("shop:"+core.status.event.data.id+":"+core.status.event.data.actions.join(""));
+ }
+
core.status.boxAnimateObjs = [];
core.setBoxAnimate();
if (core.status.event.data.fromList)
core.ui.drawQuickShop();
else core.ui.closePanel();
}
+ else return false;
}
+ return true;
}
////// 商店界面时,按下某个键的操作 //////
events.prototype.keyDownShop = function (keycode) {
- var shop = core.status.event.data.shop;
- var choices = shop.choices;
if (keycode==38) {
core.status.event.selection--;
- if (core.status.event.selection<0) core.status.event.selection=0;
core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices);
}
if (keycode==40) {
core.status.event.selection++;
- if (core.status.event.selection>choices.length) core.status.event.selection=choices.length;
core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices);
}
}
@@ -982,7 +1176,7 @@ events.prototype.clickQuickShop = function(x, y) {
if (x >= 5 && x <= 7) {
var topIndex = 6 - parseInt(keys.length / 2);
if (y>=topIndex && ykeys.length) core.status.event.selection=keys.length;
core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices);
}
}
@@ -1141,13 +1332,17 @@ events.prototype.keyUpToolbox = function (keycode) {
////// 存读档界面时的点击操作 //////
events.prototype.clickSL = function(x,y) {
+
+ var index=core.status.event.data;
+ var page = parseInt(index/10), offset=index%10;
+
// 上一页
if ((x == 3 || x == 4) && y == 12) {
- core.ui.drawSLPanel(core.status.event.data - 6);
+ core.ui.drawSLPanel(10*(page-1)+offset);
}
// 下一页
if ((x == 8 || x == 9) && y == 12) {
- core.ui.drawSLPanel(core.status.event.data + 6);
+ core.ui.drawSLPanel(10*(page+1)+offset);
}
// 返回
if (x>=10 && x<=12 && y==12) {
@@ -1158,50 +1353,77 @@ events.prototype.clickSL = function(x,y) {
return;
}
- var page=parseInt((core.status.event.data-1)/6);
var index=6*page+1;
if (y>=1 && y<=4) {
- if (x>=1 && x<=3) core.doSL(index, core.status.event.id);
- if (x>=5 && x<=7) core.doSL(index+1, core.status.event.id);
- if (x>=9 && x<=11) core.doSL(index+2, core.status.event.id);
+ if (x>=1 && x<=3) core.doSL("autoSave", core.status.event.id);
+ if (x>=5 && x<=7) core.doSL(5*page+1, core.status.event.id);
+ if (x>=9 && x<=11) core.doSL(5*page+2, core.status.event.id);
}
if (y>=7 && y<=10) {
- if (x>=1 && x<=3) core.doSL(index+3, core.status.event.id);
- if (x>=5 && x<=7) core.doSL(index+4, core.status.event.id);
- if (x>=9 && x<=11) core.doSL(index+5, core.status.event.id);
+ if (x>=1 && x<=3) core.doSL(5*page+3, core.status.event.id);
+ if (x>=5 && x<=7) core.doSL(5*page+4, core.status.event.id);
+ if (x>=9 && x<=11) core.doSL(5*page+5, core.status.event.id);
}
}
////// 存读档界面时,按下某个键的操作 //////
events.prototype.keyDownSL = function(keycode) {
+
+ var index=core.status.event.data;
+ var page = parseInt(index/10), offset=index%10;
+
if (keycode==37) { // left
- core.ui.drawSLPanel(core.status.event.data - 1);
+ if (offset==0) {
+ core.ui.drawSLPanel(10*(page-1) + 5);
+ }
+ else {
+ core.ui.drawSLPanel(index - 1);
+ }
return;
}
if (keycode==38) { // up
- core.ui.drawSLPanel(core.status.event.data - 3);
+ if (offset<3) {
+ core.ui.drawSLPanel(10*(page-1) + offset + 3);
+ }
+ else {
+ core.ui.drawSLPanel(index - 3);
+ }
return;
}
if (keycode==39) { // right
- core.ui.drawSLPanel(core.status.event.data + 1);
+ if (offset==5) {
+ core.ui.drawSLPanel(10*(page+1)+1);
+ }
+ else {
+ core.ui.drawSLPanel(index + 1);
+ }
return;
}
if (keycode==40) { // down
- core.ui.drawSLPanel(core.status.event.data + 3);
+ if (offset>=3) {
+ core.ui.drawSLPanel(10*(page+1) + offset - 3);
+ }
+ else {
+ core.ui.drawSLPanel(index + 3);
+ }
return;
}
if (keycode==33) { // PAGEUP
- core.ui.drawSLPanel(core.status.event.data - 6);
+ core.ui.drawSLPanel(10*(page-1) + offset);
return;
}
if (keycode==34) { // PAGEDOWN
- core.ui.drawSLPanel(core.status.event.data + 6);
+ core.ui.drawSLPanel(10*(page+1) + offset);
return;
}
}
////// 存读档界面时,放开某个键的操作 //////
events.prototype.keyUpSL = function (keycode) {
+
+ var index=core.status.event.data;
+ var page = parseInt(index/10), offset=index%10;
+
if (keycode==27 || keycode==88 || (core.status.event.id == 'save' && keycode==83) || (core.status.event.id == 'load' && keycode==68)) {
core.ui.closePanel();
if (!core.isPlaying()) {
@@ -1210,7 +1432,12 @@ events.prototype.keyUpSL = function (keycode) {
return;
}
if (keycode==13 || keycode==32 || keycode==67) {
- core.doSL(core.status.event.data, core.status.event.id);
+ if (offset==0) {
+ core.doSL("autoSave", core.status.event.id);
+ }
+ else {
+ core.doSL(5*page+offset, core.status.event.id);
+ }
return;
}
}
@@ -1219,7 +1446,7 @@ events.prototype.keyUpSL = function (keycode) {
events.prototype.clickSwitchs = function (x,y) {
if (x<5 || x>7) return;
var choices = [
- "背景音乐", "背景音效", "战斗动画", "怪物显伤", "领域显伤", "返回主菜单"
+ "背景音乐", "背景音效", "战斗动画", "怪物显伤", "领域显伤", "下载离线版本", "返回主菜单"
];
var topIndex = 6 - parseInt((choices.length - 1) / 2);
if (y>=topIndex && y=choices.length) core.status.event.selection=choices.length-1;
core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices);
}
}
@@ -1290,11 +1515,11 @@ events.prototype.keyDownSwitchs = function (keycode) {
events.prototype.keyUpSwitchs = function (keycode) {
if (keycode==27 || keycode==88) {
core.status.event.selection=0;
- core.ui.drawSettings(false);
+ core.ui.drawSettings();
return;
}
var choices = [
- "背景音乐", "背景音效", "战斗动画", "怪物显伤", "领域显伤", "返回主菜单"
+ "背景音乐", "背景音效", "战斗动画", "怪物显伤", "领域显伤", "下载离线版本", "返回主菜单"
];
if (keycode==13 || keycode==32 || keycode==67) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
@@ -1307,7 +1532,7 @@ events.prototype.keyUpSwitchs = function (keycode) {
events.prototype.clickSettings = function (x,y) {
if (x<5 || x>7) return;
var choices = [
- "系统设置", "快捷商店", "同步存档", "重新开始", "操作帮助", "关于本塔", "返回游戏"
+ "系统设置", "快捷商店", "浏览地图", "同步存档", "重新开始", "数据统计", "操作帮助", "关于本塔", "返回游戏"
];
var topIndex = 6 - parseInt((choices.length - 1) / 2);
if (y>=topIndex && y0) {
+ text+="\n当前MAX为"+t.max+",最早由 "+(t.username||"匿名")+" 于"+core.formatDate(new Date(1000*t.timestamp))+"打出。";
+ }
+ })
+ core.drawText(text);
+ }
+ }
+ else {
+ core.drawText("出错啦!\n无法拉取统计信息。\n错误原因:HTTP "+xhr.status);
+ }
+ };
+ xhr.ontimeout = function() {
+ core.drawText("出错啦!\n无法拉取统计信息。\n错误原因:Timeout");
+ }
+ xhr.onerror = function() {
+ core.drawText("出错啦!\n无法拉取统计信息。\n错误原因:XHR Error");
+ }
+ xhr.send(formData);
break;
case 6:
+ core.ui.drawHelp();
+ break;
+ case 7:
+ core.ui.drawAbout();
+ break;
+ case 8:
core.ui.closePanel();
break;
}
@@ -1352,17 +1631,12 @@ events.prototype.clickSettings = function (x,y) {
////// 系统菜单栏界面时,按下某个键的操作 //////
events.prototype.keyDownSettings = function (keycode) {
- var choices = [
- "系统设置", "快捷商店", "同步存档", "重新开始", "操作帮助", "关于本塔", "返回游戏"
- ];
if (keycode==38) {
core.status.event.selection--;
- if (core.status.event.selection<0) core.status.event.selection=0;
core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices);
}
if (keycode==40) {
core.status.event.selection++;
- if (core.status.event.selection>=choices.length) core.status.event.selection=choices.length-1;
core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices);
}
}
@@ -1374,7 +1648,7 @@ events.prototype.keyUpSettings = function (keycode) {
return;
}
var choices = [
- "系统设置", "快捷商店", "同步存档", "重新开始", "操作帮助", "关于本塔", "返回游戏"
+ "系统设置", "快捷商店", "浏览地图", "同步存档", "重新开始", "数据统计", "操作帮助", "关于本塔", "返回游戏"
];
if (keycode==13 || keycode==32 || keycode==67) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
@@ -1386,7 +1660,7 @@ events.prototype.keyUpSettings = function (keycode) {
events.prototype.clickSyncSave = function (x,y) {
if (x<5 || x>7) return;
var choices = [
- "同步存档到服务器", "从服务器加载存档", "清空本地存档", "返回主菜单"
+ "同步存档到服务器", "从服务器加载存档", "存档至本地文件", "从本地文件读档", "清空所有存档", "返回主菜单"
];
var topIndex = 6 - parseInt((choices.length - 1) / 2);
if (y>=topIndex && y=choices.length) core.status.event.selection=choices.length-1;
core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices);
}
}
@@ -1439,11 +1751,11 @@ events.prototype.keyDownSyncSave = function (keycode) {
events.prototype.keyUpSyncSave = function (keycode) {
if (keycode==27 || keycode==88) {
core.status.event.selection=2;
- core.ui.drawSettings(false);
+ core.ui.drawSettings();
return;
}
var choices = [
- "同步存档到服务器", "从服务器加载存档", "清空本地存档", "返回主菜单"
+ "同步存档到服务器", "从服务器加载存档", "存档至本地文件", "从本地文件读档", "清空所有存档", "返回主菜单"
];
if (keycode==13 || keycode==32 || keycode==67) {
var topIndex = 6 - parseInt((choices.length - 1) / 2);
@@ -1451,6 +1763,65 @@ events.prototype.keyUpSyncSave = function (keycode) {
}
}
+////// “虚拟键盘”界面时的点击操作 //////
+events.prototype.clickKeyBoard = function (x, y) {
+ if (y==3 && x>=1 && x<=11) {
+ core.ui.closePanel();
+ core.keyUp(112+x-1); // F1-F12: 112-122
+ }
+ if (y==4 && x>=1 && x<=10) {
+ core.ui.closePanel();
+ core.keyUp(x==10?48:48+x); // 1-9: 49-57; 0: 48
+ }
+ // 字母
+ var lines = [
+ ["Q","W","E","R","T","Y","U","I","O","P"],
+ ["A","S","D","F","G","H","J","K","L"],
+ ["Z","X","C","V","B","N","M"],
+ ];
+ if (y==5 && x>=1 && x<=10) {
+ core.ui.closePanel();
+ core.keyUp(lines[0][x-1].charCodeAt(0));
+ }
+ if (y==6 && x>=1 && x<=9) {
+ core.ui.closePanel();
+ core.keyUp(lines[1][x-1].charCodeAt(0));
+ }
+ if (y==7 && x>=1 && x<=7) {
+ core.ui.closePanel();
+ core.keyUp(lines[2][x-1].charCodeAt(0));
+ }
+ if (y==8 && x>=1 && x<=11) {
+ core.ui.closePanel();
+ if (x==1) core.keyUp(189); // -
+ if (x==2) core.keyUp(187); // =
+ if (x==3) core.keyUp(219); // [
+ if (x==4) core.keyUp(221); // ]
+ if (x==5) core.keyUp(220); // \
+ if (x==6) core.keyUp(186); // ;
+ if (x==7) core.keyUp(222); // '
+ if (x==8) core.keyUp(188); // ,
+ if (x==9) core.keyUp(190); // .
+ if (x==10) core.keyUp(191); // /
+ if (x==11) core.keyUp(192); // `
+ }
+ if (y==9 && x>=1 && x<=10) {
+ core.ui.closePanel();
+ if (x==1) core.keyUp(27); // ESC
+ if (x==2) core.keyUp(9); // TAB
+ if (x==3) core.keyUp(20); // CAPS
+ if (x==4) core.keyUp(16); // SHIFT
+ if (x==5) core.keyUp(17); // CTRL
+ if (x==6) core.keyUp(18); // ALT
+ if (x==7) core.keyUp(32); // SPACE
+ if (x==8) core.keyUp(8); // BACKSPACE
+ if (x==9) core.keyUp(13); // ENTER
+ if (x==10) core.keyUp(46); // DEL
+ }
+ if (y==10 && x>=9 && x<=11)
+ core.ui.closePanel();
+}
+
////// “关于”界面时的点击操作 //////
events.prototype.clickAbout = function () {
if (core.isPlaying())
diff --git a/libs/floors/sample0.js b/libs/floors/sample0.js
index bbc54cd8..e4b65511 100644
--- a/libs/floors/sample0.js
+++ b/libs/floors/sample0.js
@@ -50,7 +50,6 @@ main.floors.sample0 = {
"\t[老人,womanMagician]这些是路障、楼梯、传送门。",
"\t[老人,womanMagician]血网的伤害数值、中毒后每步伤害数值、衰弱时攻防下降的数值,都在 data.js 内定义。\n\n路障同样会尽量被自动寻路绕过。",
"\t[老人,womanMagician]楼梯和传送门需要在changeFloor中定义目标楼层和位置,可参见样板里已有的的写法。",
- "\t[老人,womanMagician]楼梯和传送门是否可“穿透”,由data.js中的全局变量所决定,你也可以单独设置。\n穿透的意思是,自动寻路得到的路径中间经过了楼梯,行走时是否触发楼层转换事件。\n例如,下面的“下箭头”就是不能穿透的。",
{"type": "hide", "time": 500}
],
"2,8": [ // 守着第一批怪物的老人
@@ -75,7 +74,6 @@ main.floors.sample0 = {
{"type": "hide", "time": 500}
]
},
-
},
"changeFloor": { // 楼层转换事件;该事件不能和上面的events有冲突(同位置点),否则会被覆盖
"6,0": {"floorId": "sample1", "stair": "downFloor"}, // 目标点:sample1层的下楼梯位置
@@ -85,8 +83,8 @@ main.floors.sample0 = {
"2,12": {"floorId": "sample0", "loc": [2,12]},
"3,12": {"floorId": "sample0", "loc": [6,1], "direction": "up"}, // 切换楼层后勇士面对上方
"4,12": {"floorId": "sample0", "loc": [0,9], "direction": "left", "time": 1000}, // 切换楼层后勇士面对左边,切换动画1000ms
- "5,12": {"floorId": "sample0", "loc": [6,10], "portalWithoutTrigger": false}, // 不能穿透
- "6,12": {"floorId": "sample0", "loc": [10,10], "direction": "left", "time": 1000, "portalWithoutTrigger": false},
+ "5,12": {"floorId": "sample0", "loc": [6,10], "time": 0}, // time=0表示无切换时间
+ "6,12": {"floorId": "sample0", "loc": [10,10], "direction": "left", "time": 1000},
},
"afterBattle": { // 战斗后可能触发的事件列表
"2,6": ["\t[ghostSkeleton]不可能,你怎么可能打败我!\n(一个打败怪物触发的事件)"]
diff --git a/libs/icons.js b/libs/icons.js
index 4aced479..b8f9d206 100644
--- a/libs/icons.js
+++ b/libs/icons.js
@@ -14,23 +14,23 @@ icons.prototype.init = function () {
'ground': 0,
'grass': 1,
'grass2': 2,
- 'snowGround': 3,
- 'ground2': 4,
- 'ground3': 5,
- 'ground4': 6,
- 'sand': 7,
- 'ground5': 8,
- 'yellowWall2': 9,
- 'whiteWall2': 10,
- 'blueWall2': 11,
- 'blockWall': 12,
- 'grayWall': 13,
- 'white': 14,
- 'ground6': 15,
- 'soil': 16,
- 'yellowWall': 17,
- 'whiteWall': 18,
- 'blueWall': 19,
+ 'yellowWall': 3,
+ 'whiteWall': 4,
+ 'blueWall': 5,
+ 'snowGround': 6,
+ 'ground2': 7,
+ 'ground3': 8,
+ 'ground4': 9,
+ 'sand': 10,
+ 'ground5': 11,
+ 'yellowWall2': 12,
+ 'whiteWall2': 13,
+ 'blueWall2': 14,
+ 'blockWall': 15,
+ 'grayWall': 16,
+ 'white': 17,
+ 'ground6': 18,
+ 'soil': 19,
'star': 20,
'lava': 21,
'ice': 22,
diff --git a/libs/items.js b/libs/items.js
index 149fb395..d503e599 100644
--- a/libs/items.js
+++ b/libs/items.js
@@ -143,8 +143,11 @@ items.prototype.getItemEffectTip = function(itemId) {
}
////// 使用道具 //////
-items.prototype.useItem = function (itemId) {
- if (!this.canUseItem(itemId)) return;
+items.prototype.useItem = function (itemId, callback) {
+ if (!this.canUseItem(itemId)) {
+ if (core.isset(callback)) callback();
+ return;
+ }
var itemCls = core.material.items[itemId].cls;
if (itemId=='book') core.ui.drawBook(0);
@@ -174,6 +177,7 @@ items.prototype.useItem = function (itemId) {
// 上楼器/下楼器
core.changeFloor(core.status.event.data.id, null, {'direction': core.status.hero.loc.direction, 'x': core.status.event.data.x, 'y': core.status.event.data.y}, null, function (){
core.drawTip(core.material.items[itemId].name + "使用成功");
+ core.replay();
});
}
if (itemId == 'poisonWine') core.setFlag('poison', false);
@@ -193,11 +197,19 @@ items.prototype.useItem = function (itemId) {
core.setFlag('curse', false);
}
core.updateStatusBar();
+
+ // 记录路线
+ if (itemId!='book' && itemId!='fly') {
+ core.status.route.push("item:"+itemId);
+ }
+
// 道具使用完毕:删除
if (itemCls=='tools')
core.status.hero.items[itemCls][itemId]--;
if (core.status.hero.items[itemCls][itemId]==0)
delete core.status.hero.items[itemCls][itemId];
+
+ if (core.isset(callback)) callback();
}
////// 当前能否使用道具 //////
diff --git a/libs/maps.js b/libs/maps.js
index 1e9c72dc..36fb5a27 100644
--- a/libs/maps.js
+++ b/libs/maps.js
@@ -356,16 +356,7 @@ maps.prototype.load = function (data, floorId) {
}
////// 将当前地图重新变成二维数组形式 //////
-maps.prototype.getMapArray = function (maps, floorId){
- if (!core.isset(floorId)) {
- var map = {};
- for (var id in maps) {
- map[id] = this.getMapArray(maps, id);
- }
- return map;
- }
-
- var thisFloor = maps[floorId];
+maps.prototype.getMapArray = function (blockArray){
var blocks = [];
for (var x=0;x<13;x++) {
@@ -374,7 +365,7 @@ maps.prototype.getMapArray = function (maps, floorId){
blocks[x].push(0);
}
}
- thisFloor.blocks.forEach(function (block) {
+ blockArray.forEach(function (block) {
if (!(core.isset(block.enable) && !block.enable))
blocks[block.y][block.x] = block.id;
});
diff --git a/libs/ui.js b/libs/ui.js
index f3635f61..1b8217af 100644
--- a/libs/ui.js
+++ b/libs/ui.js
@@ -257,6 +257,8 @@ ui.prototype.drawChoices = function(content, choices) {
if (choices.length>0) {
if (!core.isset(core.status.event.selection)) core.status.event.selection=0;
+ if (core.status.event.selection<0) core.status.event.selection=0;
+ if (core.status.event.selection>=choices.length) core.status.event.selection=choices.length-1;
var len = core.canvas.ui.measureText(core.replaceText(choices[core.status.event.selection].text || choices[core.status.event.selection])).width;
core.strokeRect('ui', 208-len/2-5, choice_top + 32 * core.status.event.selection - 20, len+10, 28, "#FFD700", 2);
}
@@ -271,7 +273,8 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) {
core.status.event.data = {'yes': yesCallback, 'no': noCallback};
core.status.event.ui = text;
- if (!core.isset(core.status.event.selection)) core.status.event.selection=1;
+ if (!core.isset(core.status.event.selection) || core.status.event.selection>1) core.status.event.selection=1;
+ if (core.status.event.selection<0) core.status.event.selection=0;
var background = core.canvas.ui.createPattern(core.material.ground, "repeat");
core.clearMap('ui', 0, 0, 416, 416);
@@ -319,29 +322,26 @@ ui.prototype.drawSwitchs = function() {
var choices = [
"背景音乐:"+(core.musicStatus.bgmStatus ? "[ON]" : "[OFF]"),
"背景音效:"+(core.musicStatus.soundStatus ? "[ON]" : "[OFF]"),
- "战斗动画: " + (core.flags.battleAnimate ? "[ON]" : "[OFF]"),
- "怪物显伤: " + (core.flags.displayEnemyDamage ? "[ON]" : "[OFF]"),
- "领域显伤: " + (core.flags.displayExtraDamage ? "[ON]" : "[OFF]"),
+ "战斗动画: "+(core.flags.battleAnimate ? "[ON]" : "[OFF]"),
+ "怪物显伤: "+(core.flags.displayEnemyDamage ? "[ON]" : "[OFF]"),
+ "领域显伤: "+(core.flags.displayExtraDamage ? "[ON]" : "[OFF]"),
+ "下载离线版本",
"返回主菜单"
];
this.drawChoices(null, choices);
-
}
////// 绘制系统菜单栏 //////
-ui.prototype.drawSettings = function (need) {
- if (!core.checkStatus('settings', need))
- return;
+ui.prototype.drawSettings = function () {
+ core.status.event.id = 'settings';
this.drawChoices(null, [
- "系统设置", "快捷商店", "同步存档", "重新开始", "操作帮助", "关于本塔", "返回游戏"
+ "系统设置", "快捷商店", "浏览地图", "同步存档", "重新开始", "数据统计", "操作帮助", "关于本塔", "返回游戏"
]);
}
////// 绘制快捷商店选择栏 //////
-ui.prototype.drawQuickShop = function (need) {
- if (core.isset(need) && !core.checkStatus('selectShop', need))
- return;
+ui.prototype.drawQuickShop = function () {
core.status.event.id = 'selectShop';
@@ -654,12 +654,17 @@ ui.prototype.drawWaiting = function(text) {
core.setAlpha('ui', 1);
core.setFillStyle('ui', background);
- var left = 97, top = 208 - 32 - 16, right = 416 - 2 * left, bottom = 416 - 2 * top;
+ core.setFont('ui', 'bold 17px Verdana');
+ 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;
+
core.fillRect('ui', left, top, right, bottom, background);
core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2);
core.canvas.ui.textAlign = "center";
- core.fillText('ui', text, 208, top + 56, "#FFFFFF", "bold 17px Verdana");
+ core.fillText('ui', text, 208, top + 56, '#FFFFFF');
}
@@ -669,7 +674,7 @@ ui.prototype.drawSyncSave = function () {
core.status.event.id = 'syncSave';
this.drawChoices(null, [
- "同步存档到服务器", "从服务器加载存档", "清空本地存档", "返回主菜单"
+ "同步存档到服务器", "从服务器加载存档", "存档至本地文件", "从本地文件读档", "清空所有存档", "返回主菜单"
]);
}
@@ -902,6 +907,38 @@ ui.prototype.drawFly = function(page) {
this.drawThumbnail(floorId, 'ui', core.status.maps[floorId].blocks, 20, 100, 273);
}
+////// 绘制浏览地图界面 //////
+ui.prototype.drawMaps = function (index) {
+ if (!core.isset(index)) index=core.floorIds.indexOf(core.status.floorId);
+
+ if (index<0) index=0;
+ if (index>=core.floorIds.length) index=core.floorIds.length-1;
+
+ core.lockControl();
+ core.status.event.id = 'viewMaps';
+ core.status.event.data = index;
+
+ var floorId = core.floorIds[index];
+
+ clearTimeout(core.interval.tipAnimate);
+
+ core.clearMap('ui', 0, 0, 416, 416);
+ core.setAlpha('ui', 1);
+ this.drawThumbnail(floorId, 'ui', core.status.maps[floorId].blocks, 0, 0, 416);
+
+ core.clearMap('data', 0, 0, 416, 416);
+ core.setOpacity('data', 0.2);
+ core.canvas.data.textAlign = 'left';
+ core.setFont('data', '16px Arial');
+
+ var text = core.floors[floorId].title;
+ var textX = 16, textY = 18, width = textX + core.canvas.data.measureText(text).width + 16, height = 42;
+ core.fillRect('data', 5, 5, width, height, '#000');
+ core.setOpacity('data', 0.5);
+ core.fillText('data', text, textX + 5, textY + 15, '#fff');
+
+}
+
////// 绘制道具栏 //////
ui.prototype.drawToolbox = function(index) {
@@ -1020,16 +1057,15 @@ ui.prototype.drawToolbox = function(index) {
////// 绘制存档/读档界面 //////
ui.prototype.drawSLPanel = function(index) {
if (!core.isset(index)) index=1;
- if (index<=0) index=1;
- if (index>180) index=180;
+ if (index<0) index=0;
+
+ var page = parseInt(index/10), offset=index%10;
+ if (page>=30) page=29;
+ if (offset>5) offset=5;
+ index=10*page+offset;
core.status.event.data=index;
- var page=parseInt((index-1)/6);
-
- // core.status.event.data = page;
- // core.status.savePage = page;
-
core.clearMap('ui', 0, 0, 416, 416);
core.setAlpha('ui', 0.85);
core.fillRect('ui', 0, 0, 416, 416, '#000000');
@@ -1040,12 +1076,11 @@ ui.prototype.drawSLPanel = function(index) {
var name=core.status.event.id=='save'?"存档":"读档";
for (var i=0;i<6;i++) {
- var id=6*page+i+1;
- var data=core.getLocalStorage("save"+id,null);
-
+ var id=5*page+i;
+ var data=core.getLocalStorage(i==0?"autoSave":"save"+id, null);
if (i<3) {
- core.fillText('ui', name+id, (2*i+1)*u, 35, '#FFFFFF', "bold 17px Verdana");
- core.strokeRect('ui', (2*i+1)*u-size/2, 50, size, size, id==index?'#FFD700':'#FFFFFF', id==index?6:2);
+ core.fillText('ui', i==0?"自动存档":name+id, (2*i+1)*u, 35, '#FFFFFF', "bold 17px Verdana");
+ core.strokeRect('ui', (2*i+1)*u-size/2, 50, size, size, i==offset?'#FFD700':'#FFFFFF', i==offset?6:2);
if (core.isset(data) && core.isset(data.floorId)) {
this.drawThumbnail(data.floorId, 'ui', core.maps.load(data.maps, data.floorId).blocks, (2*i+1)*u-size/2, 50, size, data.hero.loc);
core.fillText('ui', core.formatDate(new Date(data.time)), (2*i+1)*u, 65+size, '#FFFFFF', '10px Verdana');
@@ -1057,7 +1092,7 @@ ui.prototype.drawSLPanel = function(index) {
}
else {
core.fillText('ui', name+id, (2*i-5)*u, 230, '#FFFFFF', "bold 17px Verdana");
- core.strokeRect('ui', (2*i-5)*u-size/2, 245, size, size, id==index?'#FFD700':'#FFFFFF', id==index?6:2);
+ core.strokeRect('ui', (2*i-5)*u-size/2, 245, size, size, i==offset?'#FFD700':'#FFFFFF', i==offset?6:2);
if (core.isset(data) && core.isset(data.floorId)) {
this.drawThumbnail(data.floorId, 'ui', core.maps.load(data.maps, data.floorId).blocks, (2*i-5)*u-size/2, 245, size, data.hero.loc);
core.fillText('ui', core.formatDate(new Date(data.time)), (2*i-5)*u, 260+size, '#FFFFFF', '10px Verdana');
@@ -1091,7 +1126,7 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroL
}
}
- var mapArray = core.maps.getMapArray(core.status.maps, floorId);
+ var mapArray = core.maps.getMapArray(blocks);
for (var b in blocks) {
var block = blocks[b];
if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable)) {
@@ -1116,6 +1151,44 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroL
}
}
+ui.prototype.drawKeyBoard = function () {
+ core.lockControl();
+ core.status.event.id = 'keyBoard';
+
+ core.clearMap('ui', 0, 0, 416, 416);
+
+ var left = 16, top = 48, right = 416 - 2 * left, bottom = 416 - 2 * top;
+ var background = core.canvas.ui.createPattern(core.material.ground, "repeat");
+ core.fillRect('ui', left, top, right, bottom, background);
+ core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2);
+
+ core.canvas.ui.textAlign = "center";
+ core.fillText('ui', "虚拟键盘", 208, top+35, "#FFD700", "bold 22px Verdana");
+
+ core.setFont('ui', '17px Verdana');
+ core.setFillStyle('ui', '#FFFFFF');
+ var offset = 128-9;
+
+ var lines = [
+ ["F1","F2","F3","F4","F5","F6","F7","F8","F9","10","11"],
+ ["1","2","3","4","5","6","7","8","9","0"],
+ ["Q","W","E","R","T","Y","U","I","O","P"],
+ ["A","S","D","F","G","H","J","K","L"],
+ ["Z","X","C","V","B","N","M"],
+ ["-","=","[","]","\\",";","'",",",".","/","`"],
+ ["ES","TA","CA","SH","CT","AL","SP","BS","EN","DE"]
+ ]
+
+ lines.forEach(function (line) {
+ for (var i=0;i