diff --git a/README.md b/README.md
index de1e27fa..7c524299 100644
--- a/README.md
+++ b/README.md
@@ -63,6 +63,20 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏!
## 更新说明
+### 2018.4.19 V2.1
+
+* [x] 编辑器添加新建和删除按钮;地图自动保存
+* [x] 录像支持倒退(录像播放中每20步存一个节点,最多30个)
+* [x] Gif支持:可以作为楼层背景图或者使用显示动图事件
+* [x] 图片显示增加淡入淡出效果
+* [x] APP端也能下载或读取文件
+* [x] 地图临界显伤
+* [x] 单个存档清理
+* [x] 大数据魔塔的支持
+* [x] 进一步对JS文件和图标进行压缩
+* [x] 修复有时候无法输入ID的问题
+* [x] 其他细节优化
+
### 2018.3.17 V2.0.1
* [x] 道具使用效果的进一步分离
diff --git a/index.html b/index.html
index bf967b87..32cb7037 100644
--- a/index.html
+++ b/index.html
@@ -43,43 +43,43 @@
-

+
-

+
-

+
-

+
-

+
-

+
-

+
-

+
-

+
-

+
@@ -94,13 +94,13 @@
diff --git a/libs/actions.js b/libs/actions.js
index c29d7f1a..af7224ef 100644
--- a/libs/actions.js
+++ b/libs/actions.js
@@ -35,11 +35,13 @@ actions.prototype.onkeyUp = function(e) {
if (e.keyCode==27) // ESCAPE
core.stopReplay();
else if (e.keyCode==90) // Z
- core.rewindReplay();
+ core.speedDownReplay();
else if (e.keyCode==88) // X
- core.forwardReplay();
+ core.speedUpReplay();
else if (e.keyCode==32) // SPACE
core.triggerReplay();
+ else if (e.keyCode==65) // A
+ core.rewindReplay();
return;
}
diff --git a/libs/control.js b/libs/control.js
index a4db300b..6a0e9cda 100644
--- a/libs/control.js
+++ b/libs/control.js
@@ -1379,6 +1379,8 @@ control.prototype.startReplay = function (list) {
core.status.replay.speed=1.0;
core.status.replay.toReplay = core.clone(list);
core.status.replay.totalList = core.clone(list);
+ core.status.replay.steps = 0;
+ core.status.replay.save = [];
core.updateStatusBar();
core.drawTip("开始播放");
this.replay();
@@ -1409,7 +1411,7 @@ control.prototype.resumeReplay = function () {
}
////// 加速播放 //////
-control.prototype.forwardReplay = function () {
+control.prototype.speedUpReplay = function () {
if (!core.status.replay.replaying) return;
core.status.replay.speed = parseInt(10*core.status.replay.speed + 1)/10;
if (core.status.replay.speed>3.0) core.status.replay.speed=3.0;
@@ -1417,7 +1419,7 @@ control.prototype.forwardReplay = function () {
}
////// 减速播放 //////
-control.prototype.rewindReplay = function () {
+control.prototype.speedDownReplay = function () {
if (!core.status.replay.replaying) return;
core.status.replay.speed = parseInt(10*core.status.replay.speed - 1)/10;
if (core.status.replay.speed<0.3) core.status.replay.speed=0.3;
@@ -1432,10 +1434,47 @@ control.prototype.stopReplay = function () {
core.status.replay.replaying=false;
core.status.replay.pausing=false;
core.status.replay.speed=1.0;
+ core.status.replay.steps = 0;
+ core.status.replay.save = [];
core.updateStatusBar();
core.drawTip("停止播放并恢复游戏");
}
+////// 回退 //////
+control.prototype.rewindReplay = function () {
+ if (!core.status.replay.replaying) return;
+ if (!core.status.replay.pausing) {
+ core.drawTip("请先暂停录像");
+ return;
+ }
+ if (core.status.replay.animate) {
+ core.drawTip("请等待当前事件的处理结束");
+ return;
+ }
+ if (core.status.replay.save.length==0) {
+ core.drawTip("无法再回到上一个节点");
+ return;
+ }
+
+ var save = core.status.replay.save;
+ var data = save.pop();
+ core.loadData(data.data, function () {
+ core.status.replay = {
+ "replaying": true,
+ "pausing": true,
+ "animate": false,
+ "toReplay": data.replay.toReplay,
+ "totalList": data.replay.totalList,
+ "speed": data.replay.speed,
+ "steps": data.replay.steps,
+ "save": save
+ }
+ core.updateStatusBar();
+ core.drawTip("成功回退到上一个节点");
+ })
+
+}
+
////// 回放 //////
control.prototype.replay = function () {
@@ -1449,6 +1488,18 @@ control.prototype.replay = function () {
return;
}
+ core.status.replay.steps++;
+ if (core.status.replay.steps%20==0) {
+ if (core.status.replay.save.length == 30)
+ core.status.replay.save.shift();
+ core.status.replay.save.push({"data": core.saveData(), "replay": {
+ "totalList": core.clone(core.status.replay.totalList),
+ "toReplay": core.clone(core.status.replay.toReplay),
+ "speed": core.status.replay.speed,
+ "steps": core.status.replay.steps
+ }});
+ }
+
var action=core.status.replay.toReplay.shift();
if (action=='up' || action=='down' || action=='left' || action=='right') {
@@ -1696,7 +1747,7 @@ control.prototype.autosave = function (removeLast) {
var x=null;
if (removeLast)
x=core.status.route.pop();
- core.saveData("autoSave");
+ core.setLocalStorage("autoSave", core.saveData())
if (removeLast && core.isset(x))
core.status.route.push(x);
}
@@ -1708,7 +1759,7 @@ control.prototype.doSL = function (id, type) {
core.drawTip('不能覆盖自动存档!');
return;
}
- if (core.saveData("save"+id)) {
+ if (core.setLocalStorage("save"+id, core.saveData())) {
core.ui.closePanel();
core.drawTip('存档成功!');
if (id!="autoSave") {
@@ -1868,7 +1919,7 @@ control.prototype.syncLoad = function () {
}
////// 存档到本地 //////
-control.prototype.saveData = function(dataId) {
+control.prototype.saveData = function() {
var data = {
'floorId': core.status.floorId,
'hero': core.clone(core.status.hero),
@@ -1888,7 +1939,7 @@ control.prototype.saveData = function(dataId) {
}
core.events.beforeSaveData(data);
- return core.setLocalStorage(dataId, data);
+ return data;
}
////// 从本地读档 //////
@@ -2133,15 +2184,15 @@ control.prototype.updateStatusBar = function () {
core.statusBar.image.fly.src = core.statusBar.icons.stop.src;
core.statusBar.image.fly.style.opacity = 1;
- //core.statusBar.image.toolbox.src = core.statusBar.icons.forward.src;
- core.statusBar.image.toolbox.style.opacity = 0;
+ core.statusBar.image.toolbox.src = core.statusBar.icons.rewind.src;
+ core.statusBar.image.toolbox.style.opacity = 1;
core.statusBar.image.shop.style.opacity = 0;
- core.statusBar.image.save.src = core.statusBar.icons.rewind.src;
+ core.statusBar.image.save.src = core.statusBar.icons.speedDown.src;
core.statusBar.image.save.style.opacity = 1;
- core.statusBar.image.load.src = core.statusBar.icons.forward.src;
+ core.statusBar.image.load.src = core.statusBar.icons.speedUp.src;
core.statusBar.image.load.style.opacity = 1;
core.statusBar.image.settings.style.opacity = 0;
diff --git a/libs/core.js b/libs/core.js
index a49f131d..ae680280 100644
--- a/libs/core.js
+++ b/libs/core.js
@@ -114,7 +114,9 @@ function core() {
'animate': false, // 正在某段动画中
'toReplay': [],
'totalList': [],
- 'speed': 1.0
+ 'speed': 1.0,
+ 'steps': 0,
+ 'save': [],
},
// event事件
@@ -252,7 +254,6 @@ core.prototype.init = function (coreData, callback) {
core.material.ground = new Image();
core.material.ground.src = "project/images/ground.png";
-
core.loader.load(function () {
console.log(core.material);
// 设置勇士高度
@@ -842,6 +843,11 @@ core.prototype.clone = function (data) {
return core.utils.clone(data);
}
+////// 裁剪图片 //////
+core.prototype.cropImage = function (image, size) {
+ return core.utils.cropImage(image, size);
+}
+
////// 格式化时间为字符串 //////
core.prototype.formatDate = function(date) {
return core.utils.formatDate(date);
@@ -893,11 +899,16 @@ core.prototype.resumeReplay = function () {
}
////// 加速播放 //////
-core.prototype.forwardReplay = function () {
- core.control.forwardReplay();
+core.prototype.speedUpReplay = function () {
+ core.control.speedUpReplay();
}
////// 减速播放 //////
+core.prototype.speedDownReplay = function () {
+ core.control.speedDownReplay();
+}
+
+////// 回退播放 //////
core.prototype.rewindReplay = function () {
core.control.rewindReplay();
}
@@ -973,8 +984,8 @@ core.prototype.syncLoad = function () {
}
////// 存档到本地 //////
-core.prototype.saveData = function(dataId) {
- return core.control.saveData(dataId);
+core.prototype.saveData = function() {
+ return core.control.saveData();
}
////// 从本地读档 //////
diff --git a/libs/events.js b/libs/events.js
index de85c843..823f8a43 100644
--- a/libs/events.js
+++ b/libs/events.js
@@ -123,6 +123,16 @@ events.prototype.lose = function (reason) {
////// 游戏结束 //////
events.prototype.gameOver = function (ending, fromReplay) {
+ // 清空图片和天气
+ core.clearMap('animate', 0, 0, 416, 416);
+ while (core.dom.gif2.firstChild)
+ core.dom.gif2.removeChild(core.dom.gif2.firstChild);
+ core.clearMap('weather', 0, 0, 416, 416)
+ core.animateFrame.weather.type = null;
+ core.animateFrame.weather.level = 0;
+ core.animateFrame.weather.nodes = [];
+ core.setFg(null, 0);
+
// 下载录像
var confirmDownload = function () {
core.ui.closePanel();
diff --git a/libs/loader.js b/libs/loader.js
index e93571d1..d5271bb2 100644
--- a/libs/loader.js
+++ b/libs/loader.js
@@ -23,6 +23,9 @@ loader.prototype.setStartLoadTipText = function (text) {
loader.prototype.load = function (callback) {
+ // 加载icons
+ core.loader.loadIcons();
+
// 加载图片
core.loader.loadImages(core.materials, core.material.images, function () {
// 加载png图片
@@ -40,6 +43,20 @@ loader.prototype.load = function (callback) {
})
}
+loader.prototype.loadIcons = function () {
+
+ this.loadImage("icons.png", function (id, image) {
+ var images = core.cropImage(image);
+ for (var key in core.statusBar.icons) {
+ if (typeof core.statusBar.icons[key] == 'number') {
+ core.statusBar.icons[key] = images[core.statusBar.icons[key]];
+ if (core.isset(core.statusBar.image[key]))
+ core.statusBar.image[key].src = core.statusBar.icons[key].src;
+ }
+ }
+ });
+}
+
loader.prototype.loadImages = function (names, toSave, callback) {
if (names.length==0) {
if (core.isset(callback)) callback();
diff --git a/libs/ui.js b/libs/ui.js
index 0c9425de..89802697 100644
--- a/libs/ui.js
+++ b/libs/ui.js
@@ -20,6 +20,8 @@ ui.prototype.clearMap = function (map, x, y, width, height) {
for (var m in core.canvas) {
core.canvas[m].clearRect(0, 0, 416, 416);
}
+ while (core.dom.gif.firstChild)
+ core.dom.gif.removeChild(core.dom.gif.firstChild);
}
else {
core.canvas[map].clearRect(x||0, y||0, width||416, height||416);
diff --git a/libs/utils.js b/libs/utils.js
index 34ff3517..c2de471b 100644
--- a/libs/utils.js
+++ b/libs/utils.js
@@ -126,6 +126,24 @@ utils.prototype.clone = function (data) {
return data;
}
+////// 裁剪图片 //////
+utils.prototype.cropImage = function (image, size) {
+ size = size||32;
+ var canvas = document.createElement("canvas");
+ var context = canvas.getContext("2d");
+ canvas.width = size;
+ canvas.height = size;
+ var ans = [];
+ for (var i=0;i