diff --git a/HTML5魔塔样板使用指南.url b/HTML5魔塔样板使用指南.url index a346778c..823d8f8d 100644 --- a/HTML5魔塔样板使用指南.url +++ b/HTML5魔塔样板使用指南.url @@ -2,4 +2,4 @@ Prop3=19,2 [InternetShortcut] IDList= -URL=http://ckcz123.github.io/mota-js/ +URL=https://ckcz123.github.io/mota-js/ diff --git a/README.md b/README.md index 9fdc6774..fa46e8d3 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,61 @@ -# H5 魔塔样板 +# HTML5 魔塔样板 ## 简介 HTML5 canvas制作的魔塔样板,支持全平台游戏! **即使完全不会编程的用户,按照模板和说明文档也能很快做出一个魔塔游戏!** -* [Demo / 样板效果](http://ckcz123.com/games/template/) -* [Docs / 使用文档说明](http://ckcz123.github.io/mota-js) +* [Demo / 样板效果](https://ckcz123.com/games/template/) +* [Docs / 使用文档说明](https://ckcz123.github.io/mota-js) ![样板](./docs/img/sample0.png) +## 目录结构 + +``` bash +├── /_server/ # 为可视化地图编辑器提供一些支持的目录 +├── /docs/ # 文档目录 +├── /images/ # 所有图片素材目录 +│ ├─ /常用素材/ # 可以被直接替换的素材 +│ └─ *.png # 对应的某个具体的图片素材 +├── /libs/ # JS源代码目录 +│ ├─ /floors/ # 剧本文件,记录了每个地图的数据和事件 +│ ├─ core.js # 系统核心文件 +│ ├─ data.js # 记录了勇士的初始化信息、各个全局变量和全局Flag值 +│ ├─ enemys.js # 记录了怪物的信息,包括怪物的数据和特殊属性、伤害计算公式、临界值计算等。 +│ ├─ events.js # 处理事件的文件,所有自定义事件都会在此文件中进行处理 +│ ├─ icons.js # 记录了图标信息,将元件的ID和images目录下的素材图标对应起来 +│ ├─ items.js # 记录了道具的信息,包括道具说明、道具效果等。 +│ ├─ maps.js # 记录了地图信息,负责将数字与元件的ID一一对应起来。 +│ └─ ui.js # UI绘制信息,主要负责绘制各个UI窗口。 +├── /sounds/ # 音效目录 +├── /常用工具/ # 一些常用工具,可以辅助造塔 +│ ├─ JS代码压缩工具.exe # 能对Javascript代码进行压缩和整合,从而减少IO请求量。 http://github.com/ckcz123/JSCompressor/ +│ ├─ 便捷PS工具.exe # 能只用复制和粘贴来快速对素材进行PS操作。 http://github.com/ckcz123/ps/ +│ ├─ 地图生成器.exe # 能从一张截图识别出来具体的数字数组,方便复刻已有的塔。 http://github.com/ckcz123/map_generator/ +│ └─ 伤害和临界值计算器.exe # 一个能帮助计算怪物的伤害和临界值的小工具。 http://github.com/ckcz123/magic-tower-calculator/ +├── drawMapGUI.html # 可视化地图编辑工具,能简单地在界面上绘制地图 +├── index.html # 主程序,游戏的入口 +├── main.js # JS程序的入口,将动态对所需JS进行加载 +├── style.css # 游戏所需要用到的样式表 +└── 启动服务.exe # 一个本地的HTTP服务器,也能支撑前端的一些POST请求从而能拓展JS的IO功能。 http://github.com/ckcz123/mota-js-server/ +``` + ## 更新说明 +### 2017.12.21 + +* [x] 新增:本地HTTP服务器。 +* [x] 新增:可视化地图编辑工具。 +* [x] 新增:便捷PS工具。 +* [x] 移除了meaning.txt,现在“地图生成器”将直接从js文件中读取数字和图块对应关系。 +* [x] 新增:对Autotile图块的支持。 +* [x] 新增:怪物支持多种属性;添加仇恨属性。 +* [x] 移除了不再支持的checkBlock,现在对于领域和夹击无需再手动指定可能的点了。 +* [x] 新增:单向箭头、感叹号(单次通行)的支持。 +* [x] 新增:更多的默认素材,现在对于大多数地图风格无需P图,直接替换即可。 +* [x] 添加部分自定义事件,部分细节优化,一些已知的Bug进行了修复。 + ### 2017.12.16 * [x] 新增:战斗过程显示,可以在设置中关闭 @@ -24,7 +68,7 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! ### 2017.12.9 -* 发布初版HTML5魔塔样板 +* [x] 发布初版HTML5魔塔样板 ## 联系我们 diff --git a/[start server.cmd b/[start server.cmd deleted file mode 100644 index 814d7527..00000000 --- a/[start server.cmd +++ /dev/null @@ -1 +0,0 @@ -python _server.py \ No newline at end of file diff --git a/_server.py b/_server.py deleted file mode 100644 index e2955bc1..00000000 --- a/_server.py +++ /dev/null @@ -1,140 +0,0 @@ -# -*- coding: utf-8 -*- -import json -import socket -import threading -import os -import time - -def httpserver(port = 7945): - import http.server - http.server.test(http.server.SimpleHTTPRequestHandler,port=port) - -def voidfunc(*a,**k): - pass -sysecho=print -mecho=voidfunc - -homepage='homepage' -strtemplate='HTTP/1.0 302 Move temporarily\r\nContent-Length: 0\r\nLocation: {urlstr}\r\n\r\n' #{urlstr} - -def mainget(urlstr): - funcAfter=lambda:0 - if False and urlstr == '/': - sysecho(''.join([ - 'GET / ',addr[0],':',str(addr[1]) - ])) - return (200,homepage,funcAfter) - if True: - return (strtemplate.format(urlstr='//127.0.0.1:7945'+urlstr),'',funcAfter) - return (404,'404') - -def mainpost(urlstr,body): - funcAfter=lambda:0 - if urlstr == '/': - out='name not match' - try: - op=json.loads(body) - name=op['name'] - op['func'] - op['args'] - except Exception as e: - return (200,'error format') - if name=='readUTF8file' and op['func']=='open': - with open('./'+op['args'][0],encoding='utf-8') as fid: - out=fid.read() - if name=='writeUTF8file' and op['func']=='open': - with open('./'+op['args'][0],'w',encoding='utf-8') as fid: - out=str(fid.write(op['args'][1])) - return (200,out,funcAfter) - return (403,'no service this url') - -def mainparse(header,body): - funcAfter=lambda:0 - for _tmp in [1]: - if header[:3]=='GET': - urlstr=header.split(' ',2)[1] - mainre = mainget(urlstr) - if len(mainre)==2: - header,body=mainre - else: - header,body,funcAfter=mainre - break - if header[:4]=='POST': - urlstr=header.split(' ',2)[1] - mainre = mainpost(urlstr,body) - if len(mainre)==2: - header,body=mainre - else: - header,body,funcAfter=mainre - break - if header=='': - header,body= (403,'') - break - header,body= (403,'') - body=body.encode('utf-8') - if type(header)==int: - codeDict={200:'200 OK',302:'302 Move temporarily',403:'403 Forbidden',404:'404 Not Found'} - header=('HTTP/1.0 {statu}\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: '.format(statu=codeDict[header])+str(len(body))+'\r\nAccess-Control-Allow-Origin: *\r\n\r\n') - #\r\nAccess-Control-Allow-Origin: * null : to test in chrome - header=header.encode('utf-8') - return (header,body,funcAfter) - -def tcplink(sock, addr): - mecho('\n\nAccept new connection from %s:%s...' % addr) - tempbuffer = [''] - data='' - header='' - body='' - while True: - d = sock.recv(512) - if d: - d=d.decode('utf-8') - tempbuffer.append(d) - tempend=tempbuffer[-1][-4:]+d - if '\r\n\r\n' in tempend: - headend=True - data=''.join(tempbuffer) - header, body = data.split('\r\n\r\n', 1) - if header[:3]=='GET': - tempbuffer=[] - break - tempbuffer=[body] - a=int(header.split('Content-Length:',1)[1].split('\r\n',1)[0])-len(body.encode('utf-8'))#str.len not equal byte.len - while a>0: - tempbuffer.append(sock.recv(min(a,512)).decode('utf-8')) - a=a-min(a,512) - break - else: - break - mecho('recv end\n===') - body = ''.join(tempbuffer) - mecho(header) - mecho('---') - if len(body)>250: - mecho(body[:100]) - mecho('...\n') - mecho(body[-100:]) - else: - mecho(body) - if True: - header,body,funcAfter=mainparse(header,body) - mecho('===\nsend start\n') - sock.send(header) - sock.send(body) - mecho('\nsend end\n===') - sock.close() - mecho('Connection from %s:%s closed.' % addr) - funcAfter() - -if __name__ == '__main__': - out = threading.Thread(target=httpserver) - out.start() - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.bind(('127.0.0.1', 80)) - s.listen(500) - sysecho('Waiting for connection...') - os.popen('explorer http://127.0.0.1:7945/drawMapGUI.html') - while True: - sock, addr = s.accept() - t = threading.Thread(target=tcplink, args=(sock, addr)) - t.start() \ No newline at end of file diff --git a/_server/fsTest_cs.html b/_server/fsTest_cs.html new file mode 100644 index 00000000..0ae73da0 --- /dev/null +++ b/_server/fsTest_cs.html @@ -0,0 +1,126 @@ + + + + + + + + \ No newline at end of file diff --git a/_server/vendor/vue.min.js b/_server/vendor/vue.min.js new file mode 100644 index 00000000..4eb55b79 --- /dev/null +++ b/_server/vendor/vue.min.js @@ -0,0 +1,6 @@ +/*! + * Vue.js v2.5.11 + * (c) 2014-2017 Evan You + * Released under the MIT License. + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Vue=e()}(this,function(){"use strict";function t(t){return void 0===t||null===t}function e(t){return void 0!==t&&null!==t}function n(t){return!0===t}function r(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t}function i(t){return null!==t&&"object"==typeof t}function o(t){return"[object Object]"===Nn.call(t)}function a(t){var e=parseFloat(String(t));return e>=0&&Math.floor(e)===e&&isFinite(t)}function s(t){return null==t?"":"object"==typeof t?JSON.stringify(t,null,2):String(t)}function c(t){var e=parseFloat(t);return isNaN(e)?t:e}function u(t,e){for(var n=Object.create(null),r=t.split(","),i=0;i-1)return t.splice(n,1)}}function f(t,e){return Mn.call(t,e)}function d(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}function p(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n}function v(t,e){e=e||0;for(var n=t.length-e,r=new Array(n);n--;)r[n]=t[n+e];return r}function h(t,e){for(var n in e)t[n]=e[n];return t}function m(t){for(var e={},n=0;n0&&(tt((s=et(s,(o||"")+"_"+a))[0])&&tt(u)&&(l[c]=x(u.text+s[0].text),s.shift()),l.push.apply(l,s)):r(s)?tt(u)?l[c]=x(u.text+s):""!==s&&l.push(x(s)):tt(s)&&tt(u)?l[c]=x(u.text+s.text):(n(i._isVList)&&e(s.tag)&&t(s.key)&&e(o)&&(s.key="__vlist"+o+"_"+a+"__"),l.push(s)));return l}function nt(t,e){return(t.__esModule||fr&&"Module"===t[Symbol.toStringTag])&&(t=t.default),i(t)?e.extend(t):t}function rt(t){return t.isComment&&t.asyncFactory}function it(t){if(Array.isArray(t))for(var n=0;n=0||n.indexOf(t[i])<0)&&r.push(t[i]);return r}return t}}(n[o],r[o],i[o]));return e}(t);r&&h(t.extendOptions,r),(e=t.options=F(n,t.extendOptions)).name&&(e.components[e.name]=t)}}return e}function Rt(t){this._init(t)}function Ht(t){t.cid=0;var e=1;t.extend=function(t){t=t||{};var n=this,r=n.cid,i=t._Ctor||(t._Ctor={});if(i[r])return i[r];var o=t.name||n.options.name,a=function(t){this._init(t)};return a.prototype=Object.create(n.prototype),a.prototype.constructor=a,a.cid=e++,a.options=F(n.options,t),a.super=n,a.options.props&&function(t){var e=t.options.props;for(var n in e)mt(t.prototype,"_props",n)}(a),a.options.computed&&function(t){var e=t.options.computed;for(var n in e)gt(t.prototype,n,e[n])}(a),a.extend=n.extend,a.mixin=n.mixin,a.use=n.use,zn.forEach(function(t){a[t]=n[t]}),o&&(a.options.components[o]=a),a.superOptions=n.options,a.extendOptions=t,a.sealedOptions=h({},a.options),i[r]=a,a}}function Bt(t){return t&&(t.Ctor.options.name||t.tag)}function Ut(t,e){return Array.isArray(t)?t.indexOf(e)>-1:"string"==typeof t?t.split(",").indexOf(e)>-1:!!function(t){return"[object RegExp]"===Nn.call(t)}(t)&&t.test(e)}function Vt(t,e){var n=t.cache,r=t.keys,i=t._vnode;for(var o in n){var a=n[o];if(a){var s=Bt(a.componentOptions);s&&!e(s)&&zt(n,o,r,i)}}}function zt(t,e,n,r){var i=t[e];!i||r&&i.tag===r.tag||i.componentInstance.$destroy(),t[e]=null,l(n,e)}function Kt(t){for(var n=t.data,r=t,i=t;e(i.componentInstance);)(i=i.componentInstance._vnode)&&i.data&&(n=Jt(i.data,n));for(;e(r=r.parent);)r&&r.data&&(n=Jt(n,r.data));return function(t,n){if(e(t)||e(n))return qt(t,Wt(n));return""}(n.staticClass,n.class)}function Jt(t,n){return{staticClass:qt(t.staticClass,n.staticClass),class:e(t.class)?[t.class,n.class]:n.class}}function qt(t,e){return t?e?t+" "+e:t:e||""}function Wt(t){return Array.isArray(t)?function(t){for(var n,r="",i=0,o=t.length;i=0&&" "===(m=t.charAt(h));h--);m&&Ii.test(m)||(l=!0)}}else void 0===o?(v=i+1,o=t.slice(0,i).trim()):e();if(void 0===o?o=t.slice(0,i).trim():0!==v&&e(),a)for(i=0;i-1?{exp:t.slice(0,ii),key:'"'+t.slice(ii+1)+'"'}:{exp:t,key:null};ni=t,ii=oi=ai=0;for(;!ge();)_e(ri=ye())?be(ri):91===ri&&function(t){var e=1;oi=ii;for(;!ge();)if(t=ye(),_e(t))be(t);else if(91===t&&e++,93===t&&e--,0===e){ai=ii;break}}(ri);return{exp:t.slice(0,oi),key:t.slice(oi+1,ai)}}(t);return null===n.key?t+"="+e:"$set("+n.exp+", "+n.key+", "+e+")"}function ye(){return ni.charCodeAt(++ii)}function ge(){return ii>=ei}function _e(t){return 34===t||39===t}function be(t){for(var e=t;!ge()&&(t=ye())!==e;);}function $e(t,e,n,r,i){e=function(t){return t._withTask||(t._withTask=function(){Er=!0;var e=t.apply(null,arguments);return Er=!1,e})}(e),n&&(e=function(t,e,n){var r=si;return function i(){null!==t.apply(null,arguments)&&Ce(e,i,n,r)}}(e,t,r)),si.addEventListener(t,e,or?{capture:r,passive:i}:r)}function Ce(t,e,n,r){(r||si).removeEventListener(t,e._withTask||e,n)}function we(n,r){if(!t(n.data.on)||!t(r.data.on)){var i=r.data.on||{},o=n.data.on||{};si=r.elm,function(t){if(e(t[Li])){var n=Qn?"change":"input";t[n]=[].concat(t[Li],t[n]||[]),delete t[Li]}e(t[Mi])&&(t.change=[].concat(t[Mi],t.change||[]),delete t[Mi])}(i),X(i,o,$e,Ce,r.context),si=void 0}}function xe(n,r){if(!t(n.data.domProps)||!t(r.data.domProps)){var i,o,a=r.elm,s=n.data.domProps||{},u=r.data.domProps||{};e(u.__ob__)&&(u=r.data.domProps=h({},u));for(i in s)t(u[i])&&(a[i]="");for(i in u){if(o=u[i],"textContent"===i||"innerHTML"===i){if(r.children&&(r.children.length=0),o===s[i])continue;1===a.childNodes.length&&a.removeChild(a.childNodes[0])}if("value"===i){a._value=o;var l=t(o)?"":String(o);(function(t,n){return!t.composing&&("OPTION"===t.tagName||function(t,e){var n=!0;try{n=document.activeElement!==t}catch(t){}return n&&t.value!==e}(t,n)||function(t,n){var r=t.value,i=t._vModifiers;if(e(i)){if(i.lazy)return!1;if(i.number)return c(r)!==c(n);if(i.trim)return r.trim()!==n.trim()}return r!==n}(t,n))})(a,l)&&(a.value=l)}else a[i]=o}}}function ke(t){var e=Ae(t.style);return t.staticStyle?h(t.staticStyle,e):e}function Ae(t){return Array.isArray(t)?m(t):"string"==typeof t?Fi(t):t}function Oe(n,r){var i=r.data,o=n.data;if(!(t(i.staticStyle)&&t(i.style)&&t(o.staticStyle)&&t(o.style))){var a,s,c=r.elm,u=o.staticStyle,l=o.normalizedStyle||o.style||{},f=u||l,d=Ae(r.data.style)||{};r.data.normalizedStyle=e(d.__ob__)?h({},d):d;var p=function(t,e){var n,r={};if(e)for(var i=t;i.componentInstance;)(i=i.componentInstance._vnode)&&i.data&&(n=ke(i.data))&&h(r,n);(n=ke(t.data))&&h(r,n);for(var o=t;o=o.parent;)o.data&&(n=ke(o.data))&&h(r,n);return r}(r,!0);for(s in f)t(p[s])&&Bi(c,s,"");for(s in p)(a=p[s])!==f[s]&&Bi(c,s,null==a?"":a)}}function Se(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(/\s+/).forEach(function(e){return t.classList.add(e)}):t.classList.add(e);else{var n=" "+(t.getAttribute("class")||"")+" ";n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function Te(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(/\s+/).forEach(function(e){return t.classList.remove(e)}):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" "+(t.getAttribute("class")||"")+" ",r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function Ee(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&h(e,Ki(t.name||"v")),h(e,t),e}return"string"==typeof t?Ki(t):void 0}}function je(t){Qi(function(){Qi(t)})}function Ne(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),Se(t,e))}function Ie(t,e){t._transitionClasses&&l(t._transitionClasses,e),Te(t,e)}function Le(t,e,n){var r=Me(t,e),i=r.type,o=r.timeout,a=r.propCount;if(!i)return n();var s=i===qi?Zi:Yi,c=0,u=function(){t.removeEventListener(s,l),n()},l=function(e){e.target===t&&++c>=a&&u()};setTimeout(function(){c0&&(n=qi,l=a,f=o.length):e===Wi?u>0&&(n=Wi,l=u,f=c.length):f=(n=(l=Math.max(a,u))>0?a>u?qi:Wi:null)?n===qi?o.length:c.length:0;return{type:n,timeout:l,propCount:f,hasTransform:n===qi&&to.test(r[Gi+"Property"])}}function De(t,e){for(;t.length1}function Ue(t,e){!0!==e.data.show&&Fe(e)}function Ve(t,e,n){ze(t,e,n),(Qn||er)&&setTimeout(function(){ze(t,e,n)},0)}function ze(t,e,n){var r=e.value,i=t.multiple;if(!i||Array.isArray(r)){for(var o,a,s=0,c=t.options.length;s-1,a.selected!==o&&(a.selected=o);else if(g(Je(a),r))return void(t.selectedIndex!==s&&(t.selectedIndex=s));i||(t.selectedIndex=-1)}}function Ke(t,e){return e.every(function(e){return!g(e,t)})}function Je(t){return"_value"in t?t._value:t.value}function qe(t){t.target.composing=!0}function We(t){t.target.composing&&(t.target.composing=!1,Ge(t.target,"input"))}function Ge(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function Ze(t){return!t.componentInstance||t.data&&t.data.transition?t:Ze(t.componentInstance._vnode)}function Xe(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?Xe(it(e.children)):t}function Ye(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var i=n._parentListeners;for(var o in i)e[Pn(o)]=i[o];return e}function Qe(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}function tn(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function en(t){t.data.newPos=t.elm.getBoundingClientRect()}function nn(t){var e=t.data.pos,n=t.data.newPos,r=e.left-n.left,i=e.top-n.top;if(r||i){t.data.moved=!0;var o=t.elm.style;o.transform=o.WebkitTransform="translate("+r+"px,"+i+"px)",o.transitionDuration="0s"}}function rn(t,e){var n=e?zo:Vo;return t.replace(n,function(t){return Uo[t]})}function on(t,e,n){return{type:1,tag:t,attrsList:e,attrsMap:function(t){for(var e={},n=0,r=t.length;n=0&&a[i].lowerCasedTag!==s;i--);else i=0;if(i>=0){for(var c=a.length-1;c>=i;c--)e.end&&e.end(a[c].tag,n,r);a.length=i,o=i&&a[i-1].tag}else"br"===s?e.start&&e.start(t,[],!0,n,r):"p"===s&&(e.start&&e.start(t,[],!1,n,r),e.end&&e.end(t,n,r))}for(var i,o,a=[],s=e.expectHTML,c=e.isUnaryTag||Bn,u=e.canBeLeftOpenTag||Bn,l=0;t;){if(i=t,o&&Ho(o)){var f=0,d=o.toLowerCase(),p=Bo[d]||(Bo[d]=new RegExp("([\\s\\S]*?)(]*>)","i")),v=t.replace(p,function(t,n,r){return f=r.length,Ho(d)||"noscript"===d||(n=n.replace(//g,"$1").replace(//g,"$1")),Jo(d,n)&&(n=n.slice(1)),e.chars&&e.chars(n),""});l+=t.length-v.length,t=v,r(d,l-f,l)}else{var h=t.indexOf("<");if(0===h){if(Ao.test(t)){var m=t.indexOf("--\x3e");if(m>=0){e.shouldKeepComment&&e.comment(t.substring(4,m)),n(m+3);continue}}if(Oo.test(t)){var y=t.indexOf("]>");if(y>=0){n(y+2);continue}}var g=t.match(ko);if(g){n(g[0].length);continue}var _=t.match(xo);if(_){var b=l;n(_[0].length),r(_[1],b,l);continue}var $=function(){var e=t.match(Co);if(e){var r={tagName:e[1],attrs:[],start:l};n(e[0].length);for(var i,o;!(i=t.match(wo))&&(o=t.match(_o));)n(o[0].length),r.attrs.push(o);if(i)return r.unarySlash=i[1],n(i[0].length),r.end=l,r}}();if($){!function(t){var n=t.tagName,i=t.unarySlash;s&&("p"===o&&go(n)&&r(o),u(n)&&o===n&&r(n));for(var l=c(n)||!!i,f=t.attrs.length,d=new Array(f),p=0;p=0){for(w=t.slice(h);!(xo.test(w)||Co.test(w)||Ao.test(w)||Oo.test(w)||(x=w.indexOf("<",1))<0);)h+=x,w=t.slice(h);C=t.substring(0,h),n(h)}h<0&&(C=t,t=""),e.chars&&C&&e.chars(C)}if(t===i){e.chars&&e.chars(t);break}}r()}(t,{warn:To,expectHTML:e.expectHTML,isUnaryTag:e.isUnaryTag,canBeLeftOpenTag:e.canBeLeftOpenTag,shouldDecodeNewlines:e.shouldDecodeNewlines,shouldDecodeNewlinesForHref:e.shouldDecodeNewlinesForHref,shouldKeepComment:e.comments,start:function(t,a,u){var l=i&&i.ns||Do(t);Qn&&"svg"===l&&(a=function(t){for(var e=[],n=0;na&&o.push(JSON.stringify(t.slice(a,i)));var s=ae(r[1].trim());o.push("_s("+s+")"),a=i+r[0].length}return a':'
',Ro.innerHTML.indexOf(" ")>0}var jn=Object.freeze({}),Nn=Object.prototype.toString,In=u("slot,component",!0),Ln=u("key,ref,slot,slot-scope,is"),Mn=Object.prototype.hasOwnProperty,Dn=/-(\w)/g,Pn=d(function(t){return t.replace(Dn,function(t,e){return e?e.toUpperCase():""})}),Fn=d(function(t){return t.charAt(0).toUpperCase()+t.slice(1)}),Rn=/\B([A-Z])/g,Hn=d(function(t){return t.replace(Rn,"-$1").toLowerCase()}),Bn=function(t,e,n){return!1},Un=function(t){return t},Vn="data-server-rendered",zn=["component","directive","filter"],Kn=["beforeCreate","created","beforeMount","mounted","beforeUpdate","updated","beforeDestroy","destroyed","activated","deactivated","errorCaptured"],Jn={optionMergeStrategies:Object.create(null),silent:!1,productionTip:!1,devtools:!1,performance:!1,errorHandler:null,warnHandler:null,ignoredElements:[],keyCodes:Object.create(null),isReservedTag:Bn,isReservedAttr:Bn,isUnknownElement:Bn,getTagNamespace:y,parsePlatformTagName:Un,mustUseProp:Bn,_lifecycleHooks:Kn},qn=/[^\w.$]/,Wn="__proto__"in{},Gn="undefined"!=typeof window,Zn="undefined"!=typeof WXEnvironment&&!!WXEnvironment.platform,Xn=Zn&&WXEnvironment.platform.toLowerCase(),Yn=Gn&&window.navigator.userAgent.toLowerCase(),Qn=Yn&&/msie|trident/.test(Yn),tr=Yn&&Yn.indexOf("msie 9.0")>0,er=Yn&&Yn.indexOf("edge/")>0,nr=Yn&&Yn.indexOf("android")>0||"android"===Xn,rr=Yn&&/iphone|ipad|ipod|ios/.test(Yn)||"ios"===Xn,ir=(Yn&&/chrome\/\d+/.test(Yn),{}.watch),or=!1;if(Gn)try{var ar={};Object.defineProperty(ar,"passive",{get:function(){or=!0}}),window.addEventListener("test-passive",null,ar)}catch(t){}var sr,cr,ur=function(){return void 0===sr&&(sr=!Gn&&"undefined"!=typeof global&&"server"===global.process.env.VUE_ENV),sr},lr=Gn&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__,fr="undefined"!=typeof Symbol&&w(Symbol)&&"undefined"!=typeof Reflect&&w(Reflect.ownKeys);cr="undefined"!=typeof Set&&w(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var dr=y,pr=0,vr=function(){this.id=pr++,this.subs=[]};vr.prototype.addSub=function(t){this.subs.push(t)},vr.prototype.removeSub=function(t){l(this.subs,t)},vr.prototype.depend=function(){vr.target&&vr.target.addDep(this)},vr.prototype.notify=function(){for(var t=this.subs.slice(),e=0,n=t.length;eVr&&Fr[n].id>t.id;)n--;Fr.splice(n+1,0,t)}else Fr.push(t);Br||(Br=!0,q(ht))}}(this)},Kr.prototype.run=function(){if(this.active){var t=this.get();if(t!==this.value||i(t)||this.deep){var e=this.value;if(this.value=t,this.user)try{this.cb.call(this.vm,t,e)}catch(t){V(t,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,t,e)}}},Kr.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},Kr.prototype.depend=function(){for(var t=this.deps.length;t--;)this.deps[t].depend()},Kr.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||l(this.vm._watchers,this);for(var t=this.deps.length;t--;)this.deps[t].removeSub(this);this.active=!1}};var Jr={enumerable:!0,configurable:!0,get:y,set:y},qr={lazy:!0};Nt(It.prototype);var Wr={init:function(t,n,r,i){if(!t.componentInstance||t.componentInstance._isDestroyed){(t.componentInstance=function(t,n,r,i){var o={_isComponent:!0,parent:n,_parentVnode:t,_parentElm:r||null,_refElm:i||null},a=t.data.inlineTemplate;return e(a)&&(o.render=a.render,o.staticRenderFns=a.staticRenderFns),new t.componentOptions.Ctor(o)}(t,Pr,r,i)).$mount(n?t.elm:void 0,n)}else if(t.data.keepAlive){var o=t;Wr.prepatch(o,o)}},prepatch:function(t,e){var n=e.componentOptions;!function(t,e,n,r,i){var o=!!(i||t.$options._renderChildren||r.data.scopedSlots||t.$scopedSlots!==jn);if(t.$options._parentVnode=r,t.$vnode=r,t._vnode&&(t._vnode.parent=r),t.$options._renderChildren=i,t.$attrs=r.data&&r.data.attrs||jn,t.$listeners=n||jn,e&&t.$options.props){Cr.shouldConvert=!1;for(var a=t._props,s=t.$options._propKeys||[],c=0;c1?v(n):n;for(var r=v(arguments,1),i=0,o=n.length;iparseInt(this.max)&&zt(a,s[0],s,this._vnode)),e.data.keepAlive=!0}return e||t&&t[0]}}};!function(t){var e={};e.get=function(){return Jn},Object.defineProperty(t,"config",e),t.util={warn:dr,extend:h,mergeOptions:F,defineReactive:E},t.set=j,t.delete=N,t.nextTick=q,t.options=Object.create(null),zn.forEach(function(e){t.options[e+"s"]=Object.create(null)}),t.options._base=t,h(t.options.components,ti),function(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=v(arguments,1);return n.unshift(this),"function"==typeof t.install?t.install.apply(t,n):"function"==typeof t&&t.apply(null,n),e.push(t),this}}(t),function(t){t.mixin=function(t){return this.options=F(this.options,t),this}}(t),Ht(t),function(t){zn.forEach(function(e){t[e]=function(t,n){return n?("component"===e&&o(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&"function"==typeof n&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}})}(t)}(Rt),Object.defineProperty(Rt.prototype,"$isServer",{get:ur}),Object.defineProperty(Rt.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Rt.version="2.5.11";var ei,ni,ri,ii,oi,ai,si,ci,ui=u("style,class"),li=u("input,textarea,option,select,progress"),fi=function(t,e,n){return"value"===n&&li(t)&&"button"!==e||"selected"===n&&"option"===t||"checked"===n&&"input"===t||"muted"===n&&"video"===t},di=u("contenteditable,draggable,spellcheck"),pi=u("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,translate,truespeed,typemustmatch,visible"),vi="http://www.w3.org/1999/xlink",hi=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},mi=function(t){return hi(t)?t.slice(6,t.length):""},yi=function(t){return null==t||!1===t},gi={svg:"http://www.w3.org/2000/svg",math:"http://www.w3.org/1998/Math/MathML"},_i=u("html,body,base,head,link,meta,style,title,address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,menuitem,summary,content,element,shadow,template,blockquote,iframe,tfoot"),bi=u("svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view",!0),$i=function(t){return _i(t)||bi(t)},Ci=Object.create(null),wi=u("text,number,password,search,email,tel,url"),xi=Object.freeze({createElement:function(t,e){var n=document.createElement(t);return"select"!==t?n:(e.data&&e.data.attrs&&void 0!==e.data.attrs.multiple&&n.setAttribute("multiple","multiple"),n)},createElementNS:function(t,e){return document.createElementNS(gi[t],e)},createTextNode:function(t){return document.createTextNode(t)},createComment:function(t){return document.createComment(t)},insertBefore:function(t,e,n){t.insertBefore(e,n)},removeChild:function(t,e){t.removeChild(e)},appendChild:function(t,e){t.appendChild(e)},parentNode:function(t){return t.parentNode},nextSibling:function(t){return t.nextSibling},tagName:function(t){return t.tagName},setTextContent:function(t,e){t.textContent=e},setAttribute:function(t,e,n){t.setAttribute(e,n)}}),ki={create:function(t,e){Xt(e)},update:function(t,e){t.data.ref!==e.data.ref&&(Xt(t,!0),Xt(e))},destroy:function(t){Xt(t,!0)}},Ai=new mr("",{},[]),Oi=["create","activate","update","remove","destroy"],Si={create:te,update:te,destroy:function(t){te(t,Ai)}},Ti=Object.create(null),Ei=[ki,Si],ji={create:re,update:re},Ni={create:oe,update:oe},Ii=/[\w).+\-_$\]]/,Li="__r",Mi="__c",Di={create:we,update:we},Pi={create:xe,update:xe},Fi=d(function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach(function(t){if(t){var r=t.split(n);r.length>1&&(e[r[0].trim()]=r[1].trim())}}),e}),Ri=/^--/,Hi=/\s*!important$/,Bi=function(t,e,n){if(Ri.test(e))t.style.setProperty(e,n);else if(Hi.test(n))t.style.setProperty(e,n.replace(Hi,""),"important");else{var r=Vi(e);if(Array.isArray(n))for(var i=0,o=n.length;ip?v(n,t(i[g+1])?null:i[g+1].elm,i,d,g,o):d>g&&m(0,r,f,p)}function _(r,i,o,a){if(r!==i){var s=i.elm=r.elm;if(n(r.isAsyncPlaceholder))e(i.asyncFactory.resolved)?$(r.elm,i,o):i.isAsyncPlaceholder=!0;else if(n(i.isStatic)&&n(r.isStatic)&&i.key===r.key&&(n(i.isCloned)||n(i.isOnce)))i.componentInstance=r.componentInstance;else{var c,u=i.data;e(u)&&e(c=u.hook)&&e(c=c.prepatch)&&c(r,i);var l=r.children,d=i.children;if(e(u)&&f(i)){for(c=0;c-1?Ci[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:Ci[t]=/HTMLUnknownElement/.test(e.toString())},h(Rt.options.directives,ro),h(Rt.options.components,so),Rt.prototype.__patch__=Gn?eo:y,Rt.prototype.$mount=function(t,e){return t=t&&Gn?Zt(t):void 0,function(t,e,n){t.$el=e,t.$options.render||(t.$options.render=gr),vt(t,"beforeMount");var r;return r=function(){t._update(t._render(),n)},new Kr(t,r,y,null,!0),n=!1,null==t.$vnode&&(t._isMounted=!0,vt(t,"mounted")),t}(this,t,e)},Rt.nextTick(function(){Jn.devtools&&lr&&lr.emit("init",Rt)},0);var co,uo=/\{\{((?:.|\n)+?)\}\}/g,lo=/[-.*+?^${}()|[\]\/\\]/g,fo=d(function(t){var e=t[0].replace(lo,"\\$&"),n=t[1].replace(lo,"\\$&");return new RegExp(e+"((?:.|\\n)+?)"+n,"g")}),po={staticKeys:["staticClass"],transformNode:function(t,e){e.warn;var n=ve(t,"class");n&&(t.staticClass=JSON.stringify(n));var r=pe(t,"class",!1);r&&(t.classBinding=r)},genData:function(t){var e="";return t.staticClass&&(e+="staticClass:"+t.staticClass+","),t.classBinding&&(e+="class:"+t.classBinding+","),e}},vo={staticKeys:["staticStyle"],transformNode:function(t,e){e.warn;var n=ve(t,"style");n&&(t.staticStyle=JSON.stringify(Fi(n)));var r=pe(t,"style",!1);r&&(t.styleBinding=r)},genData:function(t){var e="";return t.staticStyle&&(e+="staticStyle:"+t.staticStyle+","),t.styleBinding&&(e+="style:("+t.styleBinding+"),"),e}},ho=function(t){return co=co||document.createElement("div"),co.innerHTML=t,co.textContent},mo=u("area,base,br,col,embed,frame,hr,img,input,isindex,keygen,link,meta,param,source,track,wbr"),yo=u("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source"),go=u("address,article,aside,base,blockquote,body,caption,col,colgroup,dd,details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,title,tr,track"),_o=/^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,bo="[a-zA-Z_][\\w\\-\\.]*",$o="((?:"+bo+"\\:)?"+bo+")",Co=new RegExp("^<"+$o),wo=/^\s*(\/?)>/,xo=new RegExp("^<\\/"+$o+"[^>]*>"),ko=/^]+>/i,Ao=/^ @@ -299,10 +552,9 @@ return 0; } - - updateMap = function () { //clearGrass(); + // console.log(map) for (var xx = 0; xx <= fullX; xx++) { for (var yy = 0; yy <= fullY; yy++) { if (!isGrass(xx, yy)) continue; @@ -341,7 +593,15 @@ for (var yy = 0; yy <= fullY; yy++) { if (isGrass(xx, yy)) continue; var mapxy=map[m(xx,yy)]; - if (typeof(mapxy) == typeof(-1) || typeof(mapxy) == typeof([][0]))continue; + if (typeof(mapxy) == typeof(-1)){ + if(mapxy == 0) cxt.clearRect(xx*32, yy*32, 32, 32); + continue; + } + else if(typeof(mapxy) == typeof([][0])) {//未定义块画红块 + cxt.fillStyle = 'red'; + cxt.fillRect(xx*32, yy*32, 32, 32); + continue; + } //context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height) cxt.clearRect(xx*32, yy*32, 32, 32); cxt.drawImage(core.material.images[mapxy.images], 0, mapxy.y*32, 32, 32, xx*32, yy*32, 32, 32); @@ -359,7 +619,7 @@ var prefix='',postfix=''; if (weak){prefix='';} if (typeof(str)==="undefined")str=''; - pout.innerHTML=prefix+String(str)+postfix; + printOut.innerHTML=prefix+String(str)+postfix; } drawInitData = function(){ @@ -417,8 +677,8 @@ function eToLoc(e) { var loc = { - 'x': document.documentElement.scrollLeft+e.clientX - mid.offsetLeft, - 'y': document.documentElement.scrollTop+e.clientY - mid.offsetTop, + 'x': document.documentElement.scrollLeft+e.clientX - mid.offsetLeft-mapEdit.offsetLeft, + 'y': document.documentElement.scrollTop+e.clientY - mid.offsetTop-mapEdit.offsetTop, 'size': 32 }; return loc; }//返回可用的组件内坐标 @@ -444,6 +704,11 @@ }//用于鼠标移出canvas时的自动清除状态 ui.onmousedown = function (e) { + if(!selectBox.isSelected) { + tip.whichShow = 1; + return; + } + holdingPath = 1; mouseOutCheck = 2; setTimeout(clear1); @@ -457,6 +722,10 @@ } ui.onmousemove = function (e) { + if(!selectBox.isSelected) { + // tip.whichShow = 1; + return; + } if (holdingPath == 0) { return; } mouseOutCheck = 2; @@ -482,48 +751,89 @@ } ui.onmouseup = function (e) { + if(!selectBox.isSelected) { + tip.whichShow = 1; + return; + } holdingPath = 0; e.stopPropagation(); var loc = eToLoc(e); if (stepPostfix.length) { - console.log(stepPostfix); + preMapData = JSON.parse(JSON.stringify(map)); + currDrawData.pos = JSON.parse(JSON.stringify(stepPostfix)); + currDrawData.info = JSON.parse(JSON.stringify(info)); + reDo = null; + // console.log(stepPostfix); for (var ii = 0; ii < stepPostfix.length; ii++) map[m(stepPostfix[ii].x, stepPostfix[ii].y)] = info; map[fullX + 1 + fullY * (fullX + 1)] = -2; - console.log(map); + // console.log(map); updateMap(); holdingPath = 0; stepPostfix = []; uc.clearRect(0, 0, 416, 416); } } + + var preMapData = {}; + var currDrawData = { + pos: [], + info: {} + }; + var reDo = null; + document.body.onkeydown = function(e) { + // 禁止快捷键的默认行为 + if( e.ctrlKey && ( e.keyCode == 90 || e.keyCode == 89 ) ) + e.preventDefault(); + //Ctrl+z 撤销上一步undo + if(e.keyCode == 90 && e.ctrlKey && preMapData && currDrawData.pos.length){ + map = JSON.parse(JSON.stringify(preMapData)); + updateMap(); + reDo = JSON.parse(JSON.stringify(currDrawData)); + currDrawData = {pos: [],info: {}}; + preMapData = null; + } + //Ctrl+y 重做一步redo + if(e.keyCode == 89 && e.ctrlKey && reDo && reDo.pos.length){ + preMapData = JSON.parse(JSON.stringify(map)); + for(var j=0; j=widthsX[spriter][1] && pos.xcore.material.images[pos.images].height)pos.y=~~(core.material.images[pos.images].height/32)-1; + pos.y=0; + }else if((pos.y+1)*32>core.material.images[pos.images].height) + pos.y=~~(core.material.images[pos.images].height/32)-1; - dataSelection.style.left=pos.x*32+'px'; - dataSelection.style.top=pos.y*32+'px'; + selectBox.isSelected = true; + // console.log(pos,core.material.images[pos.images].height) + dataSelection.style.left = pos.x*32 +'px'; + dataSelection.style.top = pos.y*32 +'px'; info={'images':pos.images,'y':pos.y}; for (var ii=0;ii'+filestr+'\n

已复制到剪贴板

'+'


'); - poutTmp.select(); - document.execCommand("Copy"); - } + + \ No newline at end of file diff --git a/images/meaning.txt b/images/meaning.txt deleted file mode 100644 index ed1e714b..00000000 --- a/images/meaning.txt +++ /dev/null @@ -1,116 +0,0 @@ -# 此文件是每个数字所代表的意思,可被地图生成器读取和使用 -# 可以模仿此格式在后面写上任意被识别内容 - - -# 文件格式: -# 编号,图标所在的图片名,图标在图片上的索引(从上到下第几个,从0开始计算) -# 注意中间以小逗号分开;不要有空格;后面可以加任意"#"代表注释 - -### 0-20 地形 ### -0,terrains,0 # 路面;此项必须在第一条。 -1,terrains,1 # 黄色墙(经典墙) -2,terrains,2 # 白色墙 -3,terrains,3 # 蓝色墙 -4,terrains,4 # 星空 -5,terrains,5 # 岩浆 -6,terrains,6 # 冰面 -7,terrains,15 # 蓝色商店左 -8,terrains,16 # 蓝色商店右 -9,terrains,17 # 红色商店左 -10,terrains,18 # 红色商店右 -11,animates,23 # 血网(经过受到伤害) -12,animates,24 # 毒网(经过中毒) -13,animates,25 # 衰网(经过衰弱) -14,animates,26 # 咒网(经过诅咒) -15,animates,31 # 水 -# 可自行往后添加 -20,autotile,0 # Autotile - -### 21-80 物品 ### -# 消耗品 -21,items,0 # 黄钥匙 -22,items,1 # 蓝钥匙 -23,items,2 # 红钥匙 -24,items,3 # 绿钥匙 -25,items,4 # 铁门钥匙 -26,items,6 # 大黄门钥匙(钥匙盒) -27,items,16 # 红宝石 -28,items,17 # 蓝宝石 -29,items,18 # 绿宝石 -30,items,19 # 黄宝石 -31,items,20 # 红血瓶 -32,items,21 # 蓝血瓶 -33,items,22 # 绿血瓶 -34,items,23 # 黄血瓶 -35,items,50 # 铁剑 -36,items,55 # 铁盾 -37,items,51 # 银剑 -38,items,56 # 银盾 -39,items,52 # 骑士剑 -40,items,57 # 骑士盾 -41,items,53 # 圣剑 -42,items,58 # 圣盾 -43,items,54 # 神圣剑 -44,items,59 # 神圣盾 -# 特殊道具 -45,items,9 # 怪物手册 -46,items,12 # 楼层传送器 -47,items,45 # 破墙镐 -48,items,44 # 破冰镐 -49,items,43 # 炸弹 -50,items,13 # 中心对称飞行器 -51,items,15 # 上楼器 -52,items,14 # 下楼器 -53,items,11 # 幸运金币 -54,items,41 # 冰冻徽章 -55,items,40 # 十字架 -56,items,29 # 圣水 -57,items,8 # 地震卷轴 -58,items,24 # 解毒药水 -59,items,25 # 解衰药水 -60,items,27 # 解咒药水 -61,items,28 # 万能药水 -62,items,42 # 屠龙匕首 -63,items,46 # 金钱袋 -64,items,47 # 绿鞋 -65,items,48 # 圣锤 -# 可自行往后添加 - -### 81-120 门、楼梯、传送门 ### -81,terrains,9 # 黄门 -82,terrains,10 # 蓝门 -83,terrains,11 # 红门 -84,terrains,12 # 绿门 -85,terrains,13 # 机关门 -86,terrains,14 # 铁门 -87,terrains,8 # 上楼梯 -88,terrains,7 # 下楼梯 -89,animates,21 # 传送门 -90,animates,19 # 星空传送 -91,animates,30 # 上箭头传送 -92,animates,28 # 左箭头传送 -93,animates,27 # 下箭头传送 -94,animates,29 # 右箭头传送 - -### 121-150 NPC ### -121,npcs,0 # 经典老人 -122,npcs,1 # 经典商人 -123,npcs,2 # 小偷 -124,npcs,3 # 仙子 -125,npcs,4 # 神秘男老人 -126,npcs,5 # 神秘女老人 -127,npcs,6 # 老头 -128,npcs,7 # 小孩 -129,npcs,8 # 木牌 -130,npcs,9 # 经验商店 -131,npcs,10 # 金币商店 -132,npcs,11 # 公主 -# 可以添加更多的NPC图标 - - -# 在此可以继续添加更多的事件,比如单向箭头、感叹号开关、箱子等等 - - -### 201-300 怪物 ### -# 将会按照enemys.png顺序依次读取怪物 -# 如201绿色史莱姆,202红色史莱姆,依次类推 diff --git a/libs/core.js b/libs/core.js index 42f79220..aed539ee 100644 --- a/libs/core.js +++ b/libs/core.js @@ -21,7 +21,8 @@ function core() { 'events': {} } this.timeout = { - 'getItemTipTimeout': null + 'getItemTipTimeout': null, + 'turnHeroTimeout': null, } this.interval = { 'twoAnimate': null, @@ -56,6 +57,7 @@ function core() { 'floorId': null, 'thisMap': null, 'maps': null, + 'checkBlock': [], // 显伤伤害 // 勇士状态;自动寻路相关 'heroMoving': false, @@ -106,7 +108,6 @@ core.prototype.init = function (dom, statusBar, canvas, images, sounds, floorIds core[key] = coreData[key]; } core.flags = core.clone(core.data.flags); - core.flags.battleAnimate = core.getLocalStorage('battleAnimate', core.flags.battleAnimate); core.values = core.clone(core.data.values); core.firstData = core.data.getFirstData(); core.initStatus.shops = core.firstData.shops; @@ -296,7 +297,7 @@ core.prototype.clearStatus = function() { core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight); } -core.prototype.resetStatus = function(hero, hard, floorId, maps) { +core.prototype.resetStatus = function(hero, hard, floorId, flags, maps) { // 停止各个Timeout和Interval for (var i in core.interval) { @@ -314,6 +315,8 @@ core.prototype.resetStatus = function(hero, hard, floorId, maps) { // 初始化人物属性 core.status.hero = core.clone(hero); core.status.hard = hard; + if (core.isset(flags)) + core.flags = core.clone(flags); // 保存页面 core.status.savePage = core.getLocalStorage('savePage', 0); @@ -324,7 +327,7 @@ 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, core.flags, core.initStatus.maps); core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() { core.setHeroMoveTriggerInterval(); @@ -501,6 +504,10 @@ core.prototype.keyUp = function(keyCode) { if (core.status.heroStop) core.ui.drawQuickShop(true); break; + case 32: // SPACE + if (!core.status.lockControl && core.status.heroStop) + core.getNextItem(); + break; case 37: // UP break; case 38: // DOWN @@ -520,12 +527,23 @@ core.prototype.keyUp = function(keyCode) { } break; case 50: // 快捷键2:炸 - if (core.status.heroStop && core.hasItem('bomb')) { - if (core.canUseItem('bomb')) { - core.useItem('bomb'); + if (core.status.heroStop) { + if (core.hasItem('bomb')) { + if (core.canUseItem('bomb')) { + core.useItem('bomb'); + } + else { + core.drawTip('当前不能使用炸弹'); + } } - else { - core.drawTip('当前不能使用炸弹'); + else if (core.hasItem('hammer')) { + if (core.canUseItem('hammer')) { + core.useItem('hammer'); + } + else { + core.drawTip('当前不能使用圣锤'); + } + } } break; @@ -626,7 +644,7 @@ core.prototype.getClickLoc = function (x, y) { } core.prototype.onclick = function (x, y, stepPostfix) { - console.log("Click: (" + x + "," + y + ")"); + // console.log("Click: (" + x + "," + y + ")"); // 非游戏屏幕内 if (x<0 || y<0 || x>12 || y>12) return; @@ -649,6 +667,12 @@ core.prototype.onclick = function (x, y, stepPostfix) { return; } + // 开关 + if (core.status.event.id == 'switchs') { + core.events.clickSwitchs(x,y); + return; + } + // 设置 if (core.status.event.id == 'settings') { core.events.clickSettings(x,y); @@ -745,14 +769,14 @@ core.prototype.onmousewheel = function (direct) { } // 怪物手册 - if (core.status.event.id == 'book') { + if (core.status.lockControl && core.status.event.id == 'book') { if (direct==1) core.ui.drawEnemyBook(core.status.event.data - 1); if (direct==-1) core.ui.drawEnemyBook(core.status.event.data + 1); return; } // 存读档 - if (core.status.event.id == 'save' || core.status.event.id == 'load') { + if (core.status.lockControl && (core.status.event.id == 'save' || core.status.event.id == 'load')) { if (direct==1) core.ui.drawSLPanel(core.status.event.data - 1); if (direct==-1) core.ui.drawSLPanel(core.status.event.data + 1); return; @@ -807,7 +831,18 @@ core.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { return; } if (destX == core.status.hero.loc.x && destY == core.status.hero.loc.y && stepPostfix.length==0) { - core.turnHero(); + if (core.timeout.turnHeroTimeout==null) { + core.timeout.turnHeroTimeout = setTimeout(function() { + core.turnHero(); + clearTimeout(core.timeout.turnHeroTimeout); + core.timeout.turnHeroTimeout = null; + }, 250); + } + else { + clearTimeout(core.timeout.turnHeroTimeout); + core.timeout.turnHeroTimeout = null; + core.getNextItem(); + } return; } var step = 0; @@ -960,14 +995,16 @@ core.prototype.automaticRoute = function (destX, destY) { if ( (scan[direction].x + scan[nextArrow].x) == 0 && (scan[direction].y + scan[nextArrow].y) == 0 ) continue; } // 绕过亮灯(因为只有一次通行机会很宝贵) - if(nextId == "light") deepAdd=50; + if(nextId == "light") deepAdd=100; // 绕过路障 - if (nextId.substring(nextId.length-3)=="Net") deepAdd=100; + if (nextId.substring(nextId.length-3)=="Net") deepAdd=core.values.lavaDamage; // 绕过血瓶 if (!core.flags.potionWhileRouting && nextId.substring(nextId.length-6)=="Potion") deepAdd=20; // 绕过可能的夹击点 - if (nextBlock.block.event.trigger == 'checkBlock') deepAdd=200; + // if (nextBlock.block.event.trigger == 'checkBlock') deepAdd=200; } + if (core.status.checkBlock[nid]>0) + deepAdd = core.status.checkBlock[nid]; if (nx == destX && ny == destY) { route[nid] = direction; @@ -1138,6 +1175,7 @@ core.prototype.setHeroMoveTriggerInterval = function () { core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); } core.trigger(core.getHeroLoc('x'), core.getHeroLoc('y')); + core.checkBlock(); clearInterval(core.interval.heroMoveInterval); core.status.heroMoving = false; }); @@ -1415,6 +1453,7 @@ core.prototype.afterBattle = function(id, x, y, callback) { hint += ",经验+" + core.material.enemys[id].experience; core.drawTip(hint); + core.updateCheckBlockMap(); // 打完怪物,触发事件 core.events.afterBattle(id,x,y,callback); @@ -1491,6 +1530,8 @@ core.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback) core.setHeroLoc('x', heroLoc.x); core.setHeroLoc('y', heroLoc.y); core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + core.updateCheckBlockMap(); + core.updateCheckBlock(); core.updateFg(); }, 15) }); @@ -1992,6 +2033,7 @@ core.prototype.addBlock = function(x,y,floodId) { // 本身是禁用事件,启用之 if (core.isset(block.enable) && !block.enable) { block.enable = true; + core.updateCheckBlockMap(); // 在本层,添加动画 if (floodId == core.status.floorId && core.isset(block.event)) { blockIcon = core.material.icons[block.event.cls][block.event.id]; @@ -2028,24 +2070,22 @@ core.prototype.removeBlockById = function (index, floorId) { var blocks = core.status.maps[floorId].blocks; var x=blocks[index].x, y=blocks[index].y; - // 检查该点是否是checkBlock - if (core.floors[floorId].checkBlock.indexOf(x+","+y)>=0) { - blocks[index] = {'x': x, 'y': y, 'event': {'cls': 'terrains', 'id': 'ground', 'noPass': false, 'trigger': 'checkBlock'}}; - return; - } - // 检查该点是否存在事件 var event = core.floors[floorId].events[x+","+y]; if (!core.isset(event)) event = core.floors[floorId].changeFloor[x+","+y]; + var shouldUpdateBlockMap = blocks[index].event.cls == 'enemys'; // 不存在事件,直接删除 if (!core.isset(event)) { blocks.splice(index,1); + if (shouldUpdateBlockMap) + core.updateCheckBlockMap(); return; } - blocks[index].enable = false; + if (shouldUpdateBlockMap) + core.updateCheckBlockMap(); } core.prototype.removeBlockByIds = function (floorId, ids) { @@ -2144,32 +2184,154 @@ core.prototype.drawBoxAnimate = function (background) { } } +core.prototype.updateCheckBlockMap = function() { + // 更新领域、夹击地图 + core.status.checkBlockMap = []; + var blocks = core.status.thisMap.blocks; + for (var n=0;n12 || ny<0 || ny>12) return; + if (core.status.checkBlockMap[13*nx+ny]%1000000>0) { + damage += core.status.checkBlockMap[13*nx+ny] % 1000000; + } + }) + + var leftValue = core.status.hero.hp - damage; + if (leftValue>1) { + var has = false; + // 夹击 + if (x>0 && x<12) { + var id1=parseInt(core.status.checkBlockMap[13*(x-1)+y]/1000000), + id2=parseInt(core.status.checkBlockMap[13*(x+1)+y]/1000000); + if (id1>0 && id1==id2) + has = true; + } + if (y>0 && y<12) { + var id1=parseInt(core.status.checkBlockMap[13*x+y-1]/1000000), + id2=parseInt(core.status.checkBlockMap[13*x+y+1]/1000000); + if (id1>0 && id1==id2) + has = true; + } + if (has) { + damage += parseInt((leftValue+1) / 2); + } + } + } + core.status.checkBlock[13*x+y] = damage; + } + } +} + +core.prototype.checkBlock = function () { + // 检查领域、夹击事件 + var x=core.getHeroLoc('x'), y=core.getHeroLoc('y'); + if (core.status.checkBlock[13*x+y]>0) { + core.status.hero.hp -= core.status.checkBlock[13*x+y]; + if (core.hasBetweenAttack(x,y)) { + core.drawTip('受到夹击,生命变成一半'); + } + else if (core.hasZone(x,y)) { + core.drawTip('受到领域伤害'+core.status.checkBlock[13*x+y]+'点'); + } + if (core.status.hero.hp<=0) { + core.status.hero.hp=0; + core.updateStatusBar(); + core.events.lose('zone'); + return; + } + core.updateStatusBar(); + } +} + +core.prototype.hasZone = function (x,y) { + if (!core.isset(core.status.checkBlockMap)) core.updateCheckBlockMap(); + var isZone = false; + // 领域 + [[-1,0],[0,-1],[1,0],[0,1]].forEach(function (dir) { + var nx = x+dir[0], ny = y+dir[1]; + if (nx<0 || nx>12 || ny<0 || ny>12) return; + if (core.status.checkBlockMap[13*nx+ny]%1000000>0) { + isZone = true; + } + }) + return isZone; +} + +core.prototype.hasBetweenAttack = function(x,y) { + if (!core.isset(core.status.checkBlockMap)) core.updateCheckBlockMap(); + // 夹击 + if (x>0 && x<12) { + var id1=parseInt(core.status.checkBlockMap[13*(x-1)+y]/1000000), + id2=parseInt(core.status.checkBlockMap[13*(x+1)+y]/1000000); + if (id1>0 && id1==id2) + return true; + } + if (y>0 && y<12) { + var id1=parseInt(core.status.checkBlockMap[13*x+y-1]/1000000), + id2=parseInt(core.status.checkBlockMap[13*x+y+1]/1000000); + if (id1>0 && id1==id2) + return true; + } +} + core.prototype.setFg = function(color, time, callback) { time = time || 750; core.setOpacity('fg', 1); - var fromAlpha = 0; - if (core.isset(core.status.event.data.currentColor)) { - fromAlpha = 1; - } - else { - core.status.event.data.currentColor = [0,0,0]; + var reset = false; + + if (!core.isset(core.status.event.data.currentColor)) { + core.status.event.data.currentColor = [0,0,0,0]; } var fromColor = core.status.event.data.currentColor; - var toAlpha = 1; if (!core.isset(color)) { - color = [0,0,0]; - toAlpha=0; + color = [0,0,0,0]; + reset = true; } + if (color.length==3) { + color.push(1); + } + if (color[3]<0) color[3]=0; + if (color[3]>1) color[3]=1; var step=0; var changeAnimate = setInterval(function() { step++; core.clearMap('fg', 0, 0, 416, 416); - var nowAlpha = fromAlpha+(toAlpha-fromAlpha)*step/25; + var nowAlpha = fromColor[3]+(color[3]-fromColor[3])*step/25; var nowR = parseInt(fromColor[0]+(color[0]-fromColor[0])*step/25); var nowG = parseInt(fromColor[1]+(color[1]-fromColor[1])*step/25); var nowB = parseInt(fromColor[2]+(color[2]-fromColor[2])*step/25); @@ -2178,12 +2340,12 @@ core.prototype.setFg = function(color, time, callback) { if (nowB<0) nowB=0; if (nowB>255) nowB=255; core.setAlpha('fg', nowAlpha); - var toRGB = "#"+nowR.toString(16)+nowG.toString(16)+nowB.toString(16); + var toRGB = "#"+((1<<24)+(nowR<<16)+(nowG<<8)+nowB).toString(16).slice(1) core.fillRect('fg', 0, 0, 416, 416, toRGB); if (step>=25) { clearInterval(changeAnimate); - if (toAlpha==0) { + if (reset) { core.clearMap('fg', 0, 0, 416, 416); delete core.status.event.data.currentColor; core.setAlpha('fg', 1); @@ -2242,7 +2404,8 @@ core.prototype.updateFg = function () { // 如果存在颜色 if (core.isset(core.status.event.data) && core.isset(core.status.event.data.currentColor)) { var color=core.status.event.data.currentColor; - core.fillRect("fg",0,0,416,416,"#"+color[0].toString(16)+color[1].toString(16)+color[2].toString(16)); + core.setAlpha('fg', color[3]); + core.fillRect("fg",0,0,416,416,"#"+((1<<24)+(color[0]<<16)+(color[1]<<8)+color[2]).toString(16).slice(1)); return; } @@ -2254,32 +2417,54 @@ core.prototype.updateFg = function () { if (!core.hasItem('book')) return; core.setFont('fg', "bold 11px Arial"); var hero_hp = core.status.hero.hp; - for (var b = 0; b < mapBlocks.length; b++) { - var x = mapBlocks[b].x, y = mapBlocks[b].y; - if (core.isset(mapBlocks[b].event) && mapBlocks[b].event.cls == 'enemys' && mapBlocks[b].event.trigger=='battle' + if (core.flags.displayEnemyDamage) { + core.canvas.fg.textAlign = 'left'; + for (var b = 0; b < mapBlocks.length; b++) { + var x = mapBlocks[b].x, y = mapBlocks[b].y; + if (core.isset(mapBlocks[b].event) && mapBlocks[b].event.cls == 'enemys' && mapBlocks[b].event.trigger == 'battle' && !(core.isset(mapBlocks[b].enable) && !mapBlocks[b].enable)) { - var id = mapBlocks[b].event.id; + var id = mapBlocks[b].event.id; - var damage = core.enemys.getDamage(id); - var color = "#000000"; - if (damage <= 0) color = '#00FF00'; - else if (damage < hero_hp / 3) color = '#FFFFFF'; - else if (damage < hero_hp * 2 / 3) color = '#FFFF00'; - else if (damage < hero_hp) color = '#FF7F00'; - else color = '#FF0000'; + var damage = core.enemys.getDamage(id); + var color = "#000000"; + if (damage <= 0) color = '#00FF00'; + else if (damage < hero_hp / 3) color = '#FFFFFF'; + else if (damage < hero_hp * 2 / 3) color = '#FFFF00'; + else if (damage < 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"; - core.setFillStyle('fg', '#000000'); - core.canvas.fg.fillText(damage, 32 * x + 2, 32 * (y + 1) - 2); - core.canvas.fg.fillText(damage, 32 * x, 32 * (y + 1) - 2); - core.canvas.fg.fillText(damage, 32 * x + 2, 32 * (y + 1)); - core.canvas.fg.fillText(damage, 32 * x, 32 * (y + 1)); + core.setFillStyle('fg', '#000000'); + core.canvas.fg.fillText(damage, 32 * x + 2, 32 * (y + 1) - 2); + core.canvas.fg.fillText(damage, 32 * x, 32 * (y + 1) - 2); + core.canvas.fg.fillText(damage, 32 * x + 2, 32 * (y + 1)); + core.canvas.fg.fillText(damage, 32 * x, 32 * (y + 1)); - core.setFillStyle('fg', color); - core.canvas.fg.fillText(damage, 32 * x + 1, 32 * (y + 1) - 1); + core.setFillStyle('fg', color); + core.canvas.fg.fillText(damage, 32 * x + 1, 32 * (y + 1) - 1); + } + } + } + // 如果是领域&夹击 + if (core.flags.displayExtraDamage) { + core.canvas.fg.textAlign = 'center'; + for (var x=0;x<13;x++) { + for (var y=0;y<13;y++) { + var damage = core.status.checkBlock[13*x+y]; + if (damage>0) { + core.setFillStyle('fg', '#000000'); + core.canvas.fg.fillText(damage, 32 * x + 17, 32 * (y + 1) - 13); + core.canvas.fg.fillText(damage, 32 * x + 15, 32 * (y + 1) - 15); + core.canvas.fg.fillText(damage, 32 * x + 17, 32 * (y + 1) - 15); + core.canvas.fg.fillText(damage, 32 * x + 15, 32 * (y + 1) - 13); + + core.setFillStyle('fg', '#FF7F00'); + core.canvas.fg.fillText(damage, 32 * x + 16, 32 * (y + 1) - 14); + } + } } } } @@ -2341,6 +2526,16 @@ core.prototype.addItem = function (itemId, itemNum) { core.status.hero.items[itemCls][itemId] += itemNum; } +core.prototype.getNextItem = function() { + if (!core.status.heroStop || !core.flags.enableGentleClick) return; + var nextX = core.nextX(), nextY = core.nextY(); + var block = core.getBlock(nextX, nextY); + if (block==null) return; + if (block.block.event.trigger=='getItem') { + core.getItem(block.block.event.id, 1, nextX, nextY); + } +} + core.prototype.getItem = function (itemId, itemNum, itemX, itemY, callback) { // core.getItemAnimate(itemId, itemNum, itemX, itemY); core.playSound('item', 'ogg'); @@ -2368,6 +2563,7 @@ core.prototype.drawTip = function (text, itemIcon) { core.setFont('data', "16px Arial"); core.saveCanvas('data'); core.setOpacity('data', 0); + core.canvas.data.textAlign = 'left'; if (!core.isset(itemIcon)) { textX = 16; textY = 18; @@ -2845,6 +3041,7 @@ core.prototype.saveData = function(dataId) { 'hard': core.status.hard, 'maps': core.maps.save(core.status.maps), 'shops': {}, + 'flags': core.flags, 'version': core.firstData.version, "time": new Date().getTime() }; @@ -2862,7 +3059,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, data.flags, core.maps.load(data.maps)); // load shop times for (var shop in core.status.shops) { @@ -3038,7 +3235,6 @@ core.prototype.updateStatusBar = function () { core.statusBar.weak.innerHTML = core.hasFlag('weak')?"衰":""; core.statusBar.curse.innerHTML = core.hasFlag('curse')?"咒":""; } - core.statusBar.hard.innerHTML = core.status.hard; if (core.hasItem('book')) { @@ -3051,6 +3247,7 @@ core.prototype.updateStatusBar = function () { } else { core.statusBar.image.fly.style.opacity = 0.3; } + core.updateCheckBlock(); core.updateFg(); } diff --git a/libs/data.js b/libs/data.js index f298e063..d91af1c6 100644 --- a/libs/data.js +++ b/libs/data.js @@ -111,12 +111,12 @@ data.prototype.init = function() { 'breakArmor': 0.9, // 破甲的比例(战斗前,怪物附加角色防御的x%作为伤害) 'counterAttack': 0.1, // 反击的比例(战斗时,怪物每回合附加角色攻击的x%作为伤害,无视角色防御) 'purify': 3, // 净化的比例(战斗前,怪物附加勇士魔防的x倍作为伤害) + 'hatred': 2, // 仇恨属性中,每杀死一个怪物获得的仇恨值 /****** 系统相关 ******/ 'animateSpeed': 500, // 动画时间 } // 系统FLAG,在游戏运行中中请不要修改它。 this.flags = { - /****** 角色状态相关 ******/ "enableMDef": true, // 是否涉及勇士的魔防值;如果此项为false,则状态栏不会显示勇士的魔防值 "enableExperience": true, // 是否涉及经验值;如果此项为false,则状态栏和怪物手册均将不会显示经验值 @@ -124,11 +124,14 @@ data.prototype.init = function() { /****** 道具相关 ******/ "flyNearStair": true, // 是否需要在楼梯边使用传送器 "pickaxeFourDirections": true, // 使用破墙镐是否四个方向都破坏;如果false则只破坏面前的墙壁 + "bombFourDirections": true, // 使用炸弹是否四个方向都会炸;如果false则只炸面前的怪物(即和圣锤等价) "bigKeyIsBox": false, // 如果此项为true,则视为钥匙盒,红黄蓝钥匙+1;若为false,则视为大黄门钥匙 - /****** 系统相关 ******/ "startDirectly": false, // 点击“开始游戏”后是否立刻开始游戏而不显示难度选择界面 - "battleAnimate": true, // 是否默认显示战斗动画;用户可以手动在菜单栏中关闭 + "battleAnimate": true, // 是否默认显示战斗动画;用户可以手动在菜单栏中开关 + "displayEnemyDamage": true, // 是否地图怪物显伤;用户可以手动在菜单栏中开关 + "displayExtraDamage": false, // 是否地图高级显伤(领域、夹击等);用户可以手动在菜单栏中开关 + "enableGentleClick": true, // 是否允许轻触(获得面前物品) "portalWithoutTrigger": true, // 经过楼梯、传送门时是否能“穿透”。穿透的意思是,自动寻路得到的的路径中间经过了楼梯,行走时是否触发楼层转换事件 "potionWhileRouting": false, // 寻路算法是否经过血瓶;如果该项为false,则寻路算法会自动尽量绕过血瓶 } diff --git a/libs/enemys.js b/libs/enemys.js index 04611d30..a5e8b71f 100644 --- a/libs/enemys.js +++ b/libs/enemys.js @@ -63,7 +63,7 @@ enemys.prototype.init = function () { 'poisonZombie': {'name': '绿兽人', 'hp': 100, 'atk': 120, 'def': 0, 'money': 13, 'experience': 0, 'special': 12}, 'magicDragon': {'name': '魔龙', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0}, 'octopus': {'name': '血影', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0}, - 'fairy': {'name': '仙子', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0}, + 'darkFairy': {'name': '仙子', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0}, 'greenKnight': {'name': '强盾骑士', 'hp': 0, 'atk': 0, 'def': 0, 'money': 0, 'experience': 0, 'special': 0}, } } @@ -99,6 +99,7 @@ enemys.prototype.getSpecialText = function (enemyId) { if (this.hasSpecial(special, 14)) text.push("诅咒"); if (this.hasSpecial(special, 15)) text.push("领域"); if (this.hasSpecial(special, 16)) text.push("夹击"); + if (this.hasSpecial(special, 17)) text.push("仇恨"); return text.join(" "); } @@ -118,6 +119,9 @@ enemys.prototype.getExtraDamage = function (monster) { extra_damage = core.status.hero.hp * monster.value; extra_damage = parseInt(extra_damage); } + if (this.hasSpecial(monster.special, 17)) { // 仇恨 + extra_damage += core.getFlag('hatred', 0); + } return extra_damage; } diff --git a/libs/events.js b/libs/events.js index c90a3cfa..fac9f95e 100644 --- a/libs/events.js +++ b/libs/events.js @@ -34,11 +34,6 @@ events.prototype.init = function () { if (core.isset(callback)) callback(); }, - "checkBlock": function (data, core, callback) { - core.events.checkBlock(data.x, data.y); - if (core.isset(callback)) - callback(); - }, "changeLight": function (data, core, callback) { core.events.changeLight(data.x, data.y); if (core.isset(callback)) @@ -112,53 +107,9 @@ events.prototype.lose = function(reason) { }) } - -////// 检查领域、夹击事件 ////// -events.prototype.checkBlock = function (x,y) { - var damage = 0; - // 获得四个方向的怪物 - var directions = [[0,-1],[-1,0],[0,1],[1,0]]; // 上,左,下,右 - var enemys = [null,null,null,null]; - for (var i in directions) { - var block = core.getBlock(x+directions[i][0], y+directions[i][1]); - if (block==null) continue; - // 是怪物 - if (block.block.event.cls=='enemys') - enemys[i]=core.material.enemys[block.block.event.id]; - } - - // 领域 - for (var i in enemys) { - if (enemys[i]!=null && core.enemys.hasSpecial(enemys[i].special, 15)) { - damage+=enemys[i].value; - } - } - if (damage>0) - core.drawTip('受到领域伤害'+damage+'点'); - core.status.hero.hp-=damage; - if (core.status.hero.hp<=0) { - core.status.hero.hp=0; - core.updateStatusBar(); - core.events.lose('zone'); - return; - } - - // 夹击 - var has=false; - if (enemys[0]!=null && enemys[2]!=null && enemys[0].id==enemys[2].id && core.enemys.hasSpecial(enemys[0].special, 16)) - has=true; - if (enemys[1]!=null && enemys[3]!=null && enemys[1].id==enemys[3].id && core.enemys.hasSpecial(enemys[1].special, 16)) - has=true; - if (has && core.status.hero.hp>1) { // 1血夹击不死 - core.status.hero.hp = parseInt(core.status.hero.hp/2); - core.drawTip('受到夹击,生命变成一半'); - } - core.updateStatusBar(); -} - ////// 转换楼层结束的事件 ////// events.prototype.afterChangeFloor = function (floorId) { - if (!core.hasFlag("visited_"+floorId)) { + if (!core.isset(core.status.event.id) && !core.hasFlag("visited_"+floorId)) { this.doEvents(core.floors[floorId].firstArrive); core.setFlag("visited_"+floorId, true); } @@ -212,6 +163,9 @@ events.prototype.doAction = function() { case "text": // 文字/对话 core.ui.drawTextBox(data.data); break; + case "tip": + core.drawTip(core.replaceText(data.text)); + core.events.doAction(); case "show": // 显示 if (core.isset(data.time) && data.time>0 && (!core.isset(data.floorId) || data.floorId==core.status.floorId)) { core.animateBlock(data.loc[0],data.loc[1],'show', data.time, function () { @@ -350,8 +304,16 @@ events.prototype.doAction = function() { } } catch (e) {console.log(e)} - core.updateStatusBar(); - this.doAction(); + if (core.status.hero.hp<=0) { + core.status.hero.hp=0; + core.updateStatusBar(); + core.events.lose('damage'); + + } + else { + core.updateStatusBar(); + this.doAction(); + } break; case "if": // 条件判断 if (core.calValue(data.condition)) @@ -451,8 +413,10 @@ events.prototype.disableQuickShop = function (shopId) { } ////// 降低难度 ////// -/* + events.prototype.decreaseHard = function() { + core.drawTip("本塔不支持降低难度!"); + /* if (core.status.hard == 0) { core.drawTip("当前已是难度0,不能再降低难度了"); return; @@ -470,8 +434,8 @@ events.prototype.decreaseHard = function() { }, function () { core.ui.drawSettings(false); }); + */ } -*/ ////// 能否使用快捷商店 ////// events.prototype.canUseQuickShop = function(shopIndex) { @@ -506,20 +470,24 @@ events.prototype.afterBattle = function(enemyId,x,y,callback) { // 中毒 if (core.enemys.hasSpecial(special, 12) && !core.hasFlag('poison')) { core.setFlag('poison', true); - core.updateStatusBar(); } // 衰弱 if (core.enemys.hasSpecial(special, 13) && !core.hasFlag('weak')) { core.setFlag('weak', true); core.status.hero.atk-=core.values.weakValue; core.status.hero.def-=core.values.weakValue; - core.updateStatusBar(); } // 诅咒 if (core.enemys.hasSpecial(special, 14) && !core.hasFlag('curse')) { core.setFlag('curse', true); - core.updateStatusBar(); } + // 仇恨属性:减半 + if (core.enemys.hasSpecial(special, 17)) { + core.setFlag('hatred', parseInt(core.getFlag('hatred', 0)/2)); + } + // 增加仇恨值 + core.setFlag('hatred', core.getFlag('hatred',0)+core.values.hatred); + core.updateStatusBar(); // 如果已有事件正在处理中 if (core.status.lockControl) { @@ -604,11 +572,11 @@ events.prototype.changeLight = function(x, y) { core.canvas.event.clearRect(x * 32, y * 32, 32, 32); var blockIcon = core.material.icons[block.event.cls][block.event.id]; core.canvas.event.drawImage(core.material.images[block.event.cls], 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32); - this.afterChangeLight(); + this.afterChangeLight(x,y); } // 改变灯后的事件 -events.prototype.afterChangeLight = function() { +events.prototype.afterChangeLight = function(x,y) { } @@ -822,21 +790,48 @@ events.prototype.clickSL = function(x,y) { } } -// 菜单栏 -events.prototype.clickSettings = function (x,y) { +events.prototype.clickSwitchs = function (x,y) { if (x<5 || x>7) return; - if (y == 3) { + if (y==4) { if (core.musicStatus.isIOS) { core.drawTip("iOS设备不支持播放音乐"); return; } core.changeSoundStatus(); + core.ui.drawSwitchs(); + } + if (y==5) { + core.flags.battleAnimate=!core.flags.battleAnimate; + core.ui.drawSwitchs(); + } + if (y==6) { + core.flags.displayEnemyDamage=!core.flags.displayEnemyDamage; + core.updateFg(); + core.ui.drawSwitchs(); + } + if (y==7) { + core.flags.displayExtraDamage=!core.flags.displayExtraDamage; + core.updateFg(); + core.ui.drawSwitchs(); + } + if (y==8) { core.ui.drawSettings(false); } +} + +// 菜单栏 +events.prototype.clickSettings = function (x,y) { + if (x<5 || x>7) return; + if (y == 3) { + core.ui.drawSwitchs(); + } if (y==4) { + /* core.flags.battleAnimate=!core.flags.battleAnimate; core.setLocalStorage('battleAnimate', core.flags.battleAnimate); core.ui.drawSettings(false); + */ + this.decreaseHard(); } if (y == 5) core.ui.drawQuickShop(); // if (y == 5) this.decreaseHard(); diff --git a/libs/floors/MT0.js b/libs/floors/MT0.js index 9d66ec6b..32000498 100644 --- a/libs/floors/MT0.js +++ b/libs/floors/MT0.js @@ -27,14 +27,6 @@ main.floors.MT0 = { }, "afterOpenDoor": { // 开完门后可能触发的事件列表 - }, - "checkBlock": [ - /****** 领域、夹击检查事件 ******/ - // 所有可能的领域、夹击点均需要在这里给出,否则将不会触发检查事件 - // 另外,如果该点已经存在events事件或changeFloor事件(即上面有相同点位置定义),则会被覆盖 - // afterBattle, afterGetItem, afterOpenDoor则不受影响(仍能正常工作)。 - // 所以 |****** 强烈要求可能的夹击、领域点不要存在自定义事件!! ******| - ] - + } } diff --git a/libs/floors/sample0.js b/libs/floors/sample0.js index e3952451..5f296247 100644 --- a/libs/floors/sample0.js +++ b/libs/floors/sample0.js @@ -59,9 +59,8 @@ main.floors.sample0 = { "\t[老人,magician]模仿、吸血、中毒、衰弱、诅咒。\n\n请注意吸血怪需要设置value为吸血数值,可参见样板中黑暗大法师的写法。", {"type": "hide", "time": 500} ], - "2,3": [ // 守着第三批怪物额老人 + "2,3": [ // 守着第三批怪物的老人 "\t[老人,magician]领域、夹击。\n请注意领域怪需要设置value为伤害数值,可参见样板中初级巫师的写法。", - "\t[老人,magician]出于游戏性能的考虑,我们不可能每走一步都对领域和夹击进行检查。\n因此我们需要在本楼层的 checkBlock 中指明哪些点可能会触发领域和夹击事件,在这些点才会对领域和夹击进行检查和处理。\n具体可参见本层 checkBlock 的写法。", "\t[老人,magician]夹击和领域同时发生时先计算领域,再夹击。\n自动寻路同样会尽量绕过你设置的这些点。\n\n另:本塔不支持阻击怪。", {"type": "hide", "time": 500} ], @@ -99,7 +98,7 @@ main.floors.sample0 = { ], "10,5": ["破墙镐是破面前的墙壁还是四个方向的墙壁,由data.js中的系统Flag所决定。"], "8,4": [ - "炸弹可以炸四个方向的怪物。\n如只需要炸前方怪物请使用上面的圣锤。\n不能被炸的怪物在enemys中可以定义,可参见样板里黑衣魔王和黑暗大法师的写法。", + "炸弹是只能炸面前的怪物还是四个方向的怪物,由data.js中的系统Flag所决定。\n如只能炸前方怪物则和上面的圣锤等价。\n不能被炸的怪物在enemys中可以定义,可参见样板里黑衣魔王和黑暗大法师的写法。", ], "10,4": ["“上楼”和“下楼”的目标层由 main.js 的 floorIds顺序所决定。"], "10,3": ["十字架目前未被定义,可能需要自行实现功能。\n有关如何实现一个道具功能参见doc文档。"], @@ -108,15 +107,7 @@ main.floors.sample0 = { }, "afterOpenDoor": { // 开完门后可能触发的事件列表 "11,12": ["你开了一个绿门,触发了一个afterOpenDoor事件"] - }, - "checkBlock": [ - /****** 领域、夹击检查事件 ******/ - // 所有可能的领域、夹击点均需要在这里给出,否则将不会触发检查事件 - // 另外,如果该点已经存在events事件或changeFloor事件(即上面有相同点位置定义),则会被覆盖 - // afterBattle, afterGetItem, afterOpenDoor则不受影响(仍能正常工作)。 - // 所以 |****** 强烈要求可能的夹击、领域点不要存在自定义事件!! ******| - "1,0", "3,0", "0,1", "2,1", "4,1", "1,2", "3,2" - ] + } } diff --git a/libs/floors/sample1.js b/libs/floors/sample1.js index 74cfca5f..9a29892b 100644 --- a/libs/floors/sample1.js +++ b/libs/floors/sample1.js @@ -30,7 +30,7 @@ main.floors.sample1 = { "4,10": [ // 走到中间时的提示 "\t[样板提示]本层楼将会对各类事件进行介绍。", "左边是一个仿50层的陷阱做法,上方是商店、快捷商店的使用方法,右上是一个典型的杀怪开门的例子,右下是各类可能的NPC事件。", - "本样板目前支持的事件列表大致有:\ntext: 显示一段文字(比如你现在正在看到的)\nshow: 使一个事件有效(可见、可被交互)\nhide: 使一个事件失效(不可见、不可被交互)\ntrigger: 触发另一个地点的事件\nbattle: 强制和某怪物战斗\nopenDoor: 无需钥匙开门(例如机关门、暗墙)\nopenShop: 打开一个全局商店\ndisableShop: 禁用一个全局商店\nchangeFloor: 传送勇士到某层某位置\nchangePos: 传送勇士到当层某位置;转向\nsetFg: 更改画面色调", + "本样板目前支持的事件列表大致有:\ntext: 显示一段文字(比如你现在正在看到的)\ntip: 左上角显示提示\nshow: 使一个事件有效(可见、可被交互)\nhide: 使一个事件失效(不可见、不可被交互)\ntrigger: 触发另一个地点的事件\nbattle: 强制和某怪物战斗\nopenDoor: 无需钥匙开门(例如机关门、暗墙)\nopenShop: 打开一个全局商店\ndisableShop: 禁用一个全局商店\nchangeFloor: 传送勇士到某层某位置\nchangePos: 传送勇士到当层某位置;转向\nsetFg: 更改画面色调", "move: 移动事件效果\nmoveHero: 移动勇士效果\nplaySound: 播放某个音频\nif: 条件判断\nchoices: 提供选项\nsetValue: 设置勇士属性道具,或某个变量/flag\nupdate: 更新状态栏和地图显伤\nwin: 获得胜利(游戏通关)\nlose: 游戏失败\nsleep: 等待多少毫秒\nexit: 立刻结束当前事件\nrevisit: 立刻结束事件并重新触发\nfunction: 自定义JS脚本\n更多支持的事件还在编写中,欢迎您宝贵的意见。", "有关各事件的样例,可参见本层一些NPC的写法。\n所有事件样例本层都有介绍。\n\n一个自定义事件处理完后,需要调用{\"type\": \"hide\"}该事件才不会再次出现。", {"type": "hide"} @@ -299,14 +299,6 @@ main.floors.sample1 = { }, "afterOpenDoor": { // 开完门后可能触发的事件列表 - }, - "checkBlock": [ - /****** 领域、夹击检查事件 ******/ - // 所有可能的领域、夹击点均需要在这里给出,否则将不会触发检查事件 - // 另外,如果该点已经存在events事件或changeFloor事件(即上面有相同点位置定义),则会被覆盖 - // afterBattle, afterGetItem, afterOpenDoor则不受影响(仍能正常工作)。 - // 所以 |****** 强烈要求可能的夹击、领域点不要存在自定义事件!! ******| - ] - + } } diff --git a/libs/floors/sample2.js b/libs/floors/sample2.js index b0bc470d..9dfe71b5 100644 --- a/libs/floors/sample2.js +++ b/libs/floors/sample2.js @@ -365,14 +365,6 @@ main.floors.sample2 = { }, "afterOpenDoor": { // 开完门后可能触发的事件列表 - }, - "checkBlock": [ - /****** 领域、夹击检查事件 ******/ - // 所有可能的领域、夹击点均需要在这里给出,否则将不会触发检查事件 - // 另外,如果该点已经存在events事件或changeFloor事件(即上面有相同点位置定义),则会被覆盖 - // afterBattle, afterGetItem, afterOpenDoor则不受影响(仍能正常工作)。 - // 所以 |****** 强烈要求可能的夹击、领域点不要存在自定义事件!! ******| - ] - + } } diff --git a/libs/icons.js b/libs/icons.js index 0d54cad5..48750086 100644 --- a/libs/icons.js +++ b/libs/icons.js @@ -144,7 +144,7 @@ icons.prototype.init = function () { 'poisonZombie': 55, 'magicDragon': 56, 'octopus': 57, - 'fairy': 58, + 'darkFairy': 58, 'greenKnight': 59, }, 'items': { diff --git a/libs/items.js b/libs/items.js index bcd74911..e2a36c8a 100644 --- a/libs/items.js +++ b/libs/items.js @@ -46,7 +46,7 @@ items.prototype.init = function () { 'steelKey': {'cls': 'tools', 'name': '铁门钥匙', 'text': '可以打开一扇铁门'}, 'pickaxe': {'cls': 'tools', 'name': '破墙镐', 'text': '可以破坏勇士面前的墙'}, 'icePickaxe': {'cls': 'tools', 'name': '破冰镐', 'text': '可以破坏勇士面前的一堵冰墙'}, - 'bomb': {'cls': 'tools', 'name': '炸弹', 'text': '可以炸掉勇士四周的怪物'}, + 'bomb': {'cls': 'tools', 'name': '炸弹', 'text': '可以炸掉勇士面前的怪物'}, 'centerFly': {'cls': 'tools', 'name': '中心对称飞行器', 'text': '可以飞向当前楼层中心对称的位置'}, 'upFly': {'cls': 'tools', 'name': '上楼器', 'text': '可以飞往楼上的相同位置'}, 'downFly': {'cls': 'tools', 'name': '下楼器', 'text': '可以飞往楼下的相同位置'}, @@ -67,6 +67,8 @@ items.prototype.getItems = function () { // 面前的墙?四周的墙? if (core.flags.pickaxeFourDirections) this.items.pickaxe.text = "可以破坏勇士四周的墙"; + if (core.flags.bombFourDirections) + this.items.bomb.text = "可以炸掉勇士四周的怪物"; return this.items; } @@ -247,7 +249,8 @@ items.prototype.canUseItem = function (itemId) { if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable) && block.event.cls == 'enemys' && Math.abs(block.x-core.status.hero.loc.x)+Math.abs(block.y-core.status.hero.loc.y)<=1) { var enemy = core.material.enemys[block.event.id]; if (core.isset(enemy.bomb) && !enemy.bomb) continue; - ids.push(i); + if (core.flags.bombFourDirections || (block.x==core.nextX() && block.y==core.nextY())) + ids.push(i); } } if (ids.length>0) { diff --git a/libs/maps.js b/libs/maps.js index d10c21ee..f03c634f 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -36,8 +36,6 @@ maps.prototype.loadFloor = function (floorId, map) { } this.addEvent(block,j,i,floor.events[j+","+i]) this.addChangeFloor(block,j,i,floor.changeFloor[j+","+i]); - if (floor.checkBlock.indexOf(j+","+i)>=0) - this.addEvent(block,j,i,{"trigger":"checkBlock"}); if (core.isset(block.event)) blocks.push(block); } } @@ -78,7 +76,6 @@ maps.prototype.getBlock = function (x, y, id) { if (id == 12) tmp.event = {'cls': 'animates', 'id': 'poisonNet', 'noPass': false, 'trigger': 'passNet'}; // 毒网 if (id == 13) tmp.event = {'cls': 'animates', 'id': 'weakNet', 'noPass': false, 'trigger': 'passNet'}; // 衰网 if (id == 14) tmp.event = {'cls': 'animates', 'id': 'curseNet', 'noPass': false, 'trigger': 'passNet'}; // 咒网 - if (id == 15) tmp.event = {'cls': 'animates', 'id': 'water', 'noPass': true}; // 水 // autotile: 20 @@ -229,7 +226,7 @@ maps.prototype.getBlock = function (x, y, id) { if (id == 256) tmp.event = {'cls': 'enemys', 'id': 'poisonZombie'}; if (id == 257) tmp.event = {'cls': 'enemys', 'id': 'magicDragon'}; if (id == 258) tmp.event = {'cls': 'enemys', 'id': 'octopus'}; - if (id == 259) tmp.event = {'cls': 'enemys', 'id': 'fairy'}; + if (id == 259) tmp.event = {'cls': 'enemys', 'id': 'darkFairy'}; if (id == 260) tmp.event = {'cls': 'enemys', 'id': 'greenKnight'}; return tmp; diff --git a/libs/ui.js b/libs/ui.js index 71c7484c..0acbb2b3 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -302,6 +302,30 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) { core.fillText('ui', "取消", 208 + 38, top + bottom - 35); } +////// 绘制开关界面 ////// +ui.prototype.drawSwitchs = function() { + // 背景音乐、背景音效、战斗动画、怪物显伤、领域显伤、返回 + + core.status.event.id = 'switchs'; + + var background = core.canvas.ui.createPattern(core.material.ground, "repeat"); + core.clearMap('ui', 0, 0, 416, 416); + core.setAlpha('ui', 1); + core.setFillStyle('ui', background); + var left = 97, top = 64 + 32, right = 416 - 2 * left, 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', "背景音乐: " + (core.musicStatus.soundStatus ? "[ON]" : "[OFF]"), 208, top + 56, "#FFFFFF", "bold 17px Verdana"); + // core.fillText('ui', "背景音效" + (core.musicStatus.soundStatus ? "[ON]" : "[OFF]"), 208, top + 88, "#FFFFFF", "bold 17px Verdana") + core.fillText('ui', "战斗动画: " + (core.flags.battleAnimate ? "[ON]" : "[OFF]"), 208, top + 88, "#FFFFFF", "bold 17px Verdana") + core.fillText('ui', "怪物显伤: " + (core.flags.displayEnemyDamage ? "[ON]" : "[OFF]"), 208, top + 120, "#FFFFFF", "bold 17px Verdana") + core.fillText('ui', "领域显伤: " + (core.flags.displayExtraDamage ? "[ON]" : "[OFF]"), 208, top + 152, "#FFFFFF", "bold 17px Verdana") + + core.fillText('ui', "返回上级菜单", 208, top + 184, "#FFFFFF", "bold 17px Verdana"); +} + /** * 绘制菜单栏 * @param need @@ -319,8 +343,8 @@ ui.prototype.drawSettings = function (need) { core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2); core.canvas.ui.textAlign = "center"; - core.fillText('ui', "音乐: " + (core.musicStatus.soundStatus ? "[ON]" : "[OFF]"), 208, top + 56, "#FFFFFF", "bold 17px Verdana"); - core.fillText('ui', '战斗过程: ' +(core.flags.battleAnimate?'[ON]':'[OFF]'), 208, top + 88, "#FFFFFF", "bold 17px Verdana") + core.fillText('ui', "系统设置", 208, top + 56, "#FFFFFF", "bold 17px Verdana"); + core.fillText('ui', "降低难度", 208, top + 88, "#FFFFFF", "bold 17px Verdana") core.fillText('ui', "快捷商店", 208, top + 120, "#FFFFFF", "bold 17px Verdana"); core.fillText('ui', "同步存档", 208, top + 152, "#FFFFFF", "bold 17px Verdana"); // core.fillText('ui', "清空存档", 208, top + 152, "#FFFFFF", "bold 17px Verdana"); @@ -358,8 +382,7 @@ ui.prototype.drawQuickShop = function (need) { core.fillText('ui', shopList[keys[i]].textInList, 208, top + 56 + 32 * i, "#FFFFFF", "bold 17px Verdana"); } - core.fillText('ui', "返回游戏", 208, top + bottom - 40); - + core.fillText('ui', "返回游戏", 208, top + bottom - 40, "#FFFFFF", "bold 17px Verdana"); } ui.prototype.drawBattleAnimate = function(monsterId, callback) { @@ -395,10 +418,15 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) { if (core.enemys.hasSpecial(mon_special, 6)) turns=5; - // 初始伤害(破甲、净化) + // 初始伤害 var initDamage = 0; if (core.enemys.hasSpecial(mon_special, 7)) initDamage+=parseInt(core.values.breakArmor * hero_def); - if (core.enemys.hasSpecial(mon_special, 9)) initDamage=parseInt(core.values.purify * hero_mdef); + if (core.enemys.hasSpecial(mon_special, 9)) initDamage+=parseInt(core.values.purify * hero_mdef); + if (core.enemys.hasSpecial(mon_special, 11)) { // 吸血 + var extraDamage = monster.value * hero_hp; + initDamage+=parseInt(extraDamage); + } + if (core.enemys.hasSpecial(mon_special, 17)) initDamage+=core.getFlag('hatred', 0); hero_mdef-=initDamage; if (hero_mdef<0) { hero_hp+=hero_mdef; @@ -425,6 +453,7 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) { core.fillRect('ui', left, top, right, bottom, '#000000'); core.setAlpha('ui', 1); core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2); + core.clearMap('data',0,0,416,416); core.setAlpha('data', 1); core.setOpacity('data', 1); core.status.boxAnimateObjs = []; diff --git a/启动服务.exe b/启动服务.exe new file mode 100644 index 00000000..e6f4a85c Binary files /dev/null and b/启动服务.exe differ diff --git a/常用工具/Jint.dll b/常用工具/Jint.dll new file mode 100644 index 00000000..437d2bb2 Binary files /dev/null and b/常用工具/Jint.dll differ diff --git a/常用工具/地图生成器.exe b/常用工具/地图生成器.exe index 67eda508..541b3626 100644 Binary files a/常用工具/地图生成器.exe and b/常用工具/地图生成器.exe differ diff --git a/更新内容.txt b/更新内容.txt deleted file mode 100644 index 204a5f44..00000000 --- a/更新内容.txt +++ /dev/null @@ -1,11 +0,0 @@ -新增:本地服务器 -新增:可视化地图编辑工具 -新增:便捷P图工具 √ -新增:支持Autotile √ -新增:怪物支持多属性 √ -新增:单向箭头、感叹号 √ -新增:勇士支持移动;其他事件支持移动 √ -快捷道具使用:1破2炸3飞;读档改为D键 √ -更多的默认素材;无需P图,直接替换即可 √ -破甲、反击、净化等效果放全局变量 √ -细节优化和Bug修复 √