Replay Control

This commit is contained in:
oc 2018-01-25 01:56:00 +08:00
parent 6cba90599b
commit 32c9d58b65
9 changed files with 185 additions and 38 deletions

BIN
images/forward.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 B

BIN
images/pause.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

BIN
images/play.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

BIN
images/rewind.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

BIN
images/stop.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

View File

@ -102,7 +102,8 @@ function core() {
'pausing': false, 'pausing': false,
'animate': false, // 正在某段动画中 'animate': false, // 正在某段动画中
'toReplay': [], 'toReplay': [],
'totalList': [] 'totalList': [],
'speed': 1.0
}, },
// event事件 // event事件
@ -603,7 +604,18 @@ core.prototype.onkeyDown = function(e) {
////// 放开某个键时 ////// ////// 放开某个键时 //////
core.prototype.onkeyUp = function(e) { core.prototype.onkeyUp = function(e) {
if (core.isset(core.status.replay)&&core.status.replay.replaying) return; if (core.isset(core.status.replay)&&core.status.replay.replaying) {
if (e.keyCode==27) // ESCAPE
core.stopReplay();
else if (e.keyCode==90) // Z
core.rewindReplay();
else if (e.keyCode==88) // X
core.forwardReplay();
else if (e.keyCode==32) // SPACE
core.triggerReplay();
return;
}
var isArrow={37:true,38:true,39:true,40:true}[e.keyCode] var isArrow={37:true,38:true,39:true,40:true}[e.keyCode]
if(isArrow && !core.status.lockControl){ if(isArrow && !core.status.lockControl){
for(var ii =0;ii<core.status.holdingKeys.length;ii++){ for(var ii =0;ii<core.status.holdingKeys.length;ii++){
@ -859,7 +871,7 @@ core.prototype.keyUp = function(keyCode) {
core.events.setInitData(hard); core.events.setInitData(hard);
core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() { core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() {
core.setHeroMoveTriggerInterval(); core.setHeroMoveTriggerInterval();
core.replay(route); core.startReplay(route);
}); });
}, function () { }, function () {
core.ui.closePanel(); core.ui.closePanel();
@ -1528,7 +1540,7 @@ core.prototype.setHeroMoveInterval = function (direction, x, y, callback) {
core.status.heroMoving = false; core.status.heroMoving = false;
if (core.isset(callback)) callback(); if (core.isset(callback)) callback();
} }
}, 12.5); }, 12.5 / core.status.replay.speed);
} }
////// 设置勇士行走过程中对事件的触发检测 ////// ////// 设置勇士行走过程中对事件的触发检测 //////
@ -1719,7 +1731,7 @@ core.prototype.eventMoveHero = function(steps, time, callback) {
moveSteps.shift(); moveSteps.shift();
} }
} }
}, time/8); }, time / 8 / core.status.replay.speed)
} }
////// 每移动一格后执行的事件 ////// ////// 每移动一格后执行的事件 //////
@ -1964,7 +1976,7 @@ core.prototype.trigger = function (x, y) {
////// 楼层切换 ////// ////// 楼层切换 //////
core.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback) { core.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback) {
var displayAnimate=!(time==0); var displayAnimate=!(time==0) && !core.status.replay.replaying;
time = time || 800; time = time || 800;
time /= 20; time /= 20;
@ -2059,11 +2071,11 @@ core.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback)
else { else {
changed(); changed();
} }
}, 15) }, 25)
}); });
} }
if (displayAnimate) {
core.playSound('floor.mp3'); core.playSound('floor.mp3');
if (displayAnimate) {
core.mapChangeAnimate('show', time/2, function () { core.mapChangeAnimate('show', time/2, function () {
changing(); changing();
}); });
@ -2071,7 +2083,7 @@ core.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback)
else { else {
changing(); changing();
} }
}, 50); }, 25);
} }
////// 地图切换动画效果 ////// ////// 地图切换动画效果 //////
@ -2465,7 +2477,7 @@ core.prototype.moveBlock = function(x,y,steps,time,immediateHide,callback) {
var animate=window.setInterval(function() { var animate=window.setInterval(function() {
animateTime += time / 16; animateTime += time / 16 / core.status.replay.speed;
if (animateTime >= core.values.animateSpeed * 2 / animateValue) { if (animateTime >= core.values.animateSpeed * 2 / animateValue) {
animateCurrent++; animateCurrent++;
animateTime = 0; animateTime = 0;
@ -2502,7 +2514,7 @@ core.prototype.moveBlock = function(x,y,steps,time,immediateHide,callback) {
moveSteps.shift(); moveSteps.shift();
} }
} }
}, time/16); }, time / 16 / core.status.replay.speed);
} }
////// 显示/隐藏某个块时的动画效果 ////// ////// 显示/隐藏某个块时的动画效果 //////
@ -2547,7 +2559,7 @@ core.prototype.animateBlock = function (x,y,type,time,callback) {
core.status.replay.animate=false; core.status.replay.animate=false;
if (core.isset(callback)) callback(); if (core.isset(callback)) callback();
} }
}, time/10); }, time / 10 / core.status.replay.speed);
} }
////// 将某个块从禁用变成启用状态 ////// ////// 将某个块从禁用变成启用状态 //////
@ -3493,22 +3505,79 @@ core.prototype.debug = function() {
core.drawTip("作弊成功"); core.drawTip("作弊成功");
} }
////// 回放 ////// ////// 开始播放 //////
core.prototype.replay = function (list) { core.prototype.startReplay = function (list) {
if (core.isset(list) && (list instanceof Array)) {
core.status.replay.replaying=true; core.status.replay.replaying=true;
core.status.replay.pausing=false;
core.status.replay.speed=1.0;
core.status.replay.toReplay = core.clone(list); core.status.replay.toReplay = core.clone(list);
core.status.replay.totalList = core.clone(list);
core.updateStatusBar();
core.drawTip("开始播放");
this.replay(); this.replay();
return; return;
} }
////// 更改播放状态 //////
core.prototype.triggerReplay = function () {
if (core.status.replay.pausing) this.resumeReplay();
else this.pauseReplay();
}
////// 暂停播放 //////
core.prototype.pauseReplay = function () {
if (!core.status.replay.replaying) return;
core.status.replay.pausing = true;
core.updateStatusBar();
core.drawTip("暂停播放");
}
////// 恢复播放 //////
core.prototype.resumeReplay = function () {
if (!core.status.replay.replaying) return;
core.status.replay.pausing = false;
core.updateStatusBar();
core.drawTip("恢复播放");
core.replay();
}
////// 加速播放 //////
core.prototype.forwardReplay = function () {
if (!core.status.replay.replaying) return;
core.status.replay.speed = parseInt(10*core.status.replay.speed + 1)/10;
if (core.status.replay.speed>2.5) core.status.replay.speed=2.5;
core.drawTip("x"+core.status.replay.speed+"倍");
}
////// 减速播放 //////
core.prototype.rewindReplay = 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;
core.drawTip("x"+core.status.replay.speed+"倍");
}
////// 停止播放 //////
core.prototype.stopReplay = function () {
if (!core.status.replay.replaying) return;
core.status.replay.toReplay = [];
core.status.replay.totalList = [];
core.status.replay.replaying=false;
core.status.replay.pausing=false;
core.status.replay.speed=1.0;
core.updateStatusBar();
core.drawTip("停止播放并恢复游戏");
}
////// 回放 //////
core.prototype.replay = function () {
if (!core.status.replay.replaying) return; // 没有回放 if (!core.status.replay.replaying) return; // 没有回放
if (core.status.replay.pausing) return; // 暂停状态 if (core.status.replay.pausing) return; // 暂停状态
if (core.status.replay.animate) return; // 正在某段动画中 if (core.status.replay.animate) return; // 正在某段动画中
if (core.status.replay.toReplay.length==0) { // 回放完毕 if (core.status.replay.toReplay.length==0) { // 回放完毕
core.status.replay.replaying=false; core.stopReplay();
core.insertAction("录像回放完毕!"); core.insertAction("录像回放完毕!");
return; return;
} }
@ -3576,7 +3645,7 @@ core.prototype.replay = function (list) {
var selection = parseInt(selections.shift()); var selection = parseInt(selections.shift());
if (isNaN(selection) || selection<0 || selection>=choices.length || !core.events.clickShop(6, topIndex+selection)) { if (isNaN(selection) || selection<0 || selection>=choices.length || !core.events.clickShop(6, topIndex+selection)) {
clearInterval(shopInterval); clearInterval(shopInterval);
core.status.replay.replaying=false; core.stopReplay();
core.drawTip("录像文件出错"); core.drawTip("录像文件出错");
return; return;
} }
@ -3603,7 +3672,7 @@ core.prototype.replay = function (list) {
} }
} }
core.status.replay.replaying=false; core.stopReplay();
core.insertAction("录像文件出错"); core.insertAction("录像文件出错");
} }
@ -4111,6 +4180,7 @@ core.prototype.readFile = function (success, error) {
return; return;
} }
core.platform.fileReader.readAsText(core.platform.fileInput.files[0]); core.platform.fileReader.readAsText(core.platform.fileInput.files[0]);
core.platform.fileInput.value = '';
} }
} }
@ -4407,16 +4477,52 @@ core.prototype.updateStatusBar = function () {
} }
core.statusBar.hard.innerHTML = core.status.hard; core.statusBar.hard.innerHTML = core.status.hard;
if (core.hasItem('book')) {
// 回放
if (core.status.replay.replaying) {
core.statusBar.image.book.src = core.status.replay.pausing?core.statusBar.icons.play.src:core.statusBar.icons.pause.src;
core.statusBar.image.book.style.opacity = 1; core.statusBar.image.book.style.opacity = 1;
} else {
core.statusBar.image.book.style.opacity = 0.3; core.statusBar.image.fly.src = core.statusBar.icons.stop.src;
}
if (core.hasItem('fly')) {
core.statusBar.image.fly.style.opacity = 1; core.statusBar.image.fly.style.opacity = 1;
} else {
core.statusBar.image.fly.style.opacity = 0.3; //core.statusBar.image.toolbox.src = core.statusBar.icons.forward.src;
core.statusBar.image.toolbox.style.opacity = 0;
core.statusBar.image.shop.style.opacity = 0;
core.statusBar.image.save.src = core.statusBar.icons.rewind.src;
core.statusBar.image.save.style.opacity = 1;
core.statusBar.image.load.src = core.statusBar.icons.forward.src;
core.statusBar.image.load.style.opacity = 1;
core.statusBar.image.settings.style.opacity = 0;
} }
else {
core.statusBar.image.book.src = core.statusBar.icons.book.src;
core.statusBar.image.book.style.opacity = core.hasItem('book')?1:0.3;
core.statusBar.image.fly.src = core.statusBar.icons.fly.src;
core.statusBar.image.fly.style.opacity = core.hasItem('fly')?1:0.3;
core.statusBar.image.toolbox.src = core.statusBar.icons.toolbox.src;
core.statusBar.image.toolbox.style.opacity = 1;
core.statusBar.image.shop.style.opacity = 1;
core.statusBar.image.save.src = core.statusBar.icons.save.src;
core.statusBar.image.save.style.opacity = 1;
core.statusBar.image.load.src = core.statusBar.icons.load.src;
core.statusBar.image.load.style.opacity = 1;
core.statusBar.image.settings.src = core.statusBar.icons.settings.src;
core.statusBar.image.settings.style.opacity = 1;
}
core.updateFg(); core.updateFg();
} }

View File

@ -115,7 +115,7 @@ events.prototype.setInitData = function (hard) {
events.prototype.win = function(reason) { events.prototype.win = function(reason) {
core.ui.closePanel(); core.ui.closePanel();
var replaying = core.status.replay.replaying; var replaying = core.status.replay.replaying;
core.status.replay.replaying=false; core.stopReplay();
core.waitHeroToStop(function() { core.waitHeroToStop(function() {
core.removeGlobalAnimate(0,0,true); core.removeGlobalAnimate(0,0,true);
core.clearMap('all'); // 清空全地图 core.clearMap('all'); // 清空全地图
@ -131,9 +131,8 @@ events.prototype.win = function(reason) {
events.prototype.lose = function(reason) { events.prototype.lose = function(reason) {
core.ui.closePanel(); core.ui.closePanel();
var replaying = core.status.replay.replaying; var replaying = core.status.replay.replaying;
core.status.replay.replaying=false; core.stopReplay();
core.waitHeroToStop(function() { core.waitHeroToStop(function() {
core.status.replay.replaying=false;
core.drawText([ core.drawText([
"\t[结局1]你死了。\n如题。" "\t[结局1]你死了。\n如题。"
], function () { ], function () {
@ -481,7 +480,7 @@ events.prototype.doAction = function() {
}, 500) }, 500)
} }
else { else {
core.status.replay.replaying=false; core.stopReplay();
core.drawTip("录像文件出错"); core.drawTip("录像文件出错");
} }
} }
@ -1047,9 +1046,10 @@ events.prototype.clickFly = function(x,y) {
var index=core.status.hero.flyRange.indexOf(core.status.floorId); var index=core.status.hero.flyRange.indexOf(core.status.floorId);
var stair=core.status.event.data<index?"upFloor":"downFloor"; var stair=core.status.event.data<index?"upFloor":"downFloor";
var floorId=core.status.event.data; var floorId=core.status.event.data;
core.status.route.push("fly:"+core.status.hero.flyRange[floorId]); var toFloor = core.status.hero.flyRange[floorId];
core.changeFloor(core.status.hero.flyRange[floorId], stair); core.status.route.push("fly:"+toFloor);
core.ui.closePanel(); core.ui.closePanel();
core.changeFloor(toFloor, stair);
} }
return; return;
} }

View File

@ -267,7 +267,7 @@ main.floors.sample1 = {
value=parseInt(action.substring(6)); value=parseInt(action.substring(6));
} }
else { else {
core.status.replay.replaying=false; core.stopReplay();
core.drawTip("录像文件出错"); core.drawTip("录像文件出错");
return; return;
} }

43
main.js
View File

@ -95,6 +95,19 @@ function main() {
'load': document.getElementById("img-load"), 'load': document.getElementById("img-load"),
'settings': document.getElementById("img-settings") 'settings': document.getElementById("img-settings")
}, },
'icons': {
'book': null,
'fly': null,
'toolbox': null,
'save': null,
'load': null,
'settings': null,
'rewind': null, // 减速
'forward': null, // 加速
'play': null, // 播放
'pause': null, // 暂停
'stop': null, // 停止
},
'floor': document.getElementById('floor'), 'floor': document.getElementById('floor'),
'lv': document.getElementById('lv'), 'lv': document.getElementById('lv'),
'hp': document.getElementById('hp'), 'hp': document.getElementById('hp'),
@ -122,6 +135,11 @@ main.prototype.init = function () {
for (var i = 0; i < main.dom.gameCanvas.length; i++) { for (var i = 0; i < main.dom.gameCanvas.length; i++) {
main.canvas[main.dom.gameCanvas[i].id] = main.dom.gameCanvas[i].getContext('2d'); main.canvas[main.dom.gameCanvas[i].id] = main.dom.gameCanvas[i].getContext('2d');
} }
Object.keys(this.statusBar.icons).forEach(function (t) {
var image=new Image();
image.src="images/"+t+".png";
main.statusBar.icons[t] = image;
})
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++) {
@ -319,12 +337,23 @@ main.dom.data.ontouchend = function () {
////// 点击状态栏中的怪物手册时 ////// ////// 点击状态栏中的怪物手册时 //////
main.statusBar.image.book.onclick = function () { main.statusBar.image.book.onclick = function () {
if (core.isset(core.status.replay) && core.status.replay.replaying) {
core.triggerReplay();
return;
}
if (main.core.isPlaying()) if (main.core.isPlaying())
main.core.openBook(true); main.core.openBook(true);
} }
////// 点击状态栏中的楼层传送器时 ////// ////// 点击状态栏中的楼层传送器时 //////
main.statusBar.image.fly.onclick = function () { main.statusBar.image.fly.onclick = function () {
if (core.isset(core.status.replay) && core.status.replay.replaying) {
core.stopReplay();
return;
}
if (main.core.isPlaying()) if (main.core.isPlaying())
main.core.useFly(true); main.core.useFly(true);
} }
@ -343,12 +372,24 @@ main.statusBar.image.shop.onclick = function () {
////// 点击状态栏中的存档按钮时 ////// ////// 点击状态栏中的存档按钮时 //////
main.statusBar.image.save.onclick = function () { main.statusBar.image.save.onclick = function () {
if (core.isset(core.status.replay) && core.status.replay.replaying) {
core.rewindReplay();
return;
}
if (main.core.isPlaying()) if (main.core.isPlaying())
main.core.save(true); main.core.save(true);
} }
////// 点击状态栏中的读档按钮时 ////// ////// 点击状态栏中的读档按钮时 //////
main.statusBar.image.load.onclick = function () { main.statusBar.image.load.onclick = function () {
if (core.isset(core.status.replay) && core.status.replay.replaying) {
core.forwardReplay();
return;
}
if (main.core.isPlaying()) if (main.core.isPlaying())
main.core.load(true); main.core.load(true);
} }
@ -398,7 +439,7 @@ main.dom.replayGame.onclick = function () {
core.events.setInitData(obj.hard); core.events.setInitData(obj.hard);
core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() { core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() {
core.setHeroMoveTriggerInterval(); core.setHeroMoveTriggerInterval();
core.replay(core.decodeRoute(obj.route)); core.startReplay(core.decodeRoute(obj.route));
}); });
}, function () { }, function () {