From 2f42a9402bcb8cdb3e1253c1618445757c173f47 Mon Sep 17 00:00:00 2001 From: oc Date: Fri, 15 Dec 2017 21:25:33 +0800 Subject: [PATCH] Battle --- .idea/markdown-navigator.xml | 72 +++++ .../markdown-navigator/profiles_settings.xml | 3 + docs/start.md | 6 +- libs/core.js | 31 ++- libs/data.js | 3 +- libs/enemys.js | 5 +- libs/events.js | 3 +- libs/floors/MT0.js | 1 + libs/floors/sample0.js | 4 +- libs/floors/sample1.js | 1 + libs/floors/sample2.js | 1 + libs/ui.js | 245 +++++++++++++++++- 12 files changed, 364 insertions(+), 11 deletions(-) create mode 100644 .idea/markdown-navigator.xml create mode 100644 .idea/markdown-navigator/profiles_settings.xml diff --git a/.idea/markdown-navigator.xml b/.idea/markdown-navigator.xml new file mode 100644 index 00000000..dbe0e461 --- /dev/null +++ b/.idea/markdown-navigator.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/markdown-navigator/profiles_settings.xml b/.idea/markdown-navigator/profiles_settings.xml new file mode 100644 index 00000000..57927c5a --- /dev/null +++ b/.idea/markdown-navigator/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/docs/start.md b/docs/start.md index d36dde90..b15063ee 100644 --- a/docs/start.md +++ b/docs/start.md @@ -8,7 +8,8 @@ - Windows 8以上操作系统;Windows 7需要安装.Net Framework 4.0。(能打开同目录下的“地图生成器.exe”即可) - 任一款现代浏览器。强烈推荐Chrome。 -- 一个很好的文本编辑器。推荐带有高亮染色、错误提示等效果。例如:WebStorm,VSCode,或者至少也要Sublime Text。[Sublime Text下载地址](https://www.sublimetext.com/ ),如提示注册的话百度随便搜索一个注册码输入即可。 +- 一个很好的文本编辑器。推荐带有高亮染色、错误提示等效果。例如:WebStorm,VSCode,或者至少也要Sublime Text。 +([VSCode下载地址](https://code.visualstudio.com/ ),群里的群文件中也有,强烈推荐值。) - RPG Maker XP,任一个魔塔样板(推荐魔塔样板7630) 只要满足了上述条件,你就可以开始做自己的塔啦! @@ -36,7 +37,8 @@ 然后,任意绘制一张地图。 -在这里我们就以1层小塔的地图为例。你也可以任意绘制自己的地图 +在这里我们就以1层小塔的地图为例。你也可以任意绘制自己的地图。 + ![绘制地图](./img/rmxp2.png) (我把原塔素材改成了经典样式,但是本质上是一样的。) diff --git a/libs/core.js b/libs/core.js index 75e03a49..d8dfd6ae 100644 --- a/libs/core.js +++ b/libs/core.js @@ -1262,8 +1262,21 @@ core.prototype.battle = function (id, x, y, force, callback) { core.clearContinueAutomaticRoute(); return; } - core.playSound('attack', 'ogg'); - core.status.hero.hp -= damage; + if (core.flags.battleAnimate) { + core.waitHeroToStop(function() { + core.ui.drawBattleAnimate(id, function() { + core.afterBattle(id, x, y, callback); + }); + }); + } + else { + core.playSound('attack', 'ogg'); + core.afterBattle(id, x, y, callback); + } +} + +core.prototype.afterBattle = function(id, x, y, callback) { + core.status.hero.hp -= core.enemys.getDamage(id); if (core.status.hero.hp<=0) { core.status.hero.hp=0; core.updateStatusBar(); @@ -1290,6 +1303,7 @@ core.prototype.battle = function (id, x, y, force, callback) { // 打完怪物,触发事件 core.events.afterBattle(id,x,y,callback); + } core.prototype.trigger = function (x, y) { @@ -1422,6 +1436,19 @@ core.prototype.strokeRect = function (map, x, y, width, height, style, lineWidth core.canvas[map].strokeRect(x, y, width, height); } +core.prototype.drawLine = function (map, x1, y1, x2, y2, style, lineWidth) { + if (core.isset(style)) { + core.setStrokeStyle(map, style); + } + if (core.isset(lineWidth)) { + core.setLineWidth(map, lineWidth); + } + core.canvas[map].beginPath(); + core.canvas[map].moveTo(x1, y1); + core.canvas[map].lineTo(x2, y2); + core.canvas[map].stroke(); +} + core.prototype.setFont = function (map, font) { core.canvas[map].font = font; } diff --git a/libs/data.js b/libs/data.js index d82a37b9..49b1f360 100644 --- a/libs/data.js +++ b/libs/data.js @@ -109,7 +109,6 @@ data.prototype.init = function() { "moneyPocket": 500, // 金钱袋加金币的数值 /****** 系统相关 ******/ - "cannotUseQuickShop": ["MT0"], // 不能使用快捷商店的楼层列表 'animateSpeed': 500, } // 系统FLAG,在游戏运行中中请不要修改它。 @@ -125,7 +124,7 @@ data.prototype.init = function() { "bigKeyIsBox": false, // 如果此项为true,则视为钥匙盒,红黄蓝钥匙+1;若为false,则视为大黄门钥匙 /****** 系统相关 ******/ - "startDirectly": true, // 点击“开始游戏”后是否立刻开始游戏而不显示难度选择界面 + "startDirectly": false, // 点击“开始游戏”后是否立刻开始游戏而不显示难度选择界面 "battleAnimate": true, // 是否默认显示战斗动画;用户可以手动在菜单栏中关闭 "portalWithoutTrigger": true, // 经过楼梯、传送门时是否能“穿透”。穿透的意思是,自动寻路得到的的路径中间经过了楼梯,行走时是否触发楼层转换事件 "potionWhileRouting": false, // 寻路算法是否经过血瓶;如果该项为false,则寻路算法会自动尽量绕过血瓶 diff --git a/libs/enemys.js b/libs/enemys.js index 062193d6..d71a4d7a 100644 --- a/libs/enemys.js +++ b/libs/enemys.js @@ -103,14 +103,17 @@ enemys.prototype.getDamage = function (monsterId) { var mon_hp = monster.hp, mon_atk = monster.atk, mon_def = monster.def, mon_special = monster.special; var damage = this.calDamage(hero_atk, hero_def, hero_mdef, mon_hp, mon_atk, mon_def, mon_special); if (damage == 999999999) return damage; + return damage + this.getExtraDamage(monster); +} +enemys.prototype.getExtraDamage = function (monster) { var extra_damage = 0; if (monster.special == 11) { // 吸血 // 吸血的比例 extra_damage = core.status.hero.hp * monster.value; extra_damage = parseInt(extra_damage); } - return damage + extra_damage; + return extra_damage; } // 临界值计算 diff --git a/libs/events.js b/libs/events.js index 898b09b4..12fe35d4 100644 --- a/libs/events.js +++ b/libs/events.js @@ -461,8 +461,9 @@ events.prototype.decreaseHard = function() { ////// 能否使用快捷商店 ////// events.prototype.canUseQuickShop = function(shopIndex) { - if (core.isset(core.values.cannotUseQuickShop) && core.values.cannotUseQuickShop.indexOf(core.status.floorId)>=0) + if (core.isset(core.floors[core.status.floorId].canUseQuickShop) && !core.isset(core.floors[core.status.floorId].canUseQuickShop)) return '当前不能使用快捷商店。'; + return null; } diff --git a/libs/floors/MT0.js b/libs/floors/MT0.js index 4bc81686..9d66ec6b 100644 --- a/libs/floors/MT0.js +++ b/libs/floors/MT0.js @@ -6,6 +6,7 @@ main.floors.MT0 = { "title": "主塔 0 层", // 楼层中文名 "name": 0, // 显示在状态栏中的层数 "canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) + "canUseQuickShop": true, // 该层是否允许使用快捷商店 "map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成 ], diff --git a/libs/floors/sample0.js b/libs/floors/sample0.js index 010428ab..a53520b8 100644 --- a/libs/floors/sample0.js +++ b/libs/floors/sample0.js @@ -6,6 +6,7 @@ main.floors.sample0 = { "title": "样板 0 层", // 楼层中文名 "name": 0, // 显示在状态栏中的层数 "canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) + "canUseQuickShop": true, // 该层是否允许使用快捷商店 "map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成 [0, 0, 220, 0, 0, 6, 87, 3, 65, 64, 44, 43, 42], [0, 246, 0, 246, 0, 6, 0, 3, 58, 59, 60, 61, 41], @@ -98,8 +99,7 @@ main.floors.sample0 = { ], "10,5": ["破墙镐是破面前的墙壁还是四个方向的墙壁,由data.js中的系统Flag所决定。"], "8,4": [ - "炸弹可以炸四个方向的怪物。\n如只需要炸前方怪物请使用上面的圣锤。", - "不能被炸的怪物在enemys中可以定义,可参见样板里黑衣魔王的写法。\n\n炸死怪物是否触发事件由 data.js 中的系统Flag所决定。" + "炸弹可以炸四个方向的怪物。\n如只需要炸前方怪物请使用上面的圣锤。\n不能被炸的怪物在enemys中可以定义,可参见样板里黑衣魔王和黑暗大法师的写法。", ], "10,4": ["“上楼”和“下楼”的目标层由 main.js 的 floorIds顺序所决定。"], "10,3": ["十字架目前未被定义,可能需要自行实现功能。\n有关如何实现一个道具功能参见doc文档。"], diff --git a/libs/floors/sample1.js b/libs/floors/sample1.js index d95d7703..ca1ae611 100644 --- a/libs/floors/sample1.js +++ b/libs/floors/sample1.js @@ -6,6 +6,7 @@ main.floors.sample1 = { "title": "样板 1 层", // 楼层中文名 "name": 1, // 显示在状态栏中的层数 "canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) + "canUseQuickShop": true, // 该层是否允许使用快捷商店 "map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成 [7, 131, 8, 2, 9, 130, 10, 2, 0, 0, 132, 0, 0], [0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0], diff --git a/libs/floors/sample2.js b/libs/floors/sample2.js index a6327e1d..b0bc470d 100644 --- a/libs/floors/sample2.js +++ b/libs/floors/sample2.js @@ -6,6 +6,7 @@ main.floors.sample2 = { "title": "主塔 40 层", // 楼层中文名 "name": 40, // 显示在状态栏中的层数 "canFlyTo": false, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) + "canUseQuickShop": true, // 该层是否允许使用快捷商店 "map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成 [5, 5, 5, 5, 5, 5, 87, 5, 5, 5, 5, 5, 5], [5, 4, 4, 4, 4, 1, 0, 1, 4, 4, 4, 4, 5], diff --git a/libs/ui.js b/libs/ui.js index e3856ec1..bd62e491 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -362,12 +362,255 @@ ui.prototype.drawQuickShop = function (need) { } -ui.prototype.drawBattleAnimate = function() { +ui.prototype.drawBattleAnimate = function(monsterId, callback) { + + // UI层 + core.lockControl(); + if (!core.isset(core.status.event.id)) { + core.status.event = {'id': 'battle'}; + } + + var hero_hp = core.getStatus('hp'), hero_atk = core.getStatus('atk'), hero_def = core.getStatus('def'), + hero_mdef = core.getStatus('mdef'); + var monster = core.material.enemys[monsterId]; + var mon_hp = monster.hp, mon_atk = monster.atk, mon_def = monster.def, mon_money=monster.money, mon_exp = monster.experience, mon_special=monster.special; + + hero_hp -= core.enemys.getExtraDamage(monster); + + if (mon_special==2) hero_def=0; // 魔攻 + if (mon_special==3 && mon_def0) + mon_hp-=hero_atk-mon_def; + if (mon_hp<0) mon_hp=0; + + // 更新怪物伤害 + core.clearMap('data', right_start, top+margin+10, lineWidth, 40); + core.canvas.data.textAlign='left'; + core.fillText('data', mon_hp, right_start, top+margin+10+26, '#DDDDDD', 'bold 16px Verdana'); + + } + else { + // 怪物攻击 + core.drawLine('data', left + margin + 6, top+margin+heroHeight+(boxWidth-32)-6, + left+margin+boxWidth-6, top+margin+6, '#FF0000', 4); + setTimeout(function() { + core.clearMap('data', left + margin, top+margin, boxWidth, heroHeight+boxWidth-32); + }, 250); + + var per_damage = mon_atk-hero_def; + if (mon_special == 8) per_damage += parseInt(0.1 * hero_atk); // 反击 + + hero_mdef-=per_damage; + if (hero_mdef<0) { + hero_hp+=hero_mdef; + hero_mdef=0; + } + // 更新勇士数据 + core.clearMap('data', left_start, top+margin+10, lineWidth, 40); + core.canvas.data.textAlign='right'; + core.fillText('data', hero_hp, left_end, top+margin+10+26, '#DDDDDD', 'bold 16px Verdana'); + + if (core.flags.enableMDef) { + core.clearMap('data', left_start, top+margin+10+3*lineHeight, lineWidth, 40); + core.fillText('data', hero_mdef, left_end, top+margin+10+26+3*lineHeight); + } + + } + turn++; + if (turn>=turns) turn=0; + + if (hero_hp<=0 || mon_hp<=0) { + // 战斗结束 + 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); + if (core.status.event.id=='battle') { + core.unLockControl(); + core.status.event.id=null; + } + if (core.isset(callback)) + callback(); + return; + } + + }, 500); } /**