From 46fc674b86a63e0a6184969420643ea8901511bd Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 4 Feb 2018 15:33:09 +0800 Subject: [PATCH] setRequestAnimationFrame --- docs/api.md | 1 - libs/core.js | 166 +++++++++++++++++++++++++++++++++++++++++-------- libs/events.js | 4 +- libs/ui.js | 12 ++-- 更新说明.txt | 1 + 5 files changed, 146 insertions(+), 38 deletions(-) diff --git a/docs/api.md b/docs/api.md index a47385d8..547bf871 100644 --- a/docs/api.md +++ b/docs/api.md @@ -148,7 +148,6 @@ core.addGlobalAnimate // 添加一个全局动画 core.removeGlobalAnimate // 删除一个或所有全局动画 core.setGlobalAnimate // 设置全局动画的显示效果 core.syncGlobalAnimate // 同步所有的全局动画效果 -core.setBoxAnimate // 显示UI层某个box的动画(如怪物手册中怪物的动画) core.drawBoxAnimate // 绘制UI层的box动画 core.updateCheckBlock // 更新领域、夹击、阻击的伤害地图 core.checkBlock // 检查并执行领域、夹击、阻击事件 diff --git a/libs/core.js b/libs/core.js index 4aabecdb..11470e07 100644 --- a/libs/core.js +++ b/libs/core.js @@ -28,14 +28,26 @@ function core() { 'turnHeroTimeout': null, } this.interval = { - 'twoAnimate': null, - 'fourAnimate': null, - 'boxAnimate': null, + //'twoAnimate': null, + //'fourAnimate': null, + //'boxAnimate': null, + //'twoTime': null, + //'fourTime': null, + //'boxTime': null, + //'globalAnimate': false, 'heroMoveTriggerInterval': null, 'heroMoveInterval': null, "tipAnimate": null, 'openDoorAnimate': null } + this.animateFrame = { + 'background': null, + 'globalAnimate': false, + 'twoTime': null, + 'fourTime': null, + 'boxTime': null, + 'speed': null, + } this.musicStatus = { 'audioContext': null, // WebAudioContext 'startDirectly': false, // 是否直接播放(加载)音乐 @@ -79,7 +91,7 @@ function core() { 'lockControl': false, // 勇士移动状态 - 'heroMoving': false, + 'heroMoving': 0, 'heroStop': true, // 自动寻路相关 @@ -268,10 +280,116 @@ core.prototype.init = function (dom, statusBar, canvas, images, pngs, bgms, soun // 设置勇士高度 core.material.icons.hero.height = core.material.images.hero.height/4; + core.setRequestAnimationFrame(); + core.showStartAnimate(); }); } +////// 设置requestAnimationFrame ////// +core.prototype.setRequestAnimationFrame = function () { + + (function() { + var lastTime = 0; + var vendors = ['webkit', 'moz']; + for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || // Webkit中此取消方法的名字变了 + window[vendors[x] + 'CancelRequestAnimationFrame']; + } + + if (!window.requestAnimationFrame) { + window.requestAnimationFrame = function(callback, element) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16.7 - (currTime - lastTime)); + var id = window.setTimeout(function() { + callback(currTime + timeToCall); + }, timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + } + if (!window.cancelAnimationFrame) { + window.cancelAnimationFrame = function(id) { + clearTimeout(id); + }; + } + }()); + + core.animateFrame.speed = core.values.animateSpeed; + core.animateFrame.background = core.canvas.ui.createPattern(core.material.ground, "repeat"); + + var scan = { + 'up': {'x': 0, 'y': -1}, + 'left': {'x': -1, 'y': 0}, + 'down': {'x': 0, 'y': 1}, + 'right': {'x': 1, 'y': 0} + }; + + var draw = function(timestamp) { + + core.animateFrame.twoTime = core.animateFrame.twoTime||timestamp; + core.animateFrame.fourTime = core.animateFrame.fourTime||timestamp; + core.animateFrame.boxTime = core.animateFrame.boxTime||timestamp; + + // Global Animate + if (core.animateFrame.globalAnimate && core.isPlaying()) { + + if (timestamp-core.animateFrame.twoTime>core.animateFrame.speed && core.isset(core.status.twoAnimateObjs)) { + + for (var a = 0; a < core.status.twoAnimateObjs.length; a++) { + var obj = core.status.twoAnimateObjs[a]; + obj.status = (obj.status+1)%2; + core.canvas.event.clearRect(obj.x, obj.y, 32, 32); + core.canvas.event.drawImage(obj.image, obj.status * 32, obj.loc * 32, 32, 32, obj.x, obj.y, 32, 32); + } + + core.animateFrame.twoTime = timestamp; + } + + if (timestamp-core.animateFrame.fourTime>core.animateFrame.speed/2 && core.isset(core.status.fourAnimateObjs)) { + for (var a = 0; a < core.status.fourAnimateObjs.length; a++) { + var obj=core.status.fourAnimateObjs[a]; + obj.status = (obj.status+1)%4; + core.canvas.event.clearRect(obj.x, obj.y, 32, 32); + core.canvas.event.drawImage(obj.image, obj.status * 32, obj.loc * 32, 32, 32, obj.x, obj.y, 32, 32); + } + // fourtime = timestamp % fourDelta; + core.animateFrame.fourTime = timestamp; + } + + } + + // Box + if (timestamp-core.animateFrame.boxTime>core.animateFrame.speed && core.isset(core.status.boxAnimateObjs) && core.status.boxAnimateObjs.length>0) { + core.drawBoxAnimate(); + core.animateFrame.boxTime = timestamp; + } + + // Hero move + if (core.status.heroMoving>0) { + var x=core.getHeroLoc('x'), y=core.getHeroLoc('y'), direction = core.getHeroLoc('direction'); + if (core.status.heroMoving<=4) { + core.drawHero(direction, x, y, 'leftFoot', 4*core.status.heroMoving*scan[direction].x, 4*core.status.heroMoving*scan[direction].y); + } + else if (core.status.heroMoving<=8) { + core.drawHero(direction, x, y, 'rightFoot', 4*core.status.heroMoving*scan[direction].x, 4*core.status.heroMoving*scan[direction].y); + } + } + + window.requestAnimationFrame(draw); + + } + + window.requestAnimationFrame(draw); + + + + +} + + + ////// 显示游戏开始界面 ////// core.prototype.showStartAnimate = function (callback) { core.dom.startPanel.style.opacity=1; @@ -1555,11 +1673,11 @@ core.prototype.setAutoHeroMove = function (steps) { ////// 设置行走的效果动画 ////// core.prototype.setHeroMoveInterval = function (direction, x, y, callback) { - if (core.status.heroMoving) { + if (core.status.heroMoving>0) { return; } - core.status.heroMoving = true; - var moveStep = 0; + // core.status.heroMoving = true; + // var moveStep = 0; var scan = { 'up': {'x': 0, 'y': -1}, 'left': {'x': -1, 'y': 0}, @@ -1567,22 +1685,25 @@ core.prototype.setHeroMoveInterval = function (direction, x, y, callback) { 'right': {'x': 1, 'y': 0} }; core.interval.heroMoveInterval = window.setInterval(function () { - moveStep++; + core.status.heroMoving++; + /* if (moveStep<=4) { core.drawHero(direction, x, y, 'leftFoot', 4*moveStep*scan[direction].x, 4*moveStep*scan[direction].y); } - else if (moveStep<=8) { + else if (moveStep<8) { core.drawHero(direction, x, y, 'rightFoot', 4*moveStep*scan[direction].x, 4*moveStep*scan[direction].y); } - if (moveStep==8) { + */ + if (core.status.heroMoving==8) { core.setHeroLoc('x', x+scan[direction].x); core.setHeroLoc('y', y+scan[direction].y); core.moveOneStep(); + core.clearMap('hero', 0, 0, 416, 416); core.drawHero(direction, core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); //if (core.status.heroStop) // core.drawHero(direction, core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); clearInterval(core.interval.heroMoveInterval); - core.status.heroMoving = false; + core.status.heroMoving = 0; if (core.isset(callback)) callback(); } }, 12.5 / core.status.replay.speed); @@ -2785,6 +2906,7 @@ core.prototype.removeGlobalAnimate = function (x, y, all) { ////// 设置全局动画的显示效果 ////// core.prototype.setGlobalAnimate = function (speed) { + /* clearInterval(core.interval.twoAnimate); clearInterval(core.interval.fourAnimate); var animateClose = false; @@ -2810,6 +2932,10 @@ core.prototype.setGlobalAnimate = function (speed) { animateClose = false; } }, speed / 2); + */ + core.syncGlobalAnimate(); + core.animateFrame.speed = speed; + core.animateFrame.globalAnimate = true; } ////// 同步所有的全局动画效果 ////// @@ -2822,25 +2948,13 @@ core.prototype.syncGlobalAnimate = function () { }) } -////// 显示UI层某个box的动画 ////// -core.prototype.setBoxAnimate = function () { - clearInterval(core.interval.boxAnimate); - if (core.status.boxAnimateObjs.length > 0) { - var background = core.canvas.ui.createPattern(core.material.ground, "repeat"); - core.drawBoxAnimate(background); - core.interval.boxAnimate = setInterval(function () { - core.drawBoxAnimate(background); - }, core.values.animateSpeed); - } -} - ////// 绘制UI层的box动画 ////// -core.prototype.drawBoxAnimate = function (background) { +core.prototype.drawBoxAnimate = function () { for (var a = 0; a < core.status.boxAnimateObjs.length; a++) { var obj = core.status.boxAnimateObjs[a]; - obj.status = obj.status == 0 ? 1 : 0; + obj.status = ((obj.status||0)+1)%2; core.clearMap('ui', obj.bgx, obj.bgy, obj.bgsize, obj.bgsize); - core.fillRect('ui', obj.bgx, obj.bgy, obj.bgsize, obj.bgsize, background); + core.fillRect('ui', obj.bgx, obj.bgy, obj.bgsize, obj.bgsize, core.animateFrame.background); core.canvas.ui.drawImage(obj.image, obj.status * 32, obj.icon * 32, 32, 32, obj.x, obj.y, 32, 32); } diff --git a/libs/events.js b/libs/events.js index 2588fb5a..74547ab0 100644 --- a/libs/events.js +++ b/libs/events.js @@ -254,7 +254,7 @@ events.prototype.doEvents = function (list, x, y, callback) { ////// 执行当前自定义事件列表中的下一个事件 ////// events.prototype.doAction = function() { // 清空boxAnimate和UI层 - clearInterval(core.interval.boxAnimate); + core.status.boxAnimateObjs = []; core.clearMap('ui', 0, 0, 416, 416); core.setAlpha('ui', 1.0); @@ -1152,7 +1152,6 @@ events.prototype.clickShop = function(x,y) { } core.status.boxAnimateObjs = []; - core.setBoxAnimate(); if (core.status.event.data.fromList) core.ui.drawQuickShop(); else core.ui.closePanel(); @@ -1182,7 +1181,6 @@ events.prototype.keyUpShop = function (keycode) { } core.status.boxAnimateObjs = []; - core.setBoxAnimate(); if (core.status.event.data.fromList) core.ui.drawQuickShop(); diff --git a/libs/ui.js b/libs/ui.js index f069f381..b00ca87d 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -15,7 +15,6 @@ main.instance.ui = new ui(); ////// 结束一切事件和绘制,关闭UI窗口,返回游戏进程 ////// ui.prototype.closePanel = function () { core.status.boxAnimateObjs = []; - core.setBoxAnimate(); core.clearMap('ui', 0, 0, 416, 416); core.setAlpha('ui', 1.0); core.unLockControl(); @@ -86,7 +85,6 @@ ui.prototype.drawTextBox = function(content) { core.setAlpha('ui', 1); core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2); core.status.boxAnimateObjs = []; - core.setBoxAnimate(); // 名称 core.canvas.ui.textAlign = "left"; @@ -114,7 +112,7 @@ ui.prototype.drawTextBox = function(content) { 'bgx': left + 15, 'bgy': top + 40, 'bgsize': 32, 'image': image, 'x': left + 15, 'y': top + 40, 'icon': icon }); - core.setBoxAnimate(); + core.drawBoxAnimate(); } } } @@ -237,7 +235,7 @@ ui.prototype.drawChoices = function(content, choices) { 'bgx': left + 15, 'bgy': top + 30, 'bgsize': 32, 'image': image, 'x': left + 15, 'y': top + 30, 'icon': icon }); - core.setBoxAnimate(); + core.drawBoxAnimate(); } } } @@ -442,7 +440,6 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) { core.setAlpha('data', 1); core.setOpacity('data', 1); core.status.boxAnimateObjs = []; - core.setBoxAnimate(); var margin = 35; var boxWidth = 40; @@ -473,7 +470,7 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) { 'bgx': left + right - margin - 40, 'bgy': top+margin, 'bgsize': boxWidth, 'image': core.material.images.enemys, 'x': left + right - margin - 40 + (boxWidth-32)/2, 'y': top + margin + (boxWidth-32)/2, 'icon': core.material.icons.enemys[monsterId] }); - core.setBoxAnimate(); + core.drawBoxAnimate(); var lineWidth = 80; @@ -636,7 +633,6 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) { // 战斗结束 clearInterval(battleInterval); core.status.boxAnimateObjs = []; - core.setBoxAnimate(); core.clearMap('ui', 0, 0, 416, 416); core.setAlpha('ui', 1.0); core.clearMap('data', 0, 0, 416, 416); @@ -863,7 +859,7 @@ ui.prototype.drawBook = function (index) { } } - core.setBoxAnimate(); + core.drawBoxAnimate(); this.drawPagination(page, totalPage); } diff --git a/更新说明.txt b/更新说明.txt index ca772251..8c4f7fab 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -6,6 +6,7 @@ 未成功打怪和开门则不自动存档。 重新支持楼梯穿透。 支持多结局,成绩将分开统计。 +重构勇士行走过程和事件检测,大幅提升性能。 修复所有已知Bug。 -----------------------------------------------------------------------