diff --git a/README.md b/README.md index 2a03e535..66369b8a 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! ``` bash ├── /_server/ # 为可视化地图编辑器提供一些支持的目录 ├── /docs/ # 文档目录 +├── /animates/ # 动画目录 ├── /images/ # 所有图片素材目录 │ ├─ /常用素材/ # 可以被直接替换的素材 │ └─ *.png # 对应的某个具体的图片素材 @@ -32,6 +33,7 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! │ └─ ui.js # UI绘制信息,主要负责绘制各个UI窗口。 ├── /sounds/ # 音效目录 ├── /常用工具/ # 一些常用工具,可以辅助造塔 +│ ├─ RM动画导出器.exe # 能从RMXP中导出动画,以供H5使用。 http://github.com/ckcz123/animate_export/ │ ├─ JS代码压缩工具.exe # 能对Javascript代码进行压缩和整合,从而减少IO请求量。 http://github.com/ckcz123/JSCompressor/ │ ├─ 便捷PS工具.exe # 能只用复制和粘贴来快速对素材进行PS操作。 http://github.com/ckcz123/ps/ │ ├─ 地图生成器.exe # 能从一张截图识别出来具体的数字数组,方便复刻已有的塔。 http://github.com/ckcz123/map_generator/ @@ -45,6 +47,33 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! ## 更新说明 +### 2018.2.9 V1.4.1 + +* [x] 改变图块(setBlock事件)。 +* [x] 同一个点的多事件处理(做法详见文档)。 +* [x] 地图中每个块的可通行方向控制(悬崖效果)。 +* [x] 动画支持带旋转和翻转的帧。 +* [x] 现在可以允许用户丢弃道具了(例如不会再使用的装备)。 +* [x] 修复行走时按键会发生动画抖动问题。 +* [x] 修复无法打开战斗动画的Bug。 + +### 2018.2.6 V1.4 + +* [x] 支持动画。 +* [x] 瞬间移动。 +* [x] 支持天气系统,可以在剧本中设置默认天气。 +* [x] 新增自定义事件-图片显示。 +* [x] 同时可以在剧本中设定多个背景素材。 +* [x] 剧情文本特性控制,人物的对话框效果。 +* [x] 单存档同步到服务器,下载到文件和读取。 +* [x] 键盘支持自动寻路操作。 +* [x] 浏览地图模式下可以查看怪物数据。 +* [x] 未成功打怪和开门则不自动存档。 +* [x] 重新支持楼梯穿透。 +* [x] 支持多结局,成绩将分开统计。 +* [x] 重构全局动画、行走动画和行走检测,大幅提升性能。 +* [x] 修复所有已知Bug。 + ### 2018.1.21 V1.3.2 * [x] 增加录像和回放功能。 diff --git a/animates/hand.animate b/animates/hand.animate new file mode 100644 index 00000000..bffc26d1 --- /dev/null +++ b/animates/hand.animate @@ -0,0 +1 @@ +{"ratio":2,"bitmaps":["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAA6+SURBVHhe7ZwPbFVVnsfJuENiQmKyCckkZs2YzO5m3HV1B0YdxDFjZEVhdHCKICOriILMrDLAbAZhBhjFURERQVhmkD+CdWyhtIXyp32F0pa29P+/R1va0pb+fe+1r+//ffffOd/93dvDi7WltgXpe2/uJzm5v3vueTSc37m/P+eecyZZWFhYWFhYWFhYWFhYWFjEEshcMU2IFjcTJM+/TYgjwrJe2yVEi5sJyqbdIcQRYVkrFCFaTASwLYcQxww/s/Qfhfj3DS/85weEOAhe+dCdQrwuyH513AqAbclMIVoMB6+b+agQrwtyloJnL50lbkcNP734J0K0MGBl/7ZTiGMC+UvA8pZkidtRw868IAnR4hrc/p8/EGIE3jbrbiEOCy6+BBS9NCYzxM8ufJpnPb9C3FpcA/YflQkxAmt78oAQhwWVS4CKl8ekAJx7btx+I64B5t+GxofXilsT3vH0HCEOC+qWAZeWg1e/eq+oGhEULFiG3PmWAq4Ha/7ZENsM5+JhoxXe+PpUXFkFo7CmNzJE9YigZCFY/nOjavt3CW994ies85lOcWvCXK+5hTiJd78zlXe/b0ZH6Nx4PxWgcwPQvnHIqGZtaz4Uogm7tCQRlYvBSxeN6m2JadTEaeOOseFYBO5aEglBWf/vI1EO7939GHPsLh2Qtz4N1zbA9RHg+GioAro27xYi+ZeNk9H0OlD/2rjMD09L+Fchxg7636YvDif9x4hRzHDQiN8J96pIR3Hve7Pg32r6Bt5/eCX6E81n3HtoBTyHgX4q7sNgfYe2GPUGvG/fBvTuWSZuJ7GOdwK4+keg+X/HrACe9ouVQow9lKTpi9Uj046J21EDL5kV/3uRqAihg2bHMW/ap/BnAM6cKSx4aicCZzBQMql9ptkGSJ4Mfzq49+gC8zfu/ZvRu5vekm1g7W+Nyf4jde6QyCzmkI9NX6mceAiwjW6CzQB+MiuhvYCUaJoyhDPA5ex7WCCvHVIhWKAwyELFEsIlQLiM2pUOXENFJBsln9qcK+T+MyvgPw54k+gt+QzcsXOe+QdGAUudHT8TfeETM95VzsyEkv3TYUcg616TxdtX3S5uJ7HA/mOQjwAKdTwvvB1KAZhcokCuBORa6uw6ul6m580DRTauV6g0UaF6mZ4rNdSOFEMKQzCblHB8kPnh7R9G/t5XMabCceLJMZuqqEe2PXpWyX8CatFTUMsTBs3FoH/jXbyfHKp/r2m3mZS6HepZQKPRrFVQsQN6I11bAPUqXTup9FBx0r2DrkYh2azrotJB9a1UDMVcIkWUkyIKvq6AIZN9yJ9/F2zPAhlPfU9UxRdS/hyvUp4A1f4i1KblLiP5Eo8mcf9BcCmFRi/ZczmPOpFMik6jXadOZO1UesA0Zx3T+t7lmnc256E7AdxGDmEK58H7uO5/lTFfCpiXfuOhQv+8bijEUIahCHtEAfCdGDLCecWvE3DxZfC85zeIqvhErv5vqA3LobX+HnrXZhq4O65y72eLeDAVPGyjzqJRr1ZRx5Ep0dvBWBcZ8J7vi5+PGlLIUmgeL/TeAUXobfTvNpByK8CCeV+KZias+d1DqFsLVrXCJaril3DVK3crjWugdrwD3bEDOoWRLEBRi3SOHG0xuEqjXmumjm//s/jJDQF47qe3pmXATBlvQyP9nQoztKSI6TbmPKyjaxfQsjn+7P71kK9salK7PoLmOkDWIpVGJHU+RTSczISuNeeKZjcVrve/AGb4DPIhKr1dEvmWIJk6z0lK5iiX6Np+l2gaX3Sfmj3VmTN/irg1MUae0rMXmvsYdH82KKQkBdTSyGz81pMepnW1mkpQyBxJ5JwDuWCe1PieH4J9/mRv8dJ0cWuiOP8Grf80KeACvQFVpID6n4lH3zpM6bJBoYhKNiKk0uuaHiMEFmLs01646vaAfR0CzVsLpc79GYoznXxkDimATE+o7iHR7JbBlFZSAvkaueovosoEsE9m/pJE4y0VVfFDoP6te0MtuxHu+hKK6zQpIB+avyJBPL7l6OqVVhYoozewlAKBgaL5SuPjc6Xj9NxhP3wHW/c3yd3HoPRmkwIKxvUt+GaiS3X8WucbRVTHB33ZCXe6C1651Fe5KpJ1Su2J6XJPBuS+s2FRNaFwuXmO5is2lXDN5uuBpgUI2uMnG/ZV/xGBhm0ItexHuPMoFOcZqO7cGeLxhKNJTT2GAvRAI5kgio7izf57696bFWzeA6n9C8jdx8n82JrEo6hAC9XNM3yB4rHromogVG7e+O+hy6vmBWuWbvCXLvyD78Izb/vOP5ntzXr8fdEsdpDaDpHzPWY6XtV1/hFRHTWo/uqQEZUpvcch9xxGuH0HpCt/QrBuNQJVL8NX8jz6834RVQNnCGqfbZXWa2tVXJk2Ci+XifKm7i8tjTg6CjtF86hC8xQ9q7rPknlMR7j7EKS2HQg2bkKg9rfwlb8Cz4VF94um0Q/6y+4gx6ZEOv0rRe8vLBHNog6lzwbZkYpwx0GErmwnv7UJ3qqV58Xj2EJq2bpAdZ0YogDVdyFq12Uqzkwa/SmQrh5AsJmChsvrvnGBcFShVP/m3nDj+kq59QMoHXuhOJKg9p0apADRNCpRek6mhDuPINS6L3byAfX8nJXyxecCatVSqPVroLa8DbVzF1TH59B6jemGfOje4phQQNhx8tVwR3J0dz42TvoOT53+T/rJR17Rsx4vUPPnetXihVyrXQ6taS209vehOfZC7zsK3ZMF3Wd8IC+hQil/oDy63wDnifukjiT4m/fo/roto/6AP6Eg59F/0Ep/laBdeq1JvbJO0zs/ht77GVj/cTDfOep0YxWDMd9SAR6qimoFwJk8RWpPQvDKX+Gv3wJv9Tr0F69Ab94LcGT/MqM78+fLujPmRPfGQM2xc5bmPiwx32nq+DzwIKX4oUqz87lUE90KoOTLeANCLXvhvfzesDt3Ygb02+7gwQLq9DIq1WbnGx9dxOOoJNR34k7hhMe86SNq4RKZHup8hO1mEdVRSdh5Zna46ygpYD8CjR8N+k4QsyBcQR1/TQGXotsJuzLflXtSKQ/4jPKAHfDXbYKvemXsLcz9KgMKMFazGZ//qKDsu+JR1KE6bXWyI50y4cPkBz5BsP5t+KvXwFu6DO6ChSNuFolKmJRfA7kUkKupkBLkOvID9tfF46hDdZ9D2Hli0Jqha3gLX5jtOT9vt9s255Coim6YNy0foRwa9cVUqqiQCZIvgcm1baJJVAFP0fc1z3mo7uOxv4WV9/3feiGa8FDZvGj3A6rvYpLuzYXmPgXKB+JrbSiXihZwiXIBoQQWtn8gHkUNLFBMWTspwHMKmutLKJ17zP0FMQ/3nvkBD+ZTIlZC4ehAMhZt+QALVf+ZBUvA/LnQvSeh9SZC69oF5cpbPaJJbKK79q1nnhQwXxaYoQT6T5pZMSVmTKrdI5pNOObACBkThjlgnuPQew9C79oOrWUD1Po3oFS8OGjDX0ygtv3JpXd/DN11sFLrSxl0ngMX80Jcrv2hqJow9GBtrpEsitsIWscHc7SWN5s0+3Jo5YugFj4D7dwT0R+KKmWLXpLty3Wt6XezRdUQ9EBRIQuWQw9UcFE1IXD50koerqbBUAY9lFspqodFvzB3g2Z7DNqpn0I9NiP6IiXkPPq9cM5Tw8bQX0f15lxl/ovmDKkeqC4W1bcUYy2q4YuMRJFLhWQes8lUpkS2to6Elvbg0+rR6W4l6UfRsedYPT5zUNj5TWjuk+TscsnmXqTRV0H+oOa0eHRLMNaicqkWerA8shGP+09NZZ7PM5jzk1ENomvwxGkP8KT7p4rbW8t4RoC53saRZMbbRthnhH+GDdbDNbfkTdBC1QkU9ZhmhwcvDhuN8ZY/xPb8z0hITe9nyB1/gepMhtZ/skH3562gEPBzIxLRpRr+bTpmzVe2Z+DLnPGFrpDCzvM0CE6NaPvjjuCldQg1b4msQDPQfPlhHio184SB6Yq6mxqiqr6CGYr7Ate8hWT6jG/U1PHeLOieE2DuJMp8D8TOmp8bwVv04tpAxf80iNsIzJdJIWnev3Bjw7U5cWcHlDowpeGGMma1/8IjsjtHUvtyoPadpWJDuCfzbtmV5tJ6U6A5P4fu+Cv07qFnTcQl7rwFQ5b2qc59V/X+I78xZB7KoyxZTN4pFKEo9eZWIlJEGw9ffn00U9mqr+hBtTcvSe3NgeKyQXJkhGVHBuSeNCopCDuTzJO54PxkitzxiaJd3QK9ZSPUy6vj+whM16m5Q/YCGKeYKB3bIltDeeA0OcccmMcNmNPYlWDh2kRzs7WhDNnYZtpASjJKHbW1UyhbQ/a8kkxKsbHfgEb5eSjOLOrsDIQ7UxFsHZhYk1oPbJeu7oN0de+gOZ5ww9rZav0qGKs69PJfTUhIPGGEG1aXC9GEe74A96cDwUxSQi51csFjRr0ROYESJgpXd5ub+aiwUM0WFiIFBSih8xZBceeb8zawJ08Ot6e4pPZEczn89Y4k+Dpq2eJPtYsJ0HLnbBZV8Y1Utngm7L+O7J7k3R9P5a5d5qEaxuEazJ8+aFMfCxbkC5FM1cACL81bJBlOVXOfo45OGtTRgcZdKwP1W+Gveecbj7+8BmyP36Gf/S9omY+Yio9rvn4+NG97M4F3vA30bINxvIyojvDVTRPMe/ZT46r1Z32o952mkDZ9WCfqLV8721OyasxbUPXjM07zpJkTk1xNFKxhxU7evBpoWw/e+daIiRDvSTIPglJ7k6dp3V9Abt93XQfal7dkXJsAedoD94z2EPG4QK9a1MntL4MUETkjbjRoLTsRbtw2pukDi2HghT8HL3mWLM3YRp1at4ki1vXx8fVqIuE5j4PlPhlxtKNFrfgtpLI34vOch1sFku+ZzM88PK5sVC0Y29HFFsPA06atZukPHhG3Y0I9+0tLATcKO3LfuD9+qyefiu6di7EA+/K+cY1+AyX9Meso4olES3k4cmCrxTggB3xDq9CU5BkvCdFiIlCTfhz7azljGST/OD7P+LSwsLCwsLCwsLCwsLCwsLCwiCMmTfp/Ne/YPCPMPC8AAAAASUVORK5CYII=","data:image/png;base64,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","data:image/png;base64,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","","","","","","",""],"frame_max":8,"frames":[[[0,0,0,30,120]],[[0,0,0,50,255]],[[0,0,0,70,255]],[[1,0,0,80,255]],[[1,0,0,90,255]],[[2,0,0,90,120]],[],[]]} \ No newline at end of file diff --git a/animates/jianji.animate b/animates/jianji.animate new file mode 100644 index 00000000..2720aafc --- /dev/null +++ b/animates/jianji.animate @@ -0,0 +1 @@ +{"ratio":2,"bitmaps":["","","","","","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJKSURBVHhe7dpNTxNBHMfxAhox0QRNTPSgV+PJiy/DA569E6+ePXD2LCYai0k1JFKpPEgL8rS4FEIrpnApiGmaGpOmBqUgpC07D3aawfgKZhLz/Vxm5re3ncx/ZtqNAQAAAAD+Y1rrLtuFa+blMwGeBUFwxnbhSzKpezodHWM1+DI4qLuZAI+mpyuXbJdJ8CEIyr1/SxHc+fcUlCse3TWtjnEy8mJl/dft0Vl12Q6ZBNdMGUpnxWc7hA+LuWho+L26Z/qUIg9m8gc3n6SkON0buCk7Zk5CM6tifSglQxvBtfHwsP/pmJTDGXXFRnAp9fHHtXehOBh6K5s2gkum7o8siYGwIFV8Sj2wMVxKzB3eSgWRfJWWihuyB8839NnMqhhotqR6MSl3bQyXgkD3Lm/J46W8PB6fVddtDFfae0HPyAcRtlv9Zl6UuRN4sLamzpeqorFTOVGp5ahzQ4ZDnRNRRlbMKhgPo912020fwZVkoK8Wy+J36XskR+eixzaGS68X5ZZZBVNho1Uu614bw5XEvL5R+BodfqtGcmxBPbIxXHo2ITaUXQW1Wu2CjeGK+bdssyTq1b1IZrLqoY3h0stJmejsBSuNk0JZ99kYrrTffdfml6j6sy7EfE7ctzFciqfVHdXeDMwqsBFcyxdlvH4kRKWuTz/ogmt7+yKcyDaapizZCC6Z70k/bbcWstvqoo3gmlLqXGGn2W+H8GF/X/e1yxA/0gGAAxz7PGPDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAs1jsD8fsSMjMXLQKAAAAAElFTkSuQmCC","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAPYSURBVHhe7dxLT5xVGAdwpKKkiYmX1oTExIULozHxMxhjYqILdeta070foBt3rkSUgsO0OIW0XMZhrgwX33BrwULAcilWKQ6ptRKRDpeBmfe5eE49NX4Bz0vG/y+ZzDnPmQXvec6VMDQAAAAAAABAHVPVx1wRfLOdjwRELAiCx10RotLXp6ceFrQBsyEq589rIxIQoWy29IwrIglRCILN5n+WIvDn36egubWDd+27NuBkFImp2T9fvzosz7oqkuCbXYZy07TgqhCF8bmwrSsj79sylqIIFL4vv/zFINOjvQE3Zc/sSagwQ7NtgzzpQuDbt5N77305wNyVl7MuBD4NTmy3JCep3NbPxy4EPtl1v+c7+ri1jyWWlnMuDD51j+y90jMScntSFTfkCHTMa9PwNfqwf4y1M8W3XRh8yt+WJy+kVOM51eSoPOfC4IvZC05dKvD49JJqe5LZha1G9w7/tSDQ5kRRNXtNNTUdvuHC4Is9EcWGuHxrM5TeUTrAzTgCiUBeuLFGPLtKfGWc+10YifDFjvrECO+X7pJkprhmN2fMBM8SI/Lm8s8hrZeIL+f4D5sAJMGz4RtU+XVH9PoK02Agr5kE2NPQ/yMJ7mEjY0f75WL46S/3Q9n6nTlW4LK9IfeZo6r7SH0TkRbTCU2uGol5czsOlqh6UBGdW6Wwp8ifuWWofmeBfUDX+SdipMXTvLa7L7prDqTJKX2Qn5SzLgn1yTxco31A84p09D/St6JPFK+THB+zLG9yrXOIb9Z7AprM60Sts20DXN0ukxxVze14JjwIFvXpuk7CSZMoSMvwTMhVUi39RhLP8LZrAh/saG8dYNoti9ZYdGKRqvlZedU1gw+dKfloZoXFzoIdsxxdKtI+liHPzF4ge4dqZoHqDxscdmd4wCQBv6r2pX2IP1/cIBHT6/uHJOZeUEkHesY1gw+xDB9Va6o2CeslCttTfNM1gQ/xnLxVukdsViG1U+GbLB+m5/W0a65PJ22zu5jjROX471nw4wZRPMe9rqk+mec8URud/XrTwi1aNj+XmQWi3Vl6gD9l8awjrWe2dnjPJmF8gWpfZ8O3XRP4MrZA55hZdsuhdGX4vskF7gU+2aVoa5vH7GZ8ZZQrXxXledcEvlwMtLlGfHf9DlFvgZZdGHxavSMvHtWo0j3Chw+/fwz+haF8sPQT1TqGaMKFwCe7AW/ek09iea5gM46I7fjMFMdbr4bvuBD4ZpLQ2J7ioqtCFNJpPR1LyVOuClG4kJSXXBGiEgSKfw4FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPWtoeEvT/ukTdlu2cUAAAAASUVORK5CYII=","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAScSURBVHhe7dzLT9xVFAdwpFqrxrdt0sSVG6MxMel/0Lgx0YUuXLlw1xj/CRa600QLtLyH0gEKwwzMwDDD8PqVZ0EgQHkIDRShNQK1pcOb+d1zjvfi1fgPcH8N+X42c3/nsuF35p57z/wY8gAAAAAAAOAUE5Hn7BBcMzcfCQiY53nP2yEEJRKRM8cDycNqCEpBgeQjAQFKJlfftEMkIQiet3Luv1IE7vz/FDQ6v/u5eZU8nIwCMTDy5OPGDn7LXiIJrpky1D6oJuwlBKFn1C+uauMvzRilKADpX7PvF8VI/bs3oFN2zJyE0kNqpDhG/TYErrX0b39xLUpUleLzNgQuxfo2Lzb3q2xxEx3aELhk6n5dr7pSGCGubOVvbRhcqunc/qCu06eSZhF0yAEoG5cXOobV103dJOVxumfD4FLqHr9YGhcJtYs0d/HbNgyu6L3gzI009QxOiZQ0E9mwkW9f4aR5npwLZ0SSwyLxQf+yDYMr5kRUmaDsbys+13epXXTGAQh7/O7YvKKROUUNPdRkw0iEK+ZdH+6kndWHitsGKGc2Z6wEx8Kd/MnMkq8WVhXVttNfJgFIgmMdY2r/j8csd2ZJxTz+SCfAnIaQBBfMu7024//w+7rPaxtElWnKmg45oo+q9kfgpI3r7tibUke7+yyjc8qvy9CPtgxhFbgSaqX5rR2WLX0gbR6Qp6l+Po+9wKHIrJzN3FF8eEg8s0K58gTdRQIcK47S0WZW8cGR7o6H/F1vUt5AEhwKp/lix5BPR0pk9U/FoTbatFPggnm3F0ZJbWVZcsTSN6mOUiP8oZ0GF0pb5MrQLLFZBY91ObqRUTsoQw6Zm633At7eE70KRKaXya9po6iO46NqV0rjFJ1cVsz6ru/sKdZ9wX6rJ+/YaThp5rFlZZsuQzkRk4SFVeWXxOmunQYXQu00/GCdRVchMUvhZpL2WsflZTt9Opn6a4eBM6ugSq+C/cN/VsHislI6KfV2+nTSv+cztdFVJcgbm/PN/dergKUmqZ7iT1kcMiuyOEa89kg3BVrPhMpVJP1P7TS4UBTjS70TZicQ2cr6rMvSuh6iL3CptEXtrm2QqULS0EX71zN8wU6BC1dT/FrLbRalE7BwX6n6tJqxU+BKRSvdmr3PcpBTXNNJe8ffPwZ3dN3PD+ljqdLbwdSiUmUJ1WenwJVQK18ammZZeagolCTdIWAzdq66Xe1sPGFJDCm/qMk//v4xOHQzw68kB483Y74epz0bBldM2alIqP7FZZa6TuVHuuR1OwWumI8jqlPE/dOKy1rowIbBpatRvjwyy1LWIlI5yK/aMLh0q4NyXRMs4Qwt2RC4VBCRs3UZEfOty1P/rOBZVZ6kqehtltoMNdoQuBbtJSpqEinAg/tgVKflq1K9GYcz/I0NgWuFUcoVNh0/uMHHE0HQHfKF4qhIY7d//D+JIACxPposRWMWnOFhfunnBpFol7xnQ+CSqf/lcequSeF/UATGHEV/acSRNFCVCQq1DdP39hJcM6Xop3piewlBWHrAn12L8Xf2EoJQ30GP0JgBAAAAAAAAAAAAAAAAAMDJy8v7G+ppS3n2R3dTAAAAAElFTkSuQmCC","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAANMSURBVHhe7dlLT1NREAfwqtFEjboxJm6Nn8Bv4M5ENy5cu3PhypUuSXRrogJqESgBBKVcUlrKowVBjFSjEAXRiBF8JopGEbEFeufhOXq+Auc25f9b3Tuz6p3MnEdjAAAAAAAAUMVUdYt7BACIlMYwjiKFAlQEFAE2OY1ha1oJUATY5DCKKgCuKgAAAAAAAAAANhd7H4Q7oYi1Dclh9whRyT+Rc+iEiNgP35EPL71fpAsoQkQmJ3X76AyVVkp804XAt0SGX/1YJln6w3XohAgkZ3VH7hHJ2hrTzALXowgRqA94/ZvpguIqc6bAF10YfGkflINDEyGvk+qHL0TN/XLepcAHO3ZqA6alZdEyi45PU2nwqRx0afAhntIzE7MstgvsotyWp99YDzyyH9usBfK7qKYLVKfnOWzt4wBF8Cjey8GzeRIxX32lSNKR41JmTPe7NGy0BnMwa+ozY6isaovw+gOFN3t5xqXBh0Q/Fz59FTVTSG0rtGW5mJnUXS5dnSppztouaDZdUFr73wVz80SmKJ0uXZ3M79zqHitCc5rHnr4M7fc3XSDamqVfyaRuc2nYaLYj63tYPn43hwLj3hSVG7PhMZcGH+p65MjolF0JVJeWQzFj6at5xJbUp3iK/nxcZDuF9O4wl27k5IBLgQ/XBmRv6r4omQK8XiDqHKQXLgW+NGb4zuyC6GqZpDXPxZqaytowVD0z97cmzLaUzHLwfI6oIU3jLgW+JDJyZGJa9N1n4kSWzQkBi7F3Lf20svhTND1BYV13eMKFwZe2nOzOPvy3GMuNXi66MPhix05jmh7MzYt25ClMDus+lwJf7HVEywDLg2mShhSvujD4dC2Qo49nRRtSqk0PZY8Lg093hrg8PCXanuO3LgQ+1SR1R0dOtTbJUvX/FVSqW1l+HtwXvZ3jLhcC34JR5rpu1ZoK+z9j02gZ1FNxsxi35+S0C4FvtQGXa7v//XGD64komBPygfpAtWskPOlC4FvPOD+L42AWnUJBdl65qxoM6yEXAp/s/L/VyyOtA/zGhcA3uxW92oUtaaSa0pzoK/Al9wq+2VF0uZPFvUIU3n6S49d75Kx7hSh0DvF3HMwAAAAAAAAAAAAAAAAAAGDjxWJ/Ae8wTjJnuOHhAAAAAElFTkSuQmCC","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAI9SURBVHhe7drLa1NBFMfxaFFRUXfudOGf0LUb165ciDvd+0eo4FbQPmn6ClrtI02ITZPa2BJ8tN1YsYpQLBXxgV1EQTBSbe45x1w4/4JzL+b7Wc35ZRUm98zMzWQAAAAAAP8xM9vnQwBIlGVoR4liAlKBSUCHswxb0zRgEtDhaEUpwKsKAAAAAAAAAAAAAAAABBRfV+HKSsKyZTvrQyQhu24Hxip2xkskIVeR6XYr6vKyM6Sp98ZPQa4qxY5aD9pfdr8PU2GsLPWXm3LDS4QW//r7S/Lny3e95BFC6ytqd/1Fq9mejNMeIbShUtT81JB3qnrII4TUs6DHi/VII5FqRy3KaTJSlqm321H0uyWDTEIC4h3a+LzoXktkY0uveYyQxsvavfpa7cPX6NdYVS97jJBy1ehnc1dtbjVqDkzpKY8Ryr2aHq2smO00Ih0s2w+PEUq8AI/MRc8a39QePI5a+SU74R8hlHzeunILopsfI82WZNdjhNRT0HM77acgWzIbXdFjHiOkqUXZe/NebaIm2x4hpOt5O/h8w6w3L1petyMeI6ThimwUnqjdr8mMRwitUBfpmzW7nrL/MzpG7pFdHGovxhM1veIRQustyF7vrCgv6hLSPiGf7C+YzSy3LniE0IpP5dUQB7PkrK3p4dvTZoUl7hQlIu7/ww9l+e6CbHmE0OKt6J0ZtqSJGp2T8fk1ueklQotb0a1JUS+RhO3Pen6gqFe9RBImF6XBwQwAAAAAAAAAAAAA8O9lMn8BWYFAb1I8LpQAAAAASUVORK5CYII=","","","","","","","","","",""],"frame_max":20,"frames":[[[5,0,0,50,255,0,120]],[[6,0,0,50,255,0,120]],[[7,0,0,50,255,0,120]],[[8,0,0,50,255,0,120]],[[5,0,0,60,255,1,60]],[[5,0,0,60,255,1,60]],[[5,0,0,60,255,1,60]],[[6,0,0,60,255,1,60]],[[7,0,0,60,255,1,60]],[[8,0,0,60,200,1,60]],[[5,-8,-8,60,255,0,60]],[[6,0,-8,60,200,0,60]],[[6,0,-8,60,255,0,60]],[[6,0,-8,60,255,0,60]],[[7,0,-8,60,255,0,60]],[[8,0,-8,60,255,0,60]],[[8,0,-8,60,255,0,60]],[[9,0,-8,60,255,0,60]],[[9,0,-8,60,200,0,60]],[[9,0,-8,60,50,0,60]]]} \ No newline at end of file diff --git a/animates/sword.animate b/animates/sword.animate new file mode 100644 index 00000000..21cc63a0 --- /dev/null +++ b/animates/sword.animate @@ -0,0 +1 @@ +{"ratio":2,"bitmaps":["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAD6SURBVHhe7dQ9SsVAFAXg+MNTeAhaWCrWLsHGUlCwsHMXgo2NjZ31a1yBVtaCrSvQ1i24hSSegbuEBAS/Dw7M3JnqZEgHAAAAAAAAAAAAAP/NOI5rySI5GobhNDlJ9uuYqaXo9RR83Pf9U/KevGV/kxwkW+2D1FWmkmKXKfYuZf8k38lrZpeZHSaLusaU2ktOyRcp+zP5Sl6yv858t53VNaaWcrdT9mPSXvpHskrxO3XMnNpvJYW3F/+Q9XmNmVv7raT055R+n/VejZlbyt5M6VfJbdYbNWZureyUvkzOagQAAAAAAAAAAAAAAAAAAAAAAAAAAADwd3XdL135q9NaPZ6+AAAAAElFTkSuQmCC","data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJ4SURBVHhe7de7alRRFMbx3DSIgqiNIBJsBUUESyutBAsLO9/CWtL4BtorlgFBRGIEEQwxMSBiMWouGo2TCyaTC0lmJjM5ey+/HVfeYPZB8P+DNefsS/WdxZ5zugAAAAAAAAAAAAAAAAAAAID/lZkdVnX7ELmkkA+C1rU3xngthHBf1xsa9+1vQmcdhK7qUdAXFPh4URSjur+r6vdt6DQP/ZDqkkL/ZlZs6jqh8WnfghzU1UcOQlclmop3fBk5KPA+hXxRYb9LiWtsujR0Oe5b0Gke+hUF/TaFLtHrh29BDgr9jEJOoReqeur2RPfTvgWdpnzTG8yAQm6oYgq8uWfWLvaD1y+vkNko3G6FPJ9CT7ZbZpVVs9m1/Ydw3bchB3X9+dTxqVLwk4tmH1T1VnjlW5CDGj11/XDq+HTgfFwye/rVbKpmNjzDx1N2Cn8jhb+qF8mRObOX381m1sPww4od8y3IQZn3KPzdogjNyorZ8xmzaXX9cjOe8y3IxcNvNtq2OV41ezFrttYMv30ZOSn8dOavqBrjC3+PnfVGvOfLyE0P4HH6qhr9Zfbmp7p/Lg74EnJT+LdbeyGk4F/PhfhgMp7yJeSm9/yTavza2HyIYwuhPTRkvb6E3NT5fQr/2cRS2HhfDfVB/Qn7EnJLf7rq/pvTq6H9uRa2fBplSOGrTixvhdrUWqj7NMqi8HsV/shsLez5FMq004qXq+th14cok879/upO+FKp2GGfQll09PSsNOLVxXq85VMoUzr7F7fDIx+iTOnNR8fP2UGOnvKl8NPx8+RTPOpTKFt6CH4LAAAAAAAAAAAAAAAAAAAAAAAAAACAf1RX1x9x4x3SPdhnTAAAAABJRU5ErkJggg==","","","","","","","","","","","","","","","","","",""],"frame_max":5,"frames":[[[0,8,32,30,100]],[[0,-16,32,50,130]],[[0,-24,40,80,150]],[[0,-48,24,90,180],[1,-8,40,100,255]],[[0,-56,24,100,200],[1,-8,24,100,255]]]} \ No newline at end of file diff --git a/animates/thunder.animate b/animates/thunder.animate new file mode 100644 index 00000000..c40dd1d6 --- /dev/null +++ b/animates/thunder.animate @@ -0,0 +1 @@ +{"ratio":2,"bitmaps":["data:image/png;base64,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","data:image/png;base64,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","data:image/png;base64,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","data:image/png;base64,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","","","","","",""],"frame_max":16,"frames":[[[2,0,-56,50,150]],[[2,0,-40,70,200]],[[2,0,-8,100,255]],[[3,0,-8,100,150]],[[3,0,-8,100,255]],[[2,0,-8,100,255]],[[2,0,-8,100,160]],[[2,0,-8,100,255]],[[3,0,-8,100,255]],[[3,0,-8,100,200]],[[0,0,-8,100,255]],[[0,0,-8,100,150]],[[1,0,-8,100,200]],[[1,0,-8,100,150]],[[0,0,-8,100,100]],[]]} \ No newline at end of file diff --git a/animates/yongchang.animate b/animates/yongchang.animate new file mode 100644 index 00000000..c4365f42 --- /dev/null +++ b/animates/yongchang.animate @@ -0,0 +1 @@ +{"ratio":2,"bitmaps":["","","data:image/png;base64,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","data:image/png;base64,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","data:image/png;base64,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","data:image/png;base64,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","","","",""],"frame_max":16,"frames":[[[2,0,-24,50,120]],[[3,0,-24,50,120]],[[2,0,-24,50,255]],[[3,0,-24,50,255],[5,-56,40,50,255],[5,0,64,30,255],[5,56,32,40,255]],[[4,0,-24,50,255],[5,56,8,40,255],[5,-32,32,30,255],[5,-56,8,50,255],[5,0,40,30,255]],[[3,0,-24,50,255],[5,-56,-16,50,255],[5,56,-16,40,255],[5,0,24,30,255],[5,-32,0,30,255]],[[4,0,-24,50,255],[5,-56,-32,50,255],[5,56,-32,40,255],[5,0,8,30,255],[5,-32,-16,30,255]],[[3,0,-24,50,255],[5,-56,-48,50,255],[5,56,-48,40,255],[5,0,8,30,255],[5,-32,-24,30,255]],[[2,0,-24,50,255],[5,-56,-64,50,150],[5,56,-56,40,150],[5,0,-16,30,150],[5,-32,-32,30,150]],[[3,0,-24,50,255],[5,-56,-80,50,150],[5,56,-72,40,150],[5,0,-32,30,150],[5,-32,-48,30,150]],[[4,0,-24,50,120],[5,-56,-96,50,80],[5,56,-96,40,100],[5,-32,-64,30,100],[5,0,-48,30,100]],[[4,0,-24,50,255],[5,-56,-112,50,80],[5,56,-112,40,100],[5,-32,-80,30,100],[5,0,-72,30,100]],[[3,0,-24,50,255]],[[2,0,-24,50,255]],[[2,0,-24,50,80]],[[2,0,-24,50,80]]]} \ No newline at end of file diff --git a/animates/zone.animate b/animates/zone.animate new file mode 100644 index 00000000..f13a6b20 --- /dev/null +++ b/animates/zone.animate @@ -0,0 +1 @@ +{"ratio":2,"bitmaps":["data:image/png;base64,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","data:image/png;base64,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","","","","","","","",""],"frame_max":6,"frames":[[[0,0,32,30,100]],[[0,0,16,50,130]],[[0,0,0,80,150]],[[0,0,-8,90,180],[1,24,24,100,255]],[[0,0,-8,100,200],[1,24,8,100,255]],[[0,0,-8,100,255]]]} \ No newline at end of file diff --git a/docs/api.md b/docs/api.md index a47385d8..ec92f8a5 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,6 +1,6 @@ # 附录:API列表 -?> 上次更新时间:* {docsify-updated} * +?> 目前版本**v1.4.1**,上次更新时间:* {docsify-updated} * 所有系统支持的API都列在了这里。所有可能被用到的API都在前面用\*标记。 @@ -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/docs/element.md b/docs/element.md index 19b1206b..d66b2c41 100644 --- a/docs/element.md +++ b/docs/element.md @@ -1,6 +1,6 @@ # 元件说明 -?> 上次更新时间:* {docsify-updated} * +?> 目前版本**v1.4.1**,上次更新时间:* {docsify-updated} * 在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。 @@ -149,6 +149,42 @@ floorId指定的是目标楼层的唯一标识符(ID)。 可以指定time,指定后切换动画时长为指定的数值。 +## 动画和天气系统 + +现在我们的H5魔塔支持播放动画,也支持天气系统了。 + +要播放动画,你需要先使用“RM动画导出器”将动画导出,放在animates目录下,然后在main.js中定义。 + +``` js +this.animates = [// 在此存放所有可能使用的动画,必须是animate格式,在这里不写后缀名 + // 动画必须放在animates目录下;文件名不能使用中文,不能带空格或特殊字符 + "hand", "sword", "zone", "yongchang", "thunder" // 根据需求自行添加 +] +``` + +!> 动画必须是animate格式,名称不能使用中文,不能带空格或特殊字符。 + +目前暂时不支持带旋转和翻转的帧。 + +导出动画时可能会进行一些压缩以节省流量,因此清晰度可能不如原版。 + +动画播放时,是按照每秒20帧的速度(即50ms/帧)。 + +定义完毕后,我们可以调用`animate`事件来播放该动画,有关事件的详细介绍请参见[事件](event)。 + +!> 播放录像时,将默认忽略所有动画。 + +目前天气系统只支持雨和雪两种天气。 + +在每层楼的剧本文件里存在一个weather选项,表示该层楼的默认天气。 + +``` js +// 该层的默认天气。本项可忽略表示晴天,如果写则第一项为"rain"或"snow"代表雨雪,第二项为1-10之间的数代表强度。 +"weather": ["snow",5] +``` + +我们也可以使用`setWeather`事件来设置当前天气,有关事件的详细介绍请参见[事件](event)。 + ## 背景音乐 本塔支持BGM和SE的播放。 diff --git a/docs/event.md b/docs/event.md index f1ef08d2..296357f9 100644 --- a/docs/event.md +++ b/docs/event.md @@ -1,6 +1,6 @@ # 事件 -?> 上次更新时间:* {docsify-updated} * +?> 目前版本**v1.4.1**,上次更新时间:* {docsify-updated} * 本章内将对样板所支持的事件进行介绍。 @@ -214,6 +214,25 @@ ] ``` +除此以外,我们还能实现“对话框效果”,只要有`\b[...]`就可以。 + +- `\b[up]` 直接显示在当前点上方。同样把这里的up换成down则为下方。 + - 如果不存在当前点(如在firstArrive中调用),则显示在屏幕最上方(最下方) +- `\b[up,hero]` 显示在勇士上方。同样把这里的up换成down则为下方。 +- `\b[up,x,y]` 显示在(x,y)点的上方(下方);x和y都为整数且在0到12之间。 + +``` js +"x,y": [ // 实际执行的事件列表 + "\b[up]这段文字显示在当前点上方", + "\b[down]这段文字显示在当前点上方", + "\t[hero]\b[up,hero]这是一段勇士说的话,会显示在勇士上方", + "\t[小妖精,fairy]\b[down,2,2]这是一段小妖精说的话,会显示在(2,2)点下方", +] +``` + +!> `\t[...]`必须在`\b[...]`前面!不然两者都无法正常显示。 + + 另外值得一提的是,我们是可以在文字中计算一个表达式的值的。只需要将表达式用 `${ }`整个括起来就可以。 ``` js @@ -242,6 +261,25 @@ ![调试](./img/eventdebug.png) +### setText:设置剧情文本的属性 + +使用`{"type": "setText"}`可以设置剧情文本的各项属性。 + +``` js +"x,y": [ // 实际执行的事件列表 + {"type": "setText", "position": "up", "title": [255,0,0], "text": [255,255,0], "background": [0,0,255,0.3]}, + "这段话将显示在上方,标题为红色,正文为黄色,背景为透明度0.3的蓝色" +] +``` + +position为可选项,表示设置文字显示位置。只能为up(上),center(中)和down(下)三者。 + +title为可选项,如果设置则为一个RGB三元组或RGBA四元组,表示标题(名字)颜色。 + +text为可选项,如果设置则为一个RGB三元组或RGBA四元组,表示正文颜色。 + +background为可选项,如果设置则为一个RGB三元组或RGBA四元组,表示背景色。 + ### tip:显示一段提示文字 `{"type": "tip"}`可以在左上角显示一段提示文字。 @@ -381,13 +419,40 @@ revisit常常使用在一些商人之类的地方,当用户购买物品后不 ] ``` +### setBlock:设置某个图块 + +我们可以采用 `{"type": "setBlock"}` 来改变某个地图块。 + +``` js +"x,y": [ // 实际执行的事件列表 + {"type": "setBlock", "floorId": "MT1", "loc": [3,3], "number": 233}, // 将MT1层的(3,3)点变成数字233 + {"type": "setBlock", "loc": [2,1], "number": 121}, // 省略floorId则默认为本层 + {"type": "setBlock", "number": 57}, // loc也可省略,默认为当前点 +] +``` + +floorId为可选的,表示要更改的目标楼层。如果忽略此项,则默认为当前楼层。 + +loc为可选的,表示要更改地图块的坐标。如果忽略此项,则默认为当前事件点。 + +number为**要更改到的数字**,有关“数字”的定义详见参见[素材的机制](personalization#素材的机制)。 + +图块更改后: + + - 其启用/禁用状态不会发生任何改变。原来是启用还是启用,原来是禁用还是禁用。 + - 可通行状态遵循覆盖原则,即**首先取该图块的默认noPass属性,如果剧本的events中定义该点的noPass则覆盖**。 + - 触发器(trigger)亦采用覆盖原则,即**首先取该图块的默认触发器(例如怪物是battle,道具是getItem,门是openDoor),如果剧本的events中定义了该点的trigger则覆盖**。 + +图块更改往往与[同一个点的多事件处理](#同一个点的多事件处理)相关。 + ### update: 立刻更新状态栏和地图显伤 -当我们在上面调用show事件,显示一个怪物后,该怪物将不会有显伤显示。如果你需要刷新状态栏和地图显伤,只需要简单地调用 `{"type": "update"}` 即可。 +如果你需要刷新状态栏和地图显伤,只需要简单地调用 `{"type": "update"}` 即可。 ### sleep: 等待多少毫秒 等价于RMXP中的"等待x帧",不过是以毫秒来计算。 + 基本写法:`{"type": "sleep", "time": xxx}` ,其中xxx为指定的毫秒数。 ``` js @@ -492,6 +557,48 @@ time为可选的,指定的话将作为楼层切换动画的时间。 使用disableShop可以永久禁用全局商店直到再次被openShop打开为止。有关全局商店的说明可参见[全局商店](#全局商店)。 +### animate:显示动画 + +我们可以使用 `{"type": "animate"}` 来显示一段动画。 + +有关动画的详细介绍可参见[动画和天气系统](element#动画和天气系统)。 + +``` js +"x,y": [ // 实际执行的事件列表 + {"type": "animate", "name": "yongchang", "loc": [1,3]}, // 在(1,3)显示“咏唱魔法”动画 + {"type": "animate", "name": "zone", "loc": "hero"}, // 在勇士位置显示“领域”动画 + {"type": "animate", "name": "hand"} // 可以不指定loc,则默认为当前事件点 +] +``` + +name为动画名,**请确保动画在main.js中的this.animates中被定义过。** + +loc为动画的位置,可以是`[x,y]`表示在(x,y)点显示,也可以是字符串`"hero"`表示在勇士点显示。 + +loc可忽略,如果忽略则显示为事件当前点。 + +在动画播放结束后才会继续执行下一个事件。 + +### showImage:显示图片 + +我们可以使用 `{"type": "showImage"}` 来显示一张图片。 + +``` js +"x,y": [ // 实际执行的事件列表 + {"type": "showImage", "name": "bg", "loc": [231,297]}, // 在(231,297)显示bg.png + {"type": "showImage", "name": "1", "loc": [109,167]}, // 在(109,167)显示1.png + {"type": "showImage"} // 如果不指定name则清除所有图片。 +] +``` + +name为图片名。**请确保图片在main.js中的this.pngs中被定义过。** + +loc为图片左上角坐标,以像素为单位进行计算。 + +如果不指定name则清除所有显示的图片。 + +调用show/hide/move/animate等几个事件同样会清除所有显示的图片。 + ### setFg: 更改画面色调 我们可以使用 `{"type": "setFg"}` 来更改画面色调。 @@ -512,6 +619,26 @@ color为需要更改画面色调的颜色。它是一个数组,分别指定目 time为可选的,如果指定,则会作为更改画面色调的时间。 +### setWeather:更改天气 + +我们可以使用 `{"type": "setWeather"}` 来更改天气。 + +``` js +"x,y": [ // 实际执行的事件列表 + {"type": "setWeather", "name": "rain", "level": 6}, // 更改为雨天,强度为6级 + {"type": "setWeather", "name": "snow", "level": 3}, // 更改为雪天,强度为3级 + {"type": "setWeather"} // 更改回晴天 +] +``` + +name为天气选项。目前只支持`rain`和`snow`,即雨天和雪天。 + +level为天气的强度等级,在1-10之间。1级为最弱,10级为最强。 + +如果想改回晴天则直接不加任何参数。 + +!> 使用setWeather更改的天气在切换地图后会被目标地图的默认天气覆盖。 + ### move: 让某个NPC/怪物移动 如果我们需要移动某个NPC或怪物,可以使用`{"type": "move"}`。 @@ -801,6 +928,84 @@ core.insertAction(list) //往当前事件列表中插入一系列事件。使用 // …… ``` +## 同一个点的多事件处理 + +我们可以发现,就目前而且,每个点的事件是和该点进行绑定,并以该点坐标作为唯一索引来查询。 + +而有时候,我们往往需要在同一个点存在多个不同的事件。这涉及到同一个点的多事件处理。 + +我们可以依靠两来实现。**`setBlock`事件**和**if+flag的条件判断**。 + +下面以几个具体例子来进行详细说明。 + +### 打怪掉宝(怪物->道具) + +我们注意到怪物和道具都是系统默认事件,因此无需写events,而是直接在afterBattle中setBlock即可。 + +``` js +"afterBattle": { + "x,y": [ + {"type": "setBlock", "number": 21} // 变成黄钥匙。注意是当前点因此可省略floorId和loc + ] +} +``` + +### 打怪变成可对话的NPC(怪物->NPC) + +由于NPC是自定义事件,因此我们需要写events。注意到events中不覆盖trigger,则还是怪物时,存在系统trigger因此会战斗;变成NPC后没有系统trigger因此会触发自定义事件。 + +请注意打死怪物时默认会禁用该点,因此替换后需要手动进行show来启用。 + +``` js +"events": { + "x,y": [ + "可对话的NPC" + ] +}, +"afterBattle": { + "x,y": [ + {"type": "setBlock", "number": 121}, // 变成老人 + {"type": "show", "loc": [x,y]} // 启用该点 + ] +} +``` + +### 获得圣水后变成墙 + +这个例子要求获得圣水时不前进(也就是不能走到圣水地方),然后把圣水位置变成墙。 + +因此需要我们需要覆盖系统trigger(getItem),并覆盖noPass。 + +通过if来判断有没有获得圣水,没有则触发圣水(生命x2)然后变成墙,否则不执行。 + +``` js +"events": { + "x,y": { + "trigger": "action", // 覆盖系统trigger,默认的getItem不会执行 + "noPass": true, // 覆盖可通行状态,不允许走到该点 + "data": [ + {"type": "if", "condition": "flag:hasSuperPotion", // 条件判断:是否喝过圣水 + "true": [], // 喝过了,不执行 + "false": [ + {"type":"setValue", "name":"status:hp", "value":"status:hp*2"}, // 生命翻倍 + {"type":"setBlock", "number": 1}, // 将该点变成墙 + {"type":"setValue", "name":"flag:hasSuperPotion", "value": "true"} // 标记已经喝过了 + ] + } + ] + ] +} +``` + + +总之,记住如下两点: + + - 可以使用setBlock来更改一个图块。 + - 可通行状态遵循覆盖原则,即**首先取该图块的默认noPass属性,如果剧本的events中定义该点的noPass则覆盖**。 + - 触发器(trigger)亦采用覆盖原则,即**首先取该图块的默认触发器(例如怪物是battle,道具是getItem,门是openDoor),如果剧本的events中定义了该点的trigger则覆盖**。 + - 可以通过if语句和flag来控制自定义事件具体走向哪个分支。 + - 如果弄不清楚系统trigger和自定义事件等的区别,也可以全部覆盖为自定义事件,然后通过type:battle,type:openDoor等来具体进行控制。 + ## 加点事件 打败怪物后可以进行加点。 diff --git a/docs/index.md b/docs/index.md index 9f0059ef..7a358d0d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,6 @@ # HTML5 魔塔样板说明文档 -?> 上次更新时间:* {docsify-updated} * +?> 目前版本**v1.4.1**,上次更新时间:* {docsify-updated} * 众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。 diff --git a/docs/personalization.md b/docs/personalization.md index 9b4eb0ca..1f4fbd0b 100644 --- a/docs/personalization.md +++ b/docs/personalization.md @@ -1,6 +1,6 @@ # 个性化 -?> 上次更新时间:* {docsify-updated} * +?> 目前版本**v1.4.1**,上次更新时间:* {docsify-updated} * 有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。 @@ -27,27 +27,35 @@ 由于HTML5功能(素材)有限,导致了对很多比较复杂的素材(比如房子内)等无法有着较好的绘图方式。 -为了解决这个问题,我们允许用户自己放置一张图片作为某一层的背景素材。 +为了解决这个问题,我们允许用户自己放置一张或多张图片作为某一层的背景素材。 要启用这个功能,我们首先需要在`main.js`中将可能的图片进行加载。 ``` js -this.pngs = [ // 在此存放所有可能的背景图片;背景图片最好是416*416像素,其他分辨率会被强制缩放成416*416 - // 建议对于较大的图片,在网上使用在线的“图片压缩工具”来进行压缩,以节省流量 - "bg.png", // "yewai.png", +this.pngs = [ // 在此存放所有可能使用的图片,只能是png格式,可以不写后缀名 + // 图片可以被作为背景图(的一部分),也可以直接用自定义事件进行显示。 + // 图片名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 + // 建议对于较大的图片,在网上使用在线的“图片压缩工具(http://compresspng.com/zh/)”来进行压缩,以节省流量 + "bg", // 依次向后添加 ]; ``` -!> 背景素材只支持png格式,且会被强制缩放到416*416。 +!> 背景素材只支持png格式。 -!> 请使用网上的一些[在线图片压缩工具](http://www.asqql.com/gifzip/)对png图片进行压缩,以节省流量。一张500KB的png图片可以被压缩到20-30KB,显示效果不会有太大差异。 +!> 请使用网上的一些[在线图片压缩工具](http://compresspng.com/zh/)对png图片进行压缩,以节省流量。一张500KB的png图片可以被压缩到20-30KB,显示效果不会有太大差异。 -之后,我们可以在每层剧本的`"png": "xxx"`里来定义该层的默认背景图片素材。 +之后,我们可以在每层剧本的`"png"`里来定义该层的默认背景图片素材。 ``` js -"png": "bg.png", // 背景图;你可以选择一张png图片来作为背景素材。 +"png": [[x,y,"bg"]], // 背景图;你可以选择一张或多张png图片来作为背景素材。 +"png": [], // 无任何背景图 +"png": [[1,1,"house"], [6,7,"house2"]] // 在(1,1)放一个house.png,且(6,7)放house2.png ``` +png为一个数组,代表当前层所有作为背景素材的图片信息。 + +每一项为一个三元组,分别为该背景素材的x,y和图片名。其中x和y分别为横纵坐标,在0-12之间;图片名则必须在上面的this.pngs中定义过。 + 你的图片背景素材将会覆盖原来本身的背景层。 **如果你需要让某些点不可通行(比如你建了个房子,墙壁和家具等位置不让通行),则需在`events`中指定`{"noPass": false}`,参见[自定义事件](event#自定义事件)的写法。 @@ -213,15 +221,23 @@ if (itemId === 'shield5') { core.setFlag("shield5", true); // 增加一个自定义Flag:已经拿到神圣盾 } ``` -2. 免疫吸血效果:在`enemys.js`的getExtraDamage函数中,编辑成如果存在神圣盾标记,额外伤害为0。 +2. 免疫吸血效果:在`enemys.js`的伤害计算中,编辑成如果存在神圣盾标记,吸血伤害为0。 ``` js -enemys.prototype.getExtraDamage = function (monster) { - var extra_damage = 0; - if (this.hasSpecial(monster.special, 11)) { // 吸血 - // 吸血的比例 - extra_damage = core.status.hero.hp * monster.value; - if (core.hasFlag("shield5")) extra_damage = 0; // 如果存在神圣盾,则免疫吸血 - extra_damage = parseInt(extra_damage); +enemys.prototype.calDamage = function (monster, hero_hp, hero_atk, hero_def, hero_mdef) { +// ... 上略 + // 吸血 + if (this.hasSpecial(mon_special, 11)) { + var vampireDamage = hero_hp * monster.value; + + // 如果有神圣盾免疫吸血等可以在这里写 + if (core.hasFlag("shield5")) vampireDamage = 0; // 存在神圣盾,吸血伤害为0 + + vampireDamage = parseInt(vampireDamage); + // 加到自身 + if (monster.add) // 如果加到自身 + mon_hp += vampireDamage; + + initDamage += vampireDamage; } // ... 下略 ``` @@ -255,8 +271,6 @@ core.prototype.checkBlock = function () { 如果要修改伤害计算公式,请修改下面的calDamage函数。请注意,如果无法战斗,该函数必须返回`999999999`。 -对于吸血怪的额外伤害计算在getExtraDamage中。 - 对于毒衰弱怪物的战斗后结算在`events.js`中的afterBattle函数中。 对于领域、夹击、阻击怪物的检查在`events.js`中的checkBlock函数中。 diff --git a/docs/start.md b/docs/start.md index 49676e78..c9a838c0 100644 --- a/docs/start.md +++ b/docs/start.md @@ -1,6 +1,6 @@ # 快速上手 -?> 上次更新时间:* {docsify-updated} * +?> 目前版本**v1.4.1**,上次更新时间:* {docsify-updated} * 在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔! diff --git a/images/forward.png b/images/forward.png new file mode 100644 index 00000000..6701f077 Binary files /dev/null and b/images/forward.png differ diff --git a/images/pause.png b/images/pause.png new file mode 100644 index 00000000..db4f3aea Binary files /dev/null and b/images/pause.png differ diff --git a/images/play.png b/images/play.png new file mode 100644 index 00000000..34cfd72f Binary files /dev/null and b/images/play.png differ diff --git a/images/rewind.png b/images/rewind.png new file mode 100644 index 00000000..bafb4ee1 Binary files /dev/null and b/images/rewind.png differ diff --git a/images/stop.png b/images/stop.png new file mode 100644 index 00000000..8a2a1219 Binary files /dev/null and b/images/stop.png differ diff --git a/index.html b/index.html index 60b85214..7d110562 100644 --- a/index.html +++ b/index.html @@ -109,10 +109,12 @@ + + 此浏览器不支持HTML5 - + \ No newline at end of file diff --git a/libs/core.js b/libs/core.js index e5a4cafe..8176977a 100644 --- a/libs/core.js +++ b/libs/core.js @@ -3,17 +3,8 @@ */ function core() { - this.dom = {}; - this.statusBar = {}; - this.canvas = {}; - this.images = []; - this.pngs = []; - this.bgms = []; - this.sounds = []; - this.floorIds = []; - this.floors = {}; - this.firstData = {}; this.material = { + 'animates': {}, 'images': {}, 'bgms': {}, 'sounds': {}, @@ -28,14 +19,27 @@ function core() { 'turnHeroTimeout': null, } this.interval = { - 'twoAnimate': null, - 'fourAnimate': null, - 'boxAnimate': null, 'heroMoveTriggerInterval': null, 'heroMoveInterval': null, - 'heroAutoMoveScan': null, "tipAnimate": null, - 'openDoorAnimate': null + 'openDoorAnimate': null, + 'animateInterval': null, + } + this.animateFrame = { + 'background': null, + 'globalAnimate': false, + 'twoTime': null, + 'fourTime': null, + 'boxTime': null, + 'moveTime': null, + 'speed': null, + 'weather': { + 'time': null, + 'type': null, + 'level': 0, + 'nodes': [], + 'data': null, + } } this.musicStatus = { 'audioContext': null, // WebAudioContext @@ -77,22 +81,27 @@ function core() { 'maps': null, 'checkBlock': {}, // 显伤伤害 - // 勇士状态;自动寻路相关 - 'heroMoving': false, - 'heroStop': true, 'lockControl': false, - 'autoHeroMove': false, - 'automaticRouting': false, - 'automaticRouted': false, - 'autoStep': 0, - 'movedStep': 0, - 'destStep': 0, - 'automaticRoutingTemp': {'destX': 0, 'destY': 0, 'moveStep': []}, - 'autoStepRoutes': [], - 'holdingPath': 0, - 'stepPostfix': [], - 'mouseOutCheck': 1, - 'moveStepBeforeStop': [], + + // 勇士移动状态 + 'heroMoving': 0, + 'heroStop': true, + + // 自动寻路相关 + 'automaticRoute': { + 'autoHeroMove': false, + 'autoStep': 0, + 'movedStep': 0, + 'destStep': 0, + 'destX': null, + 'destY': null, + 'autoStepRoutes': [], + 'moveStepBeforeStop': [], + 'cursorX': null, + 'cursorY': null, + }, + + // 按下键的时间:为了判定双击 'downTime': null, // 路线&回放 @@ -102,7 +111,8 @@ function core() { 'pausing': false, 'animate': false, // 正在某段动画中 'toReplay': [], - 'totalList': [] + 'totalList': [], + 'speed': 1.0 }, // event事件 @@ -114,6 +124,12 @@ function core() { 'selection': null, 'ui': null, }, + 'textAttribute': { + 'position': "center", + "title": [255,215,0,1], + "background": [0,0,0,0.85], + "text": [255,255,255,1], + }, 'curtainColor': null, 'usingCenterFly':false, 'openingDoor': null, @@ -124,22 +140,12 @@ function core() { 'boxAnimateObjs': [], }; this.status = {}; - this.flags = {}; } /////////// 系统事件相关 /////////// ////// 初始化 ////// -core.prototype.init = function (dom, statusBar, canvas, images, pngs, bgms, sounds, floorIds, floors, coreData) { - core.dom = dom; - core.statusBar = statusBar; - core.canvas = canvas; - core.images = images; - core.pngs = pngs; - core.bgms = bgms; - core.sounds = sounds; - core.floorIds = floorIds; - core.floors = floors; +core.prototype.init = function (coreData) { for (var key in coreData) { core[key] = coreData[key]; } @@ -164,7 +170,7 @@ core.prototype.init = function (dom, statusBar, canvas, images, pngs, bgms, soun document.title = core.firstData.title + " - HTML5魔塔"; document.getElementById("startLogo").innerHTML = core.firstData.title; core.material.items = core.items.getItems(); - core.initStatus.maps = core.maps.initMaps(floorIds); + core.initStatus.maps = core.maps.initMaps(core.floorIds); core.material.enemys = core.clone(core.enemys.getEnemys()); core.material.icons = core.icons.getIcons(); core.material.events = core.events.getEvents(); @@ -195,12 +201,12 @@ core.prototype.init = function (dom, statusBar, canvas, images, pngs, bgms, soun core.platform.supportCopy = false; } - var chrome=/Chrome\/(\d+)\./.exec(navigator.userAgent); + var chrome=/Chrome\/(\d+)\./i.exec(navigator.userAgent); if (core.isset(chrome) && parseInt(chrome[1])>=50) core.platform.isChrome = true; - core.platform.isSafari = /Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent); - core.platform.isQQ = /QQ/.test(navigator.userAgent); - core.platform.isWeChat = /MicroMessenger/.test(navigator.userAgent); + core.platform.isSafari = /Safari/i.test(navigator.userAgent) && !/Chrome/i.test(navigator.userAgent); + core.platform.isQQ = /QQ/i.test(navigator.userAgent); + core.platform.isWeChat = /MicroMessenger/i.test(navigator.userAgent); if (window.FileReader) { core.platform.fileReader = new FileReader(); @@ -215,7 +221,9 @@ core.prototype.init = function (dom, statusBar, canvas, images, pngs, bgms, soun return; } } - catch (e) {} + catch (e) { + console.log(e); + } alert("不是有效的JSON文件!"); if (core.isset(core.platform.errorCallback)) @@ -261,10 +269,184 @@ 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; + core.animateFrame.moveTime = core.animateFrame.moveTime||timestamp; + core.animateFrame.weather.time = core.animateFrame.weather.time||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 (timestamp-core.animateFrame.moveTime>16 && core.isset(core.status.heroMoving) && 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); + } + core.animateFrame.moveTime = timestamp; + } + + // weather + if (core.isPlaying() && timestamp-core.animateFrame.weather.time>30) { + if (core.animateFrame.weather.type == 'rain' && core.animateFrame.weather.level > 0) { + + core.clearMap('weather', 0, 0, 416, 416); + + core.canvas.weather.strokeStyle = 'rgba(174,194,224,0.8)'; + core.canvas.weather.lineWidth = 1; + core.canvas.weather.lineCap = 'round'; + + core.animateFrame.weather.nodes.forEach(function (p) { + core.canvas.weather.beginPath(); + core.canvas.weather.moveTo(p.x, p.y); + core.canvas.weather.lineTo(p.x + p.l * p.xs, p.y + p.l * p.ys); + core.canvas.weather.stroke(); + + p.x += p.xs; + p.y += p.ys; + if (p.x > 416 || p.y > 416) { + p.x = Math.random() * 416; + p.y = -10; + } + + }) + + core.canvas.weather.fill(); + + } + else if (core.animateFrame.weather.type == 'snow' && core.animateFrame.weather.level > 0) { + + core.clearMap('weather', 0, 0, 416, 416); + + core.canvas.weather.fillStyle = "rgba(255, 255, 255, 0.8)"; + core.canvas.weather.beginPath(); + + if (!core.isset(core.animateFrame.weather.data)) + core.animateFrame.weather.data = 0; + core.animateFrame.weather.data += 0.01; + + var angle = core.animateFrame.weather.data; + core.animateFrame.weather.nodes.forEach(function (p) { + core.canvas.weather.moveTo(p.x, p.y); + core.canvas.weather.arc(p.x, p.y, p.r, 0, Math.PI * 2, true); + + // update + p.x += Math.sin(angle) * 2; + p.y += Math.cos(angle + p.d) + 1 + p.r / 2; + + if (p.x > 416 + 5 || p.x < -5 || p.y > 416) { + if (Math.random() > 1 / 3) { + p.x = Math.random() * 416; + p.y = -10; + } + else { + if (Math.sin(angle) > 0) { + p.x = -5; + p.y = Math.random() * 416; + } + else { + p.x = 416 + 5; + p.y = Math.random() * 416; + } + } + } + + }) + + core.canvas.weather.fill(); + + } + core.animateFrame.weather.time = timestamp; + + } + window.requestAnimationFrame(draw); + } + window.requestAnimationFrame(draw); +} + ////// 显示游戏开始界面 ////// core.prototype.showStartAnimate = function (callback) { core.dom.startPanel.style.opacity=1; @@ -358,7 +540,7 @@ core.prototype.loadAutotile = function (callback) { core.material.images.autotile={}; var autotileIds = Object.keys(core.material.icons.autotile); if (autotileIds.length==0) { - core.loadMusic(callback); + core.loadAnimates(callback); return; } for (var x=0;x0){ var stepPostfix = []; var direction={'0':{'1':'down','-1':'up'},'-1':{'0':'left'},'1':{'0':'right'}}; @@ -1015,6 +1311,8 @@ core.prototype.onclick = function (x, y, stepPostfix) { if (core.isset(core.status.replay)&&core.status.replay.replaying) return; // console.log("Click: (" + x + "," + y + ")"); + stepPostfix=stepPostfix||[]; + // 非游戏屏幕内 if (x<0 || y<0 || x>12 || y>12) return; @@ -1136,6 +1434,21 @@ core.prototype.onclick = function (x, y, stepPostfix) { return; } + if (core.status.event.id == 'syncSelect') { + core.events.clickSyncSelect(x,y); + return; + } + + if (core.status.event.id == 'localSaveSelect') { + core.events.clickLocalSaveSelect(x,y); + return; + } + + if (core.status.event.id == 'cursor') { + core.events.clickCursor(x,y); + return; + } + } ////// 滑动鼠标滚轮时的操作 ////// @@ -1190,30 +1503,35 @@ core.prototype.stopAutomaticRoute = function () { if (!core.status.played) { return; } - core.stopAutoHeroMove(); - core.status.automaticRouting = false; - core.status.automaticRouted = false; - core.status.autoStepRoutes = []; - core.status.automaticRoutingTemp = {'destX': 0, 'destY': 0, 'moveStep': []}; - if (core.status.moveStepBeforeStop.length==0) + core.status.automaticRoute.autoHeroMove = false; + core.status.automaticRoute.autoStep = 0; + core.status.automaticRoute.destStep = 0; + core.status.automaticRoute.movedStep = 0; + core.status.automaticRoute.autoStepRoutes = []; + core.status.automaticRoute.destX=null; + core.status.automaticRoute.destY=null; + core.stopHero(); + if (core.status.automaticRoute.moveStepBeforeStop.length==0) core.canvas.ui.clearRect(0, 0, 416, 416); } ////// 继续剩下的自动寻路操作 ////// core.prototype.continueAutomaticRoute = function () { // 此函数只应由events.afterOpenDoor和events.afterBattle调用 - var moveStep = core.status.moveStepBeforeStop; - core.status.moveStepBeforeStop = []; - if(moveStep.length===0)return; - if(moveStep.length===1 && moveStep[0].step===1)return; - core.status.automaticRouting = true; - core.setAutoHeroMove(moveStep); + var moveStep = core.status.automaticRoute.moveStepBeforeStop; + //core.status.automaticRoute.moveStepBeforeStop = []; + if(moveStep.length===0 || (moveStep.length===1 && moveStep[0].step===1)) { + core.status.automaticRoute.moveStepBeforeStop = []; + } + else { + core.setAutoHeroMove(moveStep); + } } ////// 清空剩下的自动寻路列表 ////// core.prototype.clearContinueAutomaticRoute = function () { core.canvas.ui.clearRect(0, 0, 416, 416); - core.status.moveStepBeforeStop=[]; + core.status.automaticRoute.moveStepBeforeStop=[]; } ////// 设置自动寻路路线 ////// @@ -1221,8 +1539,23 @@ core.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { if (!core.status.played || core.status.lockControl) { return; } - else if (core.status.automaticRouting) { + // 正在寻路中 + if (core.status.automaticRoute.autoHeroMove) { + var lastX = core.status.automaticRoute.destX, lastY=core.status.automaticRoute.destY; core.stopAutomaticRoute(); + if (lastX==destX && lastY==destY) { + core.lockControl(); + setTimeout(function () { + core.unLockControl(); + if (core.canMoveDirectly(destX, destY)) { + core.clearMap('hero', 0, 0, 416, 416); + core.setHeroLoc('x', destX); + core.setHeroLoc('y', destY); + core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + core.status.route.push("move:"+destX+":"+destY); + } + }, 100); + } return; } if (destX == core.status.hero.loc.x && destY == core.status.hero.loc.y && stepPostfix.length==0) { @@ -1243,7 +1576,6 @@ core.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { var step = 0; var tempStep = null; var moveStep; - core.status.automaticRoutingTemp = {'destX': 0, 'destY': 0, 'moveStep': []}; if (!(moveStep = core.automaticRoute(destX, destY))) { if (destX == core.status.hero.loc.x && destY == core.status.hero.loc.y){ moveStep=[]; @@ -1253,8 +1585,8 @@ core.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { } } moveStep=moveStep.concat(stepPostfix); - core.status.automaticRoutingTemp.destX = destX; - core.status.automaticRoutingTemp.destY = destY; + core.status.automaticRoute.destX=destX; + core.status.automaticRoute.destY=destY; core.canvas.ui.save(); core.canvas.ui.clearRect(0, 0, 416, 416); core.canvas.ui.fillStyle = '#bfbfbf'; @@ -1269,12 +1601,14 @@ core.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { step++; } else { - core.status.automaticRoutingTemp.moveStep.push({'direction': tempStep, 'step': step}); + //core.status.automaticRoutingTemp.moveStep.push({'direction': tempStep, 'step': step}); + core.status.automaticRoute.autoStepRoutes.push({'direction': tempStep, 'step': step}); step = 1; tempStep = moveStep[m].direction; } if (m == moveStep.length - 1) { - core.status.automaticRoutingTemp.moveStep.push({'direction': tempStep, 'step': step}); + // core.status.automaticRoutingTemp.moveStep.push({'direction': tempStep, 'step': step}); + core.status.automaticRoute.autoStepRoutes.push({'direction': tempStep, 'step': step}); core.canvas.ui.fillRect(moveStep[m].x * 32 + 10, moveStep[m].y * 32 + 10, 12, 12); } else { @@ -1322,13 +1656,9 @@ core.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { } } core.canvas.ui.restore(); - core.status.automaticRouted = true; // 立刻移动 - core.status.automaticRouting = true; - // core.setAutoHeroMove(core.status.automaticRoutingTemp.moveStep); - core.setAutoHeroMove(core.status.automaticRoutingTemp.moveStep); - core.status.automaticRoutingTemp = {'destX': 0, 'destY': 0, 'moveStep': []}; + core.setAutoHeroMove(); } @@ -1360,15 +1690,21 @@ core.prototype.automaticRoute = function (destX, destY) { f=f%169; var nowX = parseInt(f / 13), nowY = f % 13; var nowIsArrow = false, nowId, nowBlock = core.getBlock(nowX,nowY); + /* if (nowBlock!=null){ nowId = nowBlock.block.event.id; nowIsArrow = nowId.slice(0, 5).toLowerCase() == 'arrow'; } + */ for (var direction in scan) { + /* if(nowIsArrow){ var nowArrow = nowId.slice(5).toLowerCase(); if (direction != nowArrow) continue; } + */ + if (!core.canMoveHero(nowX, nowY, direction)) + continue; var nx = nowX + scan[direction].x; var ny = nowY + scan[direction].y; @@ -1384,20 +1720,22 @@ core.prototype.automaticRoute = function (destX, destY) { var nextId, nextBlock = core.getBlock(nx,ny); if (nextBlock!=null){ nextId = nextBlock.block.event.id; + /* // 遇到单向箭头处理 var isArrow = nextId.slice(0, 5).toLowerCase() == 'arrow'; if(isArrow){ var nextArrow = nextId.slice(5).toLowerCase(); if ( (scan[direction].x + scan[nextArrow].x) == 0 && (scan[direction].y + scan[nextArrow].y) == 0 ) continue; } + */ // 绕过亮灯(因为只有一次通行机会很宝贵) if(nextId == "light") 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 == 'changeFloor') deepAdd = 10; } if (core.status.checkBlock.damage[nid]>0) deepAdd = core.status.checkBlock.damage[nid]; @@ -1436,6 +1774,7 @@ core.prototype.fillPosWithPoint = function (pos) { core.fillRect('ui', pos.x*32+12,pos.y*32+12,8,8, '#bfbfbf'); } +/* ////// 清除已经寻路过的部分 ////// core.prototype.clearStepPostfix = function () { if(core.status.mouseOutCheck >0){ @@ -1450,6 +1789,7 @@ core.prototype.clearStepPostfix = function () { core.canvas.ui.restore(); } } +*/ /////////// 寻路代码相关 END /////////// @@ -1457,53 +1797,27 @@ core.prototype.clearStepPostfix = function () { /////////// 自动行走 & 行走控制 /////////// -////// 停止勇士的自动行走 ////// -core.prototype.stopAutoHeroMove = function () { - core.status.autoHeroMove = false; - core.status.automaticRouting = false; - core.status.automaticRouted = false; - core.status.autoStep = 0; - core.status.destStep = 0; - core.status.movedStep = 0; - core.status.autoStepRoutes = []; - core.stopHero(); - clearInterval(core.interval.heroAutoMoveScan); -} - ////// 设置勇士的自动行走路线 ////// core.prototype.setAutoHeroMove = function (steps) { + steps=steps||core.status.automaticRoute.autoStepRoutes; if (steps.length == 0) { return; } - core.status.autoStepRoutes = steps; - core.status.autoStep = 0; - clearInterval(core.interval.heroAutoMoveScan); - core.interval.heroAutoMoveScan = window.setInterval(function () { - if (!core.status.autoHeroMove) { - if (core.status.autoStep == core.status.autoStepRoutes.length) { - core.stopAutoHeroMove(); - return; - } - core.autoHeroMove(core.status.autoStepRoutes[core.status.autoStep].direction, core.status.autoStepRoutes[core.status.autoStep].step); - core.status.autoStep++; - } - }, 80); -} - -////// 让勇士开始自动行走 ////// -core.prototype.autoHeroMove = function (direction, step) { - core.status.autoHeroMove = true; - core.status.destStep = step; - core.moveHero(direction); + core.status.automaticRoute.autoStepRoutes=steps; + core.status.automaticRoute.autoHeroMove = true; + core.status.automaticRoute.autoStep = 1; + core.status.automaticRoute.destStep = steps[0].step; + core.moveHero(steps[0].direction); } ////// 设置行走的效果动画 ////// 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=1; + // core.status.heroMoving = true; + // var moveStep = 0; var scan = { 'up': {'x': 0, 'y': -1}, 'left': {'x': -1, 'y': 0}, @@ -1511,38 +1825,34 @@ 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(); - if (core.status.heroStop) - core.drawHero(direction, core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + 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.prototype.setHeroMoveTriggerInterval = function () { - core.interval.heroMoveTriggerInterval = window.setInterval(function () { - if (!core.status.heroStop) { - core.moveAction(); - } - }, 50); + }, 12.5 / core.status.replay.speed); } ////// 实际每一步的行走过程 ////// core.prototype.moveAction = function (callback) { if (core.interval.openDoorAnimate!=null) return; // 开门判断 + if (core.status.heroMoving>0) return; var scan = { 'up': {'x': 0, 'y': -1}, 'left': {'x': -1, 'y': 0}, @@ -1555,35 +1865,52 @@ core.prototype.moveAction = function (callback) { var noPass = core.noPass(x + scan[direction].x, y + scan[direction].y), canMove = core.canMoveHero(); if (noPass || !canMove) { core.status.route.push(direction); + core.status.automaticRoute.moveStepBeforeStop = []; if (canMove) // 非箭头:触发 core.trigger(x + scan[direction].x, y + scan[direction].y); core.drawHero(direction, x, y, 'stop'); - if (core.status.autoHeroMove) { - core.status.movedStep++; - if (core.status.destStep == core.status.movedStep) { - core.status.autoHeroMove = false; - core.status.destStep = 0; - core.status.movedStep = 0; - core.status.moveStepBeforeStop=[]; + + // core.clearContinueAutomaticRoute(); + if (core.status.automaticRoute.moveStepBeforeStop.length==0) { + core.clearContinueAutomaticRoute(); + core.stopAutomaticRoute(); + } + + /* + if (core.status.automaticRoute.autoHeroMove) { + + core.status.automaticRoute.movedStep++; + if (core.status.automaticRoute.destStep == core.status.automaticRoute.movedStep) { + core.status.automaticRoute.autoHeroMove = false; + core.status.automaticRoute.destStep = 0; + core.status.automaticRoute.movedStep = 0; + core.status.automaticRoute.moveStepBeforeStop=[]; core.stopAutomaticRoute(); } } else { - core.status.heroStop = true; + // core.status.heroStop = true; + core.stopHero(); } + */ if (core.isset(callback)) callback(); } else { core.setHeroMoveInterval(direction, x, y, function () { - if (core.status.autoHeroMove) { - core.status.movedStep++; - if (core.status.destStep == core.status.movedStep) { - core.status.autoHeroMove = false; - core.status.destStep = 0; - core.status.movedStep = 0; - core.stopHero(); - core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + if (core.status.automaticRoute.autoHeroMove) { + core.status.automaticRoute.movedStep++; + if (core.status.automaticRoute.destStep == core.status.automaticRoute.movedStep) { + if (core.status.automaticRoute.autoStep == core.status.automaticRoute.autoStepRoutes.length) { + core.clearContinueAutomaticRoute(); + core.stopAutomaticRoute(); + } + else { + core.status.automaticRoute.movedStep = 0; + core.status.automaticRoute.destStep = core.status.automaticRoute.autoStepRoutes[core.status.automaticRoute.autoStep].step; + core.setHeroLoc('direction', core.status.automaticRoute.autoStepRoutes[core.status.automaticRoute.autoStep].direction); + core.status.automaticRoute.autoStep++; + } } } else if (core.status.heroStop) { @@ -1604,15 +1931,25 @@ core.prototype.turnHero = function() { else if (core.status.hero.loc.direction == 'down') core.status.hero.loc.direction = 'left'; else if (core.status.hero.loc.direction == 'left') core.status.hero.loc.direction = 'up'; core.drawHero(core.status.hero.loc.direction, core.status.hero.loc.x, core.status.hero.loc.y, 'stop', 0, 0); - core.status.automaticRoutingTemp = {'destX': 0, 'destY': 0, 'moveStep': []}; core.canvas.ui.clearRect(0, 0, 416, 416); core.status.route.push("turn"); } ////// 勇士能否前往某方向 ////// -core.prototype.canMoveHero = function() { - var direction = core.getHeroLoc('direction'); - var nowBlock = core.getBlock(core.getHeroLoc('x'),core.getHeroLoc('y')); +core.prototype.canMoveHero = function(x,y,direction,floorId) { + if (!core.isset(x)) x=core.getHeroLoc('x'); + if (!core.isset(y)) y=core.getHeroLoc('y'); + if (!core.isset(direction)) direction=core.getHeroLoc('direction'); + if (!core.isset(floorId)) floorId=core.status.floorId; + + // 检查当前块的cannotMove + if (core.isset(core.floors[floorId].cannotMove)) { + var cannotMove = core.floors[floorId].cannotMove[x+","+y]; + if (core.isset(cannotMove) && cannotMove instanceof Array && cannotMove.indexOf(direction)>=0) + return false; + } + + var nowBlock = core.getBlock(x,y,floorId); if (nowBlock!=null){ nowId = nowBlock.block.event.id; var nowIsArrow = nowId.slice(0, 5).toLowerCase() == 'arrow'; @@ -1629,7 +1966,7 @@ core.prototype.canMoveHero = function() { 'down': {'x': 0, 'y': 1}, 'right': {'x': 1, 'y': 0} }; - var nextBlock = core.getBlock(core.nextX(),core.nextY()); + var nextBlock = core.getBlock(x+scan[direction].x,y+scan[direction].y); if (nextBlock!=null){ nextId = nextBlock.block.event.id; // 遇到单向箭头处理 @@ -1644,12 +1981,55 @@ core.prototype.canMoveHero = function() { return true; } +////// 能否瞬间移动 ////// +core.prototype.canMoveDirectly = function (destX,destY) { + if (!core.flags.enableMoveDirectly) return false; + + // 中毒状态:不能 + if (core.hasFlag('poison')) return false; + + var fromX = core.getHeroLoc('x'), fromY = core.getHeroLoc('y'); + if (fromX==destX&&fromY==destY) return false; + + // BFS + var visited=[], queue=[]; + visited[13*fromX+fromY]=true; + queue.push(13*fromX+fromY); + + var directions = [[-1,0],[1,0],[0,1],[0,-1]]; + while (queue.length>0) { + var now=queue.shift(), nowX=parseInt(now/13), nowY=now%13; + + for (var dir in directions) { + var nx=nowX+directions[dir][0], ny=nowY+directions[dir][1]; + if (nx<0||nx>=13||ny<0||ny>=13||visited[13*nx+ny]||core.getBlock(nx,ny)!=null||core.status.checkBlock.damage[13*nx+ny]>0) continue; + if (nx==destX&&ny==destY) return true; + visited[13*nx+ny]=true; + queue.push(13*nx+ny); + } + } + return false; +} + ////// 让勇士开始移动 ////// core.prototype.moveHero = function (direction, callback) { + // 如果正在移动,直接return + if (core.status.heroMoving>0) return; if (core.isset(direction)) core.setHeroLoc('direction', direction); if (!core.isset(callback)) { // 如果不存在回调函数,则使用heroMoveTrigger core.status.heroStop = false; + if (core.interval.heroMoveTriggerInterval==null) { + core.moveAction(); + core.interval.heroMoveTriggerInterval = setInterval(function () { + if (!core.status.heroStop) { + core.moveAction(); + } + else { + core.stopHero(); + } + }, 50) + } } else { // 否则,只向某个方向移动一步,然后调用callback core.moveAction(function () { @@ -1719,7 +2099,7 @@ core.prototype.eventMoveHero = function(steps, time, callback) { moveSteps.shift(); } } - }, time/8); + }, time / 8 / core.status.replay.speed) } ////// 每移动一格后执行的事件 ////// @@ -1756,13 +2136,16 @@ core.prototype.waitHeroToStop = function(callback) { ////// 停止勇士的移动状态 ////// core.prototype.stopHero = function () { core.status.heroStop = true; + clearInterval(core.interval.heroMoveTriggerInterval); + core.interval.heroMoveTriggerInterval=null; } ////// 绘制勇士 ////// core.prototype.drawHero = function (direction, x, y, status, offsetX, offsetY) { offsetX = offsetX || 0; offsetY = offsetY || 0; - core.clearAutomaticRouteNode(x, y); + var dx=offsetX==0?0:offsetX/Math.abs(offsetX), dy=offsetY==0?0:offsetY/Math.abs(offsetY); + core.clearAutomaticRouteNode(x+dx, y+dy); var heroIcon = core.material.icons.hero[direction]; x = x * 32; y = y * 32; @@ -1828,11 +2211,11 @@ core.prototype.openDoor = function (id, x, y, needKey, callback) { if (core.isset(callback)) callback(); return; } - if (core.status.moveStepBeforeStop.length==0) { - core.status.moveStepBeforeStop=core.status.autoStepRoutes.slice(core.status.autoStep-1,core.status.autoStepRoutes.length); - if (core.status.moveStepBeforeStop.length>=1)core.status.moveStepBeforeStop[0].step-=core.status.movedStep; + if (core.status.automaticRoute.moveStepBeforeStop.length==0) { + core.status.automaticRoute.moveStepBeforeStop=core.status.automaticRoute.autoStepRoutes.slice(core.status.automaticRoute.autoStep-1,core.status.automaticRoute.autoStepRoutes.length); + if (core.status.automaticRoute.moveStepBeforeStop.length>=1)core.status.automaticRoute.moveStepBeforeStop[0].step-=core.status.automaticRoute.movedStep; } - core.stopHero(); + core.stopAutomaticRoute(); var speed=30; if (needKey) { @@ -1845,6 +2228,10 @@ core.prototype.openDoor = function (id, x, y, needKey, callback) { return; } } + + if (!core.isset(core.status.event.id)) // 自动存档 + core.autosave(true); + // open core.playSound("door.ogg"); var state = 0; @@ -1872,9 +2259,9 @@ core.prototype.openDoor = function (id, x, y, needKey, callback) { ////// 战斗 ////// core.prototype.battle = function (id, x, y, force, callback) { - if (core.status.moveStepBeforeStop.length==0) { - core.status.moveStepBeforeStop=core.status.autoStepRoutes.slice(core.status.autoStep-1,core.status.autoStepRoutes.length); - if (core.status.moveStepBeforeStop.length>=1)core.status.moveStepBeforeStop[0].step-=core.status.movedStep; + if (core.status.automaticRoute.moveStepBeforeStop.length==0) { + core.status.automaticRoute.moveStepBeforeStop=core.status.automaticRoute.autoStepRoutes.slice(core.status.automaticRoute.autoStep-1,core.status.automaticRoute.autoStepRoutes.length); + if (core.status.automaticRoute.moveStepBeforeStop.length>=1)core.status.automaticRoute.moveStepBeforeStop[0].step-=core.status.automaticRoute.movedStep; } core.stopHero(); core.stopAutomaticRoute(); @@ -1886,6 +2273,10 @@ core.prototype.battle = function (id, x, y, force, callback) { core.clearContinueAutomaticRoute(); return; } + + if (!core.isset(core.status.event.id)) // 自动存档 + core.autosave(true); + if (core.flags.battleAnimate&&!core.status.replay.replaying) { core.waitHeroToStop(function() { core.ui.drawBattleAnimate(id, function() { @@ -1894,7 +2285,16 @@ core.prototype.battle = function (id, x, y, force, callback) { }); } else { - core.playSound('attack.ogg'); + + if (core.flags.equipment && core.getFlag('sword', 'sword0')!='sword0') { + core.playSound('zone.ogg'); + core.drawAnimate('sword', x, y); + } + else { + core.playSound('attack.ogg'); + core.drawAnimate('hand', x, y); + } + core.afterBattle(id, x, y, callback); } } @@ -1944,15 +2344,26 @@ core.prototype.trigger = function (x, y) { } if (core.isset(mapBlocks[b].event) && core.isset(mapBlocks[b].event.trigger)) { var trigger = mapBlocks[b].event.trigger; + // 转换楼层能否穿透 - /* - if (trigger=='changeFloor' && (core.status.autoHeroMove || core.status.autoStep= core.values.animateSpeed * 2 / animateValue) { animateCurrent++; animateTime = 0; @@ -2476,14 +2910,14 @@ core.prototype.moveBlock = function(x,y,steps,time,immediateHide,callback) { if (moveSteps.length==0) { if (immediateHide) opacityVal=0; else opacityVal -= 0.06; - core.setOpacity('data', opacityVal); - core.clearMap('data', nowX, nowY, 32, 32); - core.canvas.data.drawImage(blockImage, animateCurrent * 32, blockIcon * 32, 32, 32, nowX, nowY, 32, 32); + core.setOpacity('animate', opacityVal); + core.clearMap('animate', nowX, nowY, 32, 32); + core.canvas.animate.drawImage(blockImage, animateCurrent * 32, blockIcon * 32, 32, 32, nowX, nowY, 32, 32); if (opacityVal<=0) { clearInterval(animate); - core.loadCanvas('data'); - core.clearMap('data', 0, 0, 416, 416); - core.setOpacity('data', 1); + core.loadCanvas('animate'); + core.clearMap('animate', 0, 0, 416, 416); + core.setOpacity('animate', 1); core.status.replay.animate=false; if (core.isset(callback)) callback(); } @@ -2493,16 +2927,16 @@ core.prototype.moveBlock = function(x,y,steps,time,immediateHide,callback) { step++; nowX+=scan[moveSteps[0]].x*2; nowY+=scan[moveSteps[0]].y*2; - core.clearMap('data', nowX-32, nowY-32, 96, 96); + core.clearMap('animate', nowX-32, nowY-32, 96, 96); // 绘制 - core.canvas.data.drawImage(blockImage, animateCurrent * 32, blockIcon * 32, 32, 32, nowX, nowY, 32, 32); + core.canvas.animate.drawImage(blockImage, animateCurrent * 32, blockIcon * 32, 32, 32, nowX, nowY, 32, 32); if (step==16) { // 该移动完毕,继续 step=0; moveSteps.shift(); } } - }, time/16); + }, time / 16 / core.status.replay.speed); } ////// 显示/隐藏某个块时的动画效果 ////// @@ -2510,9 +2944,9 @@ core.prototype.animateBlock = function (x,y,type,time,callback) { if (type!='hide') type='show'; core.status.replay.animate=true; - clearInterval(core.interval.tipAnimate); - core.saveCanvas('data'); - core.clearMap('data', 0, 0, 416, 416); + //clearInterval(core.interval.tipAnimate); + core.saveCanvas('animate'); + core.clearMap('animate', 0, 0, 416, 416); var block = core.getBlock(x,y,core.status.floorId,false); if (block==null) {// 不存在 @@ -2520,8 +2954,8 @@ core.prototype.animateBlock = function (x,y,type,time,callback) { return; } // 清空UI - core.clearMap('ui', 0, 0, 416, 416); - core.setAlpha('ui', 1.0); + //core.clearMap('ui', 0, 0, 416, 416); + //core.setAlpha('ui', 1.0); block=block.block; blockIcon = core.material.icons[block.event.cls][block.event.id]; @@ -2530,24 +2964,24 @@ core.prototype.animateBlock = function (x,y,type,time,callback) { var opacityVal = 0; if (type=='hide') opacityVal=1; - core.setOpacity('data', opacityVal); - core.canvas.data.drawImage(blockImage, 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32); + core.setOpacity('animate', opacityVal); + core.canvas.animate.drawImage(blockImage, 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32); var animate = window.setInterval(function () { if (type=='show') opacityVal += 0.1; else opacityVal -= 0.1; - core.setOpacity('data', opacityVal); - core.clearMap('data',block.x * 32, block.y * 32, 32, 32); - core.canvas.data.drawImage(blockImage, 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32); + core.setOpacity('animate', opacityVal); + core.clearMap('animate',block.x * 32, block.y * 32, 32, 32); + core.canvas.animate.drawImage(blockImage, 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32); if (opacityVal >=1 || opacityVal<=0) { clearInterval(animate); - core.loadCanvas('data'); - core.clearMap('data', 0, 0, 416, 416); - core.setOpacity('data', 1); + core.loadCanvas('animate'); + core.clearMap('animate', 0, 0, 416, 416); + core.setOpacity('animate', 1); core.status.replay.animate=false; if (core.isset(callback)) callback(); } - }, time/10); + }, time / 10 / core.status.replay.speed); } ////// 将某个块从禁用变成启用状态 ////// @@ -2565,8 +2999,10 @@ core.prototype.showBlock = function(x, y, floodId) { blockImage = core.material.images[block.event.cls]; core.canvas.event.drawImage(core.material.images[block.event.cls], 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32); core.addGlobalAnimate(block.event.animate, block.x * 32, block.y * 32, blockIcon, blockImage); - core.setGlobalAnimate(core.values.animateSpeed); + // core.setGlobalAnimate(core.values.animateSpeed); + core.syncGlobalAnimate(); } + core.updateStatusBar(); } } @@ -2660,6 +3096,7 @@ core.prototype.removeGlobalAnimate = function (x, y, all) { ////// 设置全局动画的显示效果 ////// core.prototype.setGlobalAnimate = function (speed) { + /* clearInterval(core.interval.twoAnimate); clearInterval(core.interval.fourAnimate); var animateClose = false; @@ -2685,6 +3122,10 @@ core.prototype.setGlobalAnimate = function (speed) { animateClose = false; } }, speed / 2); + */ + core.syncGlobalAnimate(); + core.animateFrame.speed = speed; + core.animateFrame.globalAnimate = true; } ////// 同步所有的全局动画效果 ////// @@ -2697,30 +3138,86 @@ 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); } } +////// 绘制动画 ////// +core.prototype.drawAnimate = function (name, x, y, callback) { + + // 正在播放录像:不显示动画 + if (core.isset(core.status.replay) && core.status.replay.replaying) { + if (core.isset(callback)) callback(); + return; + } + + // 检测动画是否存在 + if (!core.isset(core.material.animates[name]) || !core.isset(x) || !core.isset(y)) { + if (core.isset(callback)) callback(); + return; + } + + // 清空animate层 + clearInterval(core.interval.animateInterval); + core.clearMap('animate', 0, 0, 416, 416); + + // 开始绘制 + var animate = core.material.animates[name]; + var ratio = animate.ratio; + var centerX = 32*x+16, centerY = 32*y+16; + var index=0; + + var draw = function (index) { + core.clearMap('animate', 0, 0, 416, 416); + + var frame = animate.frames[index]; + frame.forEach(function (t) { + var image = animate.images[t.index]; + if (!core.isset(image)) return; + var realWidth = image.width * ratio * t.zoom / 100; + var realHeight = image.height * ratio * t.zoom / 100; + core.setAlpha('animate', t.opacity / 255); + + var cx = centerX+t.x, cy=centerY+t.y; + + if (!t.mirror && !t.angle) { + core.canvas.animate.drawImage(image, cx-realWidth/2, cy-realHeight/2, realWidth, realHeight); + } + else { + core.saveCanvas('animate'); + core.canvas.animate.translate(cx,cy); + if (t.angle) + core.canvas.animate.rotate(-t.angle*Math.PI/180); + if (t.mirror) + core.canvas.animate.scale(-1,1); + core.canvas.animate.drawImage(image, -realWidth/2, -realHeight/2, realWidth, realHeight); + core.loadCanvas('animate'); + } + }) + } + + draw(index++); + + core.interval.animateInterval = setInterval(function (t) { + if (index == animate.frames.length) { + clearInterval(core.interval.animateInterval); + core.clearMap('animate', 0, 0, 416, 416); + core.setAlpha('animate', 1); + if (core.isset(callback)) callback(); + return; + } + draw(index++); + }, 50); +} + ////// 更新领域、夹击、阻击的伤害地图 ////// core.prototype.updateCheckBlock = function() { core.status.checkBlock = {}; @@ -2852,6 +3349,10 @@ core.prototype.checkBlock = function () { else if (damage>0) { core.drawTip('受到领域伤害'+damage+'点'); } + + core.playSound('zone.ogg'); + core.drawAnimate("zone", x, y); + if (core.status.hero.hp<=0) { core.status.hero.hp=0; core.updateStatusBar(); @@ -2987,6 +3488,59 @@ core.prototype.snipe = function (snipes) { } +////// 更改天气效果 ////// +core.prototype.setWeather = function (type, level) { + + // 非雨雪 + if (type!='rain' && type!='snow') { + core.clearMap('weather', 0, 0, 416, 416) + core.animateFrame.weather.type = null; + core.animateFrame.weather.level = 0; + core.animateFrame.weather.nodes = []; + return; + } + + level = parseInt(level); + + // 当前天气:则忽略 + if (type==core.animateFrame.weather.type && + (!core.isset(level) || 20*level==core.animateFrame.weather.level)) { + return; + } + + if (!core.isset(level)) level=5; + if (level<1) level=1; if (level>10) level=10; + level *= 20; + + core.clearMap('weather', 0, 0, 416, 416) + core.animateFrame.weather.type = type; + core.animateFrame.weather.level = level; + + core.animateFrame.weather.nodes = []; + + if (type == 'rain') { + for (var a=0;a1) color[3]=1; - if (time==0) { // 直接变色 - var nowR = parseInt(color[0]), nowG = parseInt(color[1]), nowB = parseInt(color[2]); - var toRGB = "#"+((1<<24)+(nowR<<16)+(nowG<<8)+nowB).toString(16).slice(1); - core.dom.curtain.style.background = toRGB; + core.dom.curtain.style.background = core.arrayToRGB(color); core.dom.curtain.style.opacity = color[3]; core.status.curtainColor = color; if (core.isset(callback)) callback(); @@ -3026,12 +3577,7 @@ core.prototype.setFg = function(color, time, callback) { 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); - if (nowR<0) nowR=0; if (nowR>255) nowR=255; - if (nowG<0) nowG=0; if (nowG>255) nowG=255; - if (nowB<0) nowB=0; if (nowB>255) nowB=255; - - var toRGB = "#"+((1<<24)+(nowR<<16)+(nowG<<8)+nowB).toString(16).slice(1); - core.dom.curtain.style.background = toRGB; + core.dom.curtain.style.background = core.arrayToRGB([nowR,nowG,nowB]); core.dom.curtain.style.opacity = nowAlpha; if (step>=25) { @@ -3473,6 +4019,14 @@ core.prototype.setTwoDigits = function (x) { return parseInt(x)<10?"0"+x:x; } +////// 数组转RGB ////// +core.prototype.arrayToRGB = function (color) { + var nowR = parseInt(color[0])||0, nowG = parseInt(color[1])||0, nowB = parseInt(color[2])||0; + if (nowR<0) nowR=0; if (nowB<0) nowB=0;if (nowG<0) nowG=0; + if (nowR>255) nowR=255; if (nowB>255) nowB=255; if (nowG>255) nowG=255; + return "#"+((1<<24)+(nowR<<16)+(nowG<<8)+nowB).toString(16).slice(1); +} + ////// 作弊 ////// core.prototype.debug = function() { core.setStatus('hp', 999999); @@ -3493,22 +4047,79 @@ core.prototype.debug = function() { core.drawTip("作弊成功"); } -////// 回放 ////// -core.prototype.replay = function (list) { +////// 开始播放 ////// +core.prototype.startReplay = function (list) { + core.status.replay.replaying=true; + core.status.replay.pausing=false; + core.status.replay.speed=1.0; + core.status.replay.toReplay = core.clone(list); + core.status.replay.totalList = core.clone(list); + core.updateStatusBar(); + core.drawTip("开始播放"); + this.replay(); + return; +} - if (core.isset(list) && (list instanceof Array)) { - core.status.replay.replaying=true; - core.status.replay.toReplay = core.clone(list); - this.replay(); - return; - } +////// 更改播放状态 ////// +core.prototype.triggerReplay = function () { + if (core.status.replay.pausing) this.resumeReplay(); + else this.pauseReplay(); +} + +////// 暂停播放 ////// +core.prototype.pauseReplay = function () { + if (!core.status.replay.replaying) return; + core.status.replay.pausing = true; + core.updateStatusBar(); + core.drawTip("暂停播放"); +} + +////// 恢复播放 ////// +core.prototype.resumeReplay = function () { + if (!core.status.replay.replaying) return; + core.status.replay.pausing = false; + core.updateStatusBar(); + core.drawTip("恢复播放"); + core.replay(); +} + +////// 加速播放 ////// +core.prototype.forwardReplay = function () { + if (!core.status.replay.replaying) return; + core.status.replay.speed = parseInt(10*core.status.replay.speed + 1)/10; + if (core.status.replay.speed>2.5) core.status.replay.speed=2.5; + core.drawTip("x"+core.status.replay.speed+"倍"); +} + +////// 减速播放 ////// +core.prototype.rewindReplay = function () { + if (!core.status.replay.replaying) return; + core.status.replay.speed = parseInt(10*core.status.replay.speed - 1)/10; + if (core.status.replay.speed<0.3) core.status.replay.speed=0.3; + core.drawTip("x"+core.status.replay.speed+"倍"); +} + +////// 停止播放 ////// +core.prototype.stopReplay = function () { + if (!core.status.replay.replaying) return; + core.status.replay.toReplay = []; + core.status.replay.totalList = []; + core.status.replay.replaying=false; + core.status.replay.pausing=false; + core.status.replay.speed=1.0; + core.updateStatusBar(); + core.drawTip("停止播放并恢复游戏"); +} + +////// 回放 ////// +core.prototype.replay = function () { if (!core.status.replay.replaying) return; // 没有回放 if (core.status.replay.pausing) return; // 暂停状态 if (core.status.replay.animate) return; // 正在某段动画中 if (core.status.replay.toReplay.length==0) { // 回放完毕 - core.status.replay.replaying=false; + core.stopReplay(); core.insertAction("录像回放完毕!"); return; } @@ -3534,7 +4145,7 @@ core.prototype.replay = function (list) { core.useItem(itemId, function () { core.replay(); }); - }, 500); + }, 750); } return; } @@ -3548,11 +4159,11 @@ core.prototype.replay = function (list) { setTimeout(function () { core.ui.closePanel(); var stair=toIndex=choices.length || !core.events.clickShop(6, topIndex+selection)) { - clearInterval(shopInterval); - core.status.replay.replaying=false; - core.drawTip("录像文件出错"); - return; - } - }, 500); + core.status.event.selection = parseInt(selections.shift()); + core.events.openShop(shopId, false); + + }, 750); return; } } @@ -3602,8 +4218,21 @@ core.prototype.replay = function (list) { } } } + else if (action.indexOf('move:')==0) { + var pos=action.substring(5).split(":"); + var x=parseInt(pos[0]), y=parseInt(pos[1]); + if (core.canMoveDirectly(x,y)) { + core.clearMap('hero', 0, 0, 416, 416); + core.setHeroLoc('x', x); + core.setHeroLoc('y', y); + core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + core.status.route.push("move:"+x+":"+y); + core.replay(); + return; + } + } - core.status.replay.replaying=false; + core.stopReplay(); core.insertAction("录像文件出错"); } @@ -3626,7 +4255,6 @@ core.prototype.checkStatus = function (name, need, item) { } core.lockControl(); - core.status.automaticRoutingTemp = {'destX': 0, 'destY': 0, 'moveStep': []}; core.status.event.id = name; return true; } @@ -3634,6 +4262,20 @@ core.prototype.checkStatus = function (name, need, item) { ////// 点击怪物手册时的打开操作 ////// core.prototype.openBook = function (need) { if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + + // 当前是book,且从“浏览地图”打开 + if (core.status.event.id == 'book' && core.isset(core.status.event.selection)) { + core.status.boxAnimateObjs = []; + core.ui.drawMaps(core.status.event.selection); + return; + } + + // 从“浏览地图”页面打开 + if (core.status.event.id=='viewMaps') { + need=false; + core.status.event.selection = core.status.event.data; + } + if (!core.checkStatus('book', need, true)) return; core.useItem('book'); @@ -3771,6 +4413,151 @@ core.prototype.doSL = function (id, type) { } } +////// 同步存档到服务器 ////// +core.prototype.syncSave = function (type) { + var saves=null; + // data + if (type=='all') { + saves=[]; + for (var i=1;i<=150;i++) { + var data = core.getLocalStorage("save"+i, null); + if (core.isset(data)) { + saves.push(data); + } + } + } + else { + for (var i=150;i>=1;i--) { + saves=core.getLocalStorage("save"+i, null); + if (core.isset(saves)) { + break; + } + } + } + if (!core.isset(saves)) { + core.drawText("没有要同步的存档"); + return; + } + core.ui.drawWaiting("正在同步,请稍后..."); + + var formData = new FormData(); + formData.append('type', 'save'); + formData.append('name', core.firstData.name); + var save_text = JSON.stringify(saves); + formData.append('data', save_text); + + // send + var xhr = new XMLHttpRequest(); + xhr.open("POST", "/games/sync.php"); + xhr.onload = function(e) { + if (xhr.status==200) { + // console.log("同步成功。"); + var response = JSON.parse(xhr.response); + if (response.code<0) { + core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:"+response.msg); + } + else { + core.drawText("同步成功!\n\n您的存档编号: "+response.code+"\n您的存档密码: "+response.msg+"\n\n请牢记以上两个信息(如截图等),在从服务器\n同步存档时使用。") + } + } + else { + core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:HTTP "+xhr.status); + } + }; + xhr.ontimeout = function() { + core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:Timeout"); + } + xhr.onerror = function() { + core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:XHR Error"); + } + xhr.send(formData); +} + +////// 从服务器加载存档 ////// +core.prototype.syncLoad = function () { + var id = prompt("请输入存档编号:"); + if (id==null || id=="") { + core.ui.drawSyncSave(); return; + } + var password = prompt("请输入存档密码:"); + if (password==null || password=="") { + core.ui.drawSyncSave(); return; + } + core.ui.drawWaiting("正在同步,请稍后..."); + + var formData = new FormData(); + formData.append('type', 'load'); + formData.append('name', core.firstData.name); + formData.append('id', id); + formData.append('password', password); + + // send + var xhr = new XMLHttpRequest(); + xhr.open("POST", "/games/sync.php"); + xhr.onload = function(e) { + if (xhr.status==200) { + // console.log("同步成功。"); + var response = JSON.parse(xhr.response); + switch (response.code) { + case 0: + // 成功 + var data=JSON.parse(response.msg); + // console.log(data); + + if (data instanceof Array) { + core.status.event.selection=1; + core.ui.drawConfirmBox("所有本地存档都将被覆盖,确认?", function () { + for (var i=1;i<=150;i++) { + if (i<=data.length) { + core.setLocalStorage("save"+i, data[i-1]); + } + else { + core.removeLocalStorage("save"+i); + } + } + core.drawText("同步成功!\n你的本地所有存档均已被覆盖。"); + }, function () { + core.status.event.selection=0; + core.ui.drawSyncSave(); + }) + } + else { + // 只覆盖单存档 + var index=150; + for (var i=150;i>=1;i--) { + if (core.getLocalStorage("save"+i, null)==null) + index=i; + else break; + } + core.setLocalStorage("save"+index, data); + core.drawText("同步成功!\n单存档已覆盖至存档"+index); + } + break; + case -1: + core.drawText("出错啦!\n存档编号"+id+"不存在!"); + break; + case -2: + core.drawText("出错啦!\n存档密码错误!"); + break; + default: + core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:"+response.msg); + break; + } + } + else { + core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:HTTP "+xhr.status); + } + }; + xhr.ontimeout = function() { + core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:Timeout"); + } + xhr.onerror = function() { + core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:XHR Error"); + } + xhr.send(formData); +} +/* + ////// 存档同步操作 ////// core.prototype.syncSave = function(type) { if (type=='save') { @@ -3892,6 +4679,7 @@ core.prototype.syncSave = function(type) { } } +*/ ////// 存档到本地 ////// core.prototype.saveData = function(dataId) { @@ -3931,7 +4719,7 @@ core.prototype.loadData = function (data, callback) { core.events.afterLoadData(data); core.changeFloor(data.floorId, null, data.hero.loc, 0, function() { - core.setHeroMoveTriggerInterval(); + //core.setHeroMoveTriggerInterval(); if (core.isset(callback)) callback(); }); } @@ -3975,6 +4763,11 @@ core.prototype.encodeRoute = function (route) { ans+='G'; else if (t.indexOf('input:')==0) ans+="P"+t.substring(6); + else if (t=='no') + ans+='N'; + else if (t.indexOf('move:')==0) { + ans+="M"+t.substring(5); + } } }); if (cnt>0) { @@ -4018,6 +4811,8 @@ core.prototype.decodeRoute = function (route) { case "T": ans.push("turn"); break; case "G": ans.push("getNext"); break; case "P": ans.push("input:"+number); break; + case "N": ans.push("no"); break; + case "M": ++index; ans.push("move:"+number+":"+getNumber()); break; } } return ans; @@ -4076,7 +4871,7 @@ core.prototype.unLockControl = function () { ////// 判断某对象是否不为undefined也不会null ////// core.prototype.isset = function (val) { - if (val == undefined || val == null) { + if (val == undefined || val == null || (typeof val=='number' && isNaN(val))) { return false; } return true @@ -4111,6 +4906,7 @@ core.prototype.readFile = function (success, error) { return; } core.platform.fileReader.readAsText(core.platform.fileInput.files[0]); + core.platform.fileInput.value = ''; } } @@ -4407,16 +5203,52 @@ core.prototype.updateStatusBar = function () { } core.statusBar.hard.innerHTML = core.status.hard; - if (core.hasItem('book')) { + + + // 回放 + if (core.status.replay.replaying) { + core.statusBar.image.book.src = core.status.replay.pausing?core.statusBar.icons.play.src:core.statusBar.icons.pause.src; core.statusBar.image.book.style.opacity = 1; - } else { - core.statusBar.image.book.style.opacity = 0.3; - } - if (core.hasItem('fly')) { + + core.statusBar.image.fly.src = core.statusBar.icons.stop.src; core.statusBar.image.fly.style.opacity = 1; - } else { - core.statusBar.image.fly.style.opacity = 0.3; + + //core.statusBar.image.toolbox.src = core.statusBar.icons.forward.src; + core.statusBar.image.toolbox.style.opacity = 0; + + core.statusBar.image.shop.style.opacity = 0; + + core.statusBar.image.save.src = core.statusBar.icons.rewind.src; + core.statusBar.image.save.style.opacity = 1; + + core.statusBar.image.load.src = core.statusBar.icons.forward.src; + core.statusBar.image.load.style.opacity = 1; + + core.statusBar.image.settings.style.opacity = 0; + } + else { + core.statusBar.image.book.src = core.statusBar.icons.book.src; + core.statusBar.image.book.style.opacity = core.hasItem('book')?1:0.3; + + core.statusBar.image.fly.src = core.statusBar.icons.fly.src; + core.statusBar.image.fly.style.opacity = core.hasItem('fly')?1:0.3; + + core.statusBar.image.toolbox.src = core.statusBar.icons.toolbox.src; + core.statusBar.image.toolbox.style.opacity = 1; + + core.statusBar.image.shop.style.opacity = 1; + + core.statusBar.image.save.src = core.statusBar.icons.save.src; + core.statusBar.image.save.style.opacity = 1; + + core.statusBar.image.load.src = core.statusBar.icons.load.src; + core.statusBar.image.load.style.opacity = 1; + + core.statusBar.image.settings.src = core.statusBar.icons.settings.src; + core.statusBar.image.settings.style.opacity = 1; + } + core.updateFg(); } diff --git a/libs/data.js b/libs/data.js index 4013a16b..02efe2b4 100644 --- a/libs/data.js +++ b/libs/data.js @@ -6,7 +6,7 @@ data.prototype.init = function() { this.firstData = { "title": "魔塔样板", // 游戏名,将显示在标题页面以及切换楼层的界面中 "name": "template", // 游戏的唯一英文标识符。由英文、数字、下划线组成,不能超过20个字符。 - "version": "Ver 1.3.2", // 当前游戏版本;版本不一致的存档不能通用。 + "version": "Ver 1.4.1", // 当前游戏版本;版本不一致的存档不能通用。 "floorId": "sample0", // 初始楼层ID "hero": { // 勇士初始数据 "name": "阳光", // 勇士名;可以改成喜欢的 @@ -159,6 +159,7 @@ data.prototype.init = function() { "bombFourDirections": true, // 使用炸弹是否四个方向都会炸;如果false则只炸面前的怪物(即和圣锤等价) "bigKeyIsBox": false, // 如果此项为true,则视为钥匙盒,红黄蓝钥匙+1;若为false,则视为大黄门钥匙 "equipment": false, // 剑和盾是否直接作为装备。如果此项为true,则作为装备,需要在道具栏使用,否则将直接加属性。 + "enableDeleteItem": true, // 是否允许删除(丢弃)道具 /****** 怪物相关 ******/ "enableNegativeDamage": true, // 是否支持负伤害(回血) "hatredDecrease": true, // 是否在和仇恨怪战斗后减一半的仇恨值,此项为false则和仇恨怪不会扣减仇恨值。 @@ -173,6 +174,8 @@ data.prototype.init = function() { "enableGentleClick": true, // 是否允许轻触(获得面前物品) "potionWhileRouting": false, // 寻路算法是否经过血瓶;如果该项为false,则寻路算法会自动尽量绕过血瓶 "enableViewMaps": true, // 是否支持在菜单栏中查看所有楼层的地图 + "portalWithoutTrigger": true, // 是否支持穿透。所谓穿透,即当自动寻路经过楼梯时,不触发楼层转换事件而是穿过它。 + "enableMoveDirectly": true, // 是否允许瞬间移动 } } diff --git a/libs/enemys.js b/libs/enemys.js index ed33c7d5..4cfaa0ae 100644 --- a/libs/enemys.js +++ b/libs/enemys.js @@ -289,10 +289,11 @@ enemys.prototype.calDamage = function (monster, hero_hp, hero_atk, hero_def, her } ////// 获得当前楼层的怪物列表 ////// -enemys.prototype.getCurrentEnemys = function () { +enemys.prototype.getCurrentEnemys = function (floorId) { + floorId=floorId||core.status.floorId; var enemys = []; var used = {}; - var mapBlocks = core.status.thisMap.blocks; + var mapBlocks = core.status.maps[floorId].blocks; for (var b = 0; b < mapBlocks.length; b++) { if (core.isset(mapBlocks[b].event) && !(core.isset(mapBlocks[b].enable) && !mapBlocks[b].enable) && mapBlocks[b].event.cls == 'enemys') { var monsterId = mapBlocks[b].event.id; diff --git a/libs/events.js b/libs/events.js index a7074d55..457cedea 100644 --- a/libs/events.js +++ b/libs/events.js @@ -6,7 +6,7 @@ function events() { events.prototype.init = function () { this.events = { 'battle': function (data, core, callback) { - core.autosave(true); + //core.autosave(true); core.battle(data.event.id, data.x, data.y); if (core.isset(callback)) callback(); @@ -17,7 +17,7 @@ events.prototype.init = function () { callback(); }, 'openDoor': function (data, core, callback) { - core.autosave(true); + //core.autosave(true); core.openDoor(data.event.id, data.x, data.y, true, function () { if (core.isset(callback)) callback(); core.replay(); @@ -115,14 +115,14 @@ events.prototype.setInitData = function (hard) { events.prototype.win = function(reason) { core.ui.closePanel(); var replaying = core.status.replay.replaying; - core.status.replay.replaying=false; + core.stopReplay(); core.waitHeroToStop(function() { core.removeGlobalAnimate(0,0,true); core.clearMap('all'); // 清空全地图 core.drawText([ "\t[恭喜通关]你的分数是${status:hp}。" ], function () { - core.events.gameOver(true, replaying); + core.events.gameOver('', replaying); }) }); } @@ -131,24 +131,23 @@ events.prototype.win = function(reason) { events.prototype.lose = function(reason) { core.ui.closePanel(); var replaying = core.status.replay.replaying; - core.status.replay.replaying=false; + core.stopReplay(); core.waitHeroToStop(function() { - core.status.replay.replaying=false; core.drawText([ "\t[结局1]你死了。\n如题。" ], function () { - core.events.gameOver(false, replaying); + core.events.gameOver(null, replaying); }); }) } ////// 游戏结束 ////// -events.prototype.gameOver = function (success, fromReplay) { +events.prototype.gameOver = function (ending, fromReplay) { // 上传成绩 var confirmUpload = function () { - if (!success) { + if (!core.isset(ending)) { core.restart(); return; } @@ -164,6 +163,7 @@ events.prototype.gameOver = function (success, fromReplay) { formData.append('platform', core.platform.isPC?"PC":core.platform.isAndroid?"Android":core.platform.isIOS?"iOS":""); formData.append('hard', core.status.hard); formData.append('username', username); + formData.append('ending', ending); formData.append('lv', core.status.hero.lv); formData.append('hp', core.status.hero.hp); formData.append('atk', core.status.hero.atk); @@ -224,14 +224,14 @@ events.prototype.afterChangeFloor = function (floorId) { if (!core.hasFlag("visited_"+floorId)) { this.doEvents(core.floors[floorId].firstArrive, null, null, function () { - core.autosave(); + //core.autosave(); }); core.setFlag("visited_"+floorId, true); return; } // 自动存档 - core.autosave(); + //core.autosave(); } ////// 开始执行一系列自定义事件 ////// @@ -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); @@ -287,11 +287,23 @@ events.prototype.doAction = function() { core.status.event.data.type=data.type; switch (data.type) { case "text": // 文字/对话 - if (core.status.replay.isreplaying) + if (core.status.replay.replaying) core.events.doAction(); else core.ui.drawTextBox(data.data); break; + case "setText": // 设置文本状态 + if (data.position=='up'||data.position=='down'||data.position=='center') { + core.status.textAttribute.position=data.position; + } + ["background", "title", "text"].forEach(function (t) { + if (core.isset(data[t]) && (data[t] instanceof Array) && data[t].length>=3) { + if (data[t].length==3) data[t].push(1); + core.status.textAttribute[t]=data[t]; + } + }) + core.events.doAction(); + break; case "tip": core.drawTip(core.replaceText(data.text)); core.events.doAction(); @@ -322,6 +334,48 @@ events.prototype.doAction = function() { } else this.doAction(); break; + case "setBlock": // 设置某图块 + { + if (core.isset(data.loc)) { + x=data.loc[0]; + y=data.loc[1]; + } + var floorId = data.floorId||core.status.floorId; + var originBlock=core.getBlock(x,y,toId,false); + var block = core.maps.getBlock(x,y,data.number); + core.maps.addInfo(block); + core.maps.addEvent(block,x,y,core.floors[floorId].events[x+","+y]); + core.maps.addChangeFloor(block,x,y,core.floors[floorId].changeFloor[x+","+y]); + if (core.isset(block.event)) { + if (originBlock==null) { + core.status.maps[floorId].blocks.push(block); + } + else { + originBlock.block.id = data.number; + originBlock.block.event = block.event; + } + core.drawMap(floorId); + core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + core.updateStatusBar(); + } + this.doAction(); + break; + } + case "animate": // 显示动画 + if (core.isset(data.loc)) { + if (data.loc == 'hero') { + x=core.getHeroLoc('x'); + y=core.getHeroLoc('y'); + } + else if (data.loc instanceof Array) { + x=data.loc[0]; + y=data.loc[1]; + } + } + core.drawAnimate(data.name, x, y, function () { + core.events.doAction(); + }) + break; case "move": // 移动事件 if (core.isset(data.loc)) { x=data.loc[0]; @@ -354,11 +408,22 @@ events.prototype.doAction = function() { core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); this.doAction(); break; + case "showImage": // 显示图片 + if (core.isset(data.loc) && core.isset(core.material.images.pngs[data.name])) { + core.canvas.animate.drawImage(core.material.images.pngs[data.name], data.loc[0], data.loc[1]); + } + else core.clearMap('animate', 0, 0, 416, 416); + this.doAction(); + break; case "setFg": // 颜色渐变 core.setFg(data.color, data.time, function() { core.events.doAction(); }); break; + case "setWeather": // 更改天气 + core.setWeather(data.name, data.level); + this.doAction(); + break; case "openDoor": // 开一个门,包括暗墙 var floorId=data.floorId || core.status.floorId; var block=core.getBlock(data.loc[0], data.loc[1], floorId); @@ -378,6 +443,7 @@ events.prototype.doAction = function() { case "openShop": // 打开一个全局商店 if (core.status.replay.replaying) { // 正在播放录像,简单将visited置为true core.status.shops[data.id].visited=true; + core.status.event.data.list = []; this.doAction(); } else @@ -470,18 +536,15 @@ events.prototype.doAction = function() { else { var action = core.status.replay.toReplay.shift(), index; if (action.indexOf("choices:")==0 && ((index=parseInt(action.substring(8)))>=0) && index0) { - this.insertAction(todo); + this.insertAction(todo,x,y); } // 如果已有事件正在处理中 if (core.status.event.id == null) { core.continueAutomaticRoute(); } + else { + core.clearContinueAutomaticRoute(); + } if (core.isset(callback)) callback(); } @@ -768,12 +837,15 @@ events.prototype.afterOpenDoor = function(doorId,x,y,callback) { } if (todo.length>0) { - this.insertAction(todo); + this.insertAction(todo,x,y); } if (core.status.event.id == null) { core.continueAutomaticRoute(); } + else { + core.clearContinueAutomaticRoute(); + } if (core.isset(callback)) callback(); } @@ -989,7 +1061,12 @@ events.prototype.clickBook = function(x,y) { } // 返回 if (x>=10 && x<=12 && y==12) { - core.ui.closePanel(); + if (core.status.event.selection==null) + core.ui.closePanel(); + else { + core.status.boxAnimateObjs = []; + core.ui.drawMaps(core.status.event.selection); + } return; } // 怪物信息 @@ -1017,7 +1094,12 @@ events.prototype.keyDownBook = function (keycode) { ////// 怪物手册界面时,放开某个键的操作 ////// events.prototype.keyUpBook = function (keycode) { if (keycode==27 || keycode==88) { - core.ui.closePanel(); + if (core.status.event.selection==null) + core.ui.closePanel(); + else { + core.status.boxAnimateObjs = []; + core.ui.drawMaps(core.status.event.selection); + } return; } if (keycode==13 || keycode==32 || keycode==67) { @@ -1044,9 +1126,10 @@ events.prototype.clickFly = function(x,y) { var index=core.status.hero.flyRange.indexOf(core.status.floorId); var stair=core.status.event.data0) { + core.status.route.push("shop:"+core.status.event.data.id+":"+core.status.event.data.actions.join("")); } + + core.status.event.data.actions = []; + + core.status.boxAnimateObjs = []; + + if (core.status.event.data.fromList) + core.ui.drawQuickShop(); else core.ui.closePanel(); return; @@ -1243,6 +1332,18 @@ events.prototype.clickToolbox = function(x,y) { core.ui.closePanel(); return; } + if (x>=10 && x<=12 && y<=1) { + if (!core.isset(core.status.event.data)) return; + if (!core.flags.enableDeleteItem) { + core.drawTip("不支持删除道具!"); + return; + } + core.removeItem(core.status.event.data); + core.status.event.data = null; + core.ui.drawToolbox(); + return; + } + var index=0; if (y==4||y==5||y==9||y==10) index=parseInt(x/2); else index=6+parseInt(x/2); @@ -1347,6 +1448,19 @@ events.prototype.keyUpToolbox = function (keycode) { this.clickToolboxIndex(core.status.event.selection); return; } + + if (keycode==46) { // delete + if (!core.isset(core.status.event.data)) return; + if (!core.flags.enableDeleteItem) { + core.drawTip("不支持删除道具!"); + return; + } + core.removeItem(core.status.event.data); + core.status.event.data = null; + core.ui.drawToolbox(); + return; + } + } ////// 存读档界面时的点击操作 ////// @@ -1464,9 +1578,7 @@ events.prototype.keyUpSL = function (keycode) { ////// 系统设置界面时的点击操作 ////// events.prototype.clickSwitchs = function (x,y) { if (x<5 || x>7) return; - var choices = [ - "背景音乐", "背景音效", "战斗动画", "怪物显伤", "领域显伤", "下载离线版本", "返回主菜单" - ]; + var choices = core.status.event.ui.choices; var topIndex = 6 - parseInt((choices.length - 1) / 2); if (y>=topIndex && y7) return; - var choices = [ - "系统设置", "快捷商店", "浏览地图", "同步存档", "重新开始", "数据统计", "操作帮助", "关于本塔", "返回游戏" - ]; + var choices = core.status.event.ui.choices; var topIndex = 6 - parseInt((choices.length - 1) / 2); if (y>=topIndex && y0) { - text+="\n当前MAX为"+t.max+",最早由 "+(t.username||"匿名")+" 于"+core.formatDate(new Date(1000*t.timestamp))+"打出。"; - } + t.info.forEach(function(ending) { + if (ending.ending!='') { + text+="\n"+ending.ending+": 已有"+ending.score+"人次通关。"; + } + if (core.isset(ending.max) && ending.max>0) { + text+="\n当前MAX为"+ending.max+",最早由 "+(ending.username||"匿名")+" 于"+core.formatDate(new Date(1000*ending.timestamp))+"打出。"; + } + }) }) core.drawText(text); } @@ -1666,9 +1779,7 @@ events.prototype.keyUpSettings = function (keycode) { core.ui.closePanel(); return; } - var choices = [ - "系统设置", "快捷商店", "浏览地图", "同步存档", "重新开始", "数据统计", "操作帮助", "关于本塔", "返回游戏" - ]; + var choices = core.status.event.ui.choices; if (keycode==13 || keycode==32 || keycode==67) { var topIndex = 6 - parseInt((choices.length - 1) / 2); this.clickSettings(6, topIndex+core.status.event.selection); @@ -1678,20 +1789,21 @@ events.prototype.keyUpSettings = function (keycode) { ////// 同步存档界面时的点击操作 ////// events.prototype.clickSyncSave = function (x,y) { if (x<5 || x>7) return; - var choices = [ - "同步存档到服务器", "从服务器加载存档", "存档至本地文件", "从本地文件读档", "清空所有存档", "返回主菜单" - ]; + var choices = core.status.event.ui.choices; var topIndex = 6 - parseInt((choices.length - 1) / 2); if (y>=topIndex && y=1;i--) { + if (core.getLocalStorage("save"+i, null)==null) + index=i; + else break; + } + core.setLocalStorage("save"+index, data); + core.drawText("同步成功!\n单存档已覆盖至存档"+index); } - core.drawText("读取成功!\n你的本地所有存档均已被覆盖。"); }, function () { }); break; case 4: + core.download(core.firstData.name+"_"+core.formatDate2(new Date())+".h5route", JSON.stringify({ + 'name': core.firstData.name, + 'hard': core.status.hard, + 'route': core.encodeRoute(core.status.route) + })); + break; + case 5: core.status.event.selection=1; core.ui.drawConfirmBox("你确定要清空所有存档吗?", function() { localStorage.clear(); core.drawText("\t[操作成功]你的所有存档已被清空。"); }, function() { - core.status.event.selection=2; - core.ui.drawSyncSave(false); + core.status.event.selection=5; + core.ui.drawSyncSave(); }) break; - case 5: + case 6: core.status.event.selection=3; core.ui.drawSettings(); break; @@ -1773,15 +1913,133 @@ events.prototype.keyUpSyncSave = function (keycode) { core.ui.drawSettings(); return; } - var choices = [ - "同步存档到服务器", "从服务器加载存档", "存档至本地文件", "从本地文件读档", "清空所有存档", "返回主菜单" - ]; + var choices = core.status.event.ui.choices; if (keycode==13 || keycode==32 || keycode==67) { var topIndex = 6 - parseInt((choices.length - 1) / 2); this.clickSyncSave(6, topIndex+core.status.event.selection); } } +////// 同步存档选择界面时的点击操作 ////// +events.prototype.clickSyncSelect = function (x, y) { + if (x<5 || x>7) return; + var choices = core.status.event.ui.choices; + + var topIndex = 6 - parseInt((choices.length - 1) / 2); + if (y>=topIndex && y7) return; + var choices = core.status.event.ui.choices; + + var topIndex = 6 - parseInt((choices.length - 1) / 2); + + var saves=null; + + if (y>=topIndex && y=1;i--) { + saves=core.getLocalStorage("save"+i, null); + if (core.isset(saves)) { + break; + } + } + break; + case 2: + break; + } + } + if (core.isset(saves)) { + var content = { + "name": core.firstData.name, + "version": core.firstData.version, + "data": saves + } + core.download(core.firstData.name+"_"+core.formatDate2(new Date())+".h5save", JSON.stringify(content)); + } + core.status.event.selection=2; + core.ui.drawSyncSave(); +} + +////// 存档下载界面时,按下某个键的操作 ////// +events.prototype.keyDownLocalSaveSelect = function (keycode) { + if (keycode==38) { + core.status.event.selection--; + core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); + } + if (keycode==40) { + core.status.event.selection++; + core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); + } +} + +////// 存档下载界面时,放开某个键的操作 ////// +events.prototype.keyUpLocalSaveSelect = function (keycode) { + if (keycode==27 || keycode==88) { + core.status.event.selection=0; + core.ui.drawSettings(); + return; + } + var choices = core.status.event.ui.choices; + if (keycode==13 || keycode==32 || keycode==67) { + var topIndex = 6 - parseInt((choices.length - 1) / 2); + this.clickLocalSaveSelect(6, topIndex+core.status.event.selection); + } +} + ////// “虚拟键盘”界面时的点击操作 ////// events.prototype.clickKeyBoard = function (x, y) { if (y==3 && x>=1 && x<=11) { @@ -1841,6 +2099,56 @@ events.prototype.clickKeyBoard = function (x, y) { core.ui.closePanel(); } +////// 光标界面时的点击操作 ////// +events.prototype.clickCursor = function (x,y) { + + if (x==core.status.automaticRoute.cursorX && y==core.status.automaticRoute.cursorY) { + core.ui.closePanel(); + core.onclick(x,y,[]); + return; + } + core.status.automaticRoute.cursorX=x; + core.status.automaticRoute.cursorY=y; + core.ui.drawCursor(); +} + +////// 光标界面时,按下某个键的操作 ////// +events.prototype.keyDownCursor = function (keycode) { + if (keycode==37) { // left + core.status.automaticRoute.cursorX--; + core.ui.drawCursor(); + return; + } + if (keycode==38) { // up + core.status.automaticRoute.cursorY--; + core.ui.drawCursor(); + return; + } + if (keycode==39) { // right + core.status.automaticRoute.cursorX++; + core.ui.drawCursor(); + return; + } + if (keycode==40) { // down + core.status.automaticRoute.cursorY++; + core.ui.drawCursor(); + return; + } +} + +////// 光标界面时,放开某个键的操作 ////// +events.prototype.keyUpCursor = function (keycode) { + if (keycode==27 || keycode==88) { + core.ui.closePanel(); + return; + } + if (keycode==13 || keycode==32 || keycode==67 || keycode==69) { + core.ui.closePanel(); + core.onclick(core.status.automaticRoute.cursorX, core.status.automaticRoute.cursorY, []); + return; + } +} + ////// “关于”界面时的点击操作 ////// events.prototype.clickAbout = function () { if (core.isPlaying()) diff --git a/libs/floors/MT0.js b/libs/floors/MT0.js index 624b8e91..602637a4 100644 --- a/libs/floors/MT0.js +++ b/libs/floors/MT0.js @@ -8,8 +8,9 @@ main.floors.MT0 = { "canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) "canUseQuickShop": true, // 该层是否允许使用快捷商店 "defaultGround": "ground", // 默认地面的图块ID(terrains中) - // "png": "bg.png", // 背景图;你可以选择一张png图片来作为背景素材。详细用法请参见文档“自定义素材”中的说明。 + "png": [], // 该层默认显示的所有图片;详细用法请查看文档“自定义素材”中的说明。 // "color": [0,0,0,0.3], // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。 + // "weather": ["snow",5], // 该层的默认天气。本项可忽略表示晴天,如果写则第一项为"rain"或"snow"代表雨雪,第二项为1-10之间的数代表强度。 // "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。 "map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成 @@ -31,6 +32,11 @@ main.floors.MT0 = { }, "afterOpenDoor": { // 开完门后可能触发的事件列表 - } + }, + "cannotMove": { // 每个图块不可通行的方向 + // 可以在这里定义每个点不能前往哪个方向,例如悬崖边不能跳下去 + // "x,y": ["up", "left"], // (x,y)点不能往上和左走 + + }, } diff --git a/libs/floors/sample0.js b/libs/floors/sample0.js index e4b65511..5f0fa6d7 100644 --- a/libs/floors/sample0.js +++ b/libs/floors/sample0.js @@ -8,8 +8,9 @@ main.floors.sample0 = { "canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) "canUseQuickShop": true, // 该层是否允许使用快捷商店 "defaultGround": "ground", // 默认地面的图块ID(terrains中) - // "png": "bg.png", // 背景图;你可以选择一张png图片来作为背景素材。详细用法请参见文档“自定义素材”中的说明。 + "png": [], // 该层默认显示的所有图片;详细用法请查看文档“自定义素材”中的说明。 // "color": [0,0,0,0.3] // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。 + // "weather": ["snow",5], // 该层的默认天气。本项可忽略表示晴天,如果写则第一项为"rain"或"snow"代表雨雪,第二项为1-10之间的数代表强度。 "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。 "map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成 [0, 0, 220, 0, 0, 20, 87, 3, 65, 64, 44, 43, 42], @@ -28,17 +29,16 @@ main.floors.sample0 = { ], "firstArrive": [ // 第一次到该楼层触发的事件 "\t[样板提示]首次到达某层可以触发 firstArrive 事件,该事件可类似于RMXP中的“自动执行脚本”。\n\n本事件支持一切的事件类型,常常用来触发对话,例如:", - "\t[hero]我是谁?我从哪来?我又要到哪去?", + "\t[hero]\b[up,hero]我是谁?我从哪来?我又要到哪去?", "\t[仙子,fairy]你问我...?我也不知道啊...", "本层主要对道具、门、怪物等进行介绍,有关事件的各种信息在下一层会有更为详细的说明。", ], "events": { // 该楼的所有可能事件列表 - "10,9": [ // 守着道具的老人 "\t[老人,man]这些是本样板支持的所有的道具。\n\n道具分为三类:items, constants, tools。\nitems 为即捡即用类道具,例如宝石、血瓶、剑盾等。\nconstants 为永久道具,例如怪物手册、楼层传送器、幸运金币等。\ntools 为消耗类道具,例如破墙镐、炸弹、中心对称飞行器等。\n\n后两类道具在工具栏中可以看到并使用。", - "\t[老人,man]有关道具效果,定义在items.js中。\n目前大多数道具已有默认行为,如有自定义的需求则需在items.js中修改代码。", + "\t[老人,man]\b[up]有关道具效果,定义在items.js中。\n目前大多数道具已有默认行为,如有自定义的需求则需在items.js中修改代码。", "\t[老人,man]constants 和 tools 各最多只允许12种,多了会导致图标溢出。", - "\t[老人,man]拾取道具结束后可触发 afterGetItem 事件。\n\n有关事件的各种信息在下一层会有更为详细的说明。", + "\t[老人,man]\b[up]拾取道具结束后可触发 afterGetItem 事件。\n\n有关事件的各种信息在下一层会有更为详细的说明。", {"type": "hide", "time": 500} // 消失 ], "10,11": [ // 守着门的老人 @@ -76,6 +76,7 @@ main.floors.sample0 = { }, }, "changeFloor": { // 楼层转换事件;该事件不能和上面的events有冲突(同位置点),否则会被覆盖 + "7,9": {"floorId": "sample1", "stair": "downFloor"}, "6,0": {"floorId": "sample1", "stair": "downFloor"}, // 目标点:sample1层的下楼梯位置 "0,11": {"floorId": "sample0", "loc": [0,12]}, // 目标点:sample0层的x=0,y=12位置 "0,12": {"floorId": "sample0", "stair": "upFloor"}, // 注意,目标层有多个楼梯的话,写stair可能会导致到达位置不确定。这时候推荐写loc指明目标点位置。 @@ -83,11 +84,11 @@ main.floors.sample0 = { "2,12": {"floorId": "sample0", "loc": [2,12]}, "3,12": {"floorId": "sample0", "loc": [6,1], "direction": "up"}, // 切换楼层后勇士面对上方 "4,12": {"floorId": "sample0", "loc": [0,9], "direction": "left", "time": 1000}, // 切换楼层后勇士面对左边,切换动画1000ms - "5,12": {"floorId": "sample0", "loc": [6,10], "time": 0}, // time=0表示无切换时间 + "5,12": {"floorId": "sample0", "loc": [6,10], "time": 0, "portalWithoutTrigger": false}, // time=0表示无切换时间 "6,12": {"floorId": "sample0", "loc": [10,10], "direction": "left", "time": 1000}, }, "afterBattle": { // 战斗后可能触发的事件列表 - "2,6": ["\t[ghostSkeleton]不可能,你怎么可能打败我!\n(一个打败怪物触发的事件)"] + "2,6": ["\t[ghostSkeleton]不可能,你怎么可能打败我!\n(一个打败怪物触发的事件)"], }, "afterGetItem": { // 获得道具后可能触发的事件列表 "11,8": ["由于状态栏放不下,绿钥匙和铁门钥匙均视为tools,放入工具栏中。\n碰到绿门和铁门仍然会自动使用开门。"], @@ -108,7 +109,12 @@ main.floors.sample0 = { }, "afterOpenDoor": { // 开完门后可能触发的事件列表 "11,12": ["你开了一个绿门,触发了一个afterOpenDoor事件"] - } + }, + "cannotMove": { // 每个图块不可通行的方向 + // 可以在这里定义每个点不能前往哪个方向,例如悬崖边不能跳下去 + // "x,y": ["up", "left"], // (x,y)点不能往上和左走 + + }, } diff --git a/libs/floors/sample1.js b/libs/floors/sample1.js index 9952e4a6..4fbc0fd7 100644 --- a/libs/floors/sample1.js +++ b/libs/floors/sample1.js @@ -8,8 +8,9 @@ main.floors.sample1 = { "canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) "canUseQuickShop": true, // 该层是否允许使用快捷商店 "defaultGround": "grass", // 默认地面的图块ID(terrains中) - "png": "bg.png", // 背景图;你可以选择一张png图片来作为背景素材。详细用法请参见文档“自定义素材”中的说明。 + "png": [[0,0,"bg"]], // // 该层默认显示的所有图片;详细用法请查看文档“自定义素材”中的说明。 // "color": [0,0,0,0.3] // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。 + "weather": ["snow",6], // 该层的默认天气。本项可忽略表示晴天,如果写则第一项为"rain"或"snow"代表雨雪,第二项为1-10之间的数代表强度。 // "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。 "map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成 [7, 131, 8, 152, 9, 130, 10, 152, 166, 165, 132, 165, 166], @@ -34,8 +35,8 @@ main.floors.sample1 = { "4,10": [ // 走到中间时的提示 "\t[样板提示]本层楼将会对各类事件进行介绍。", "左边是一个仿50层的陷阱做法,上方是商店、快捷商店的使用方法,右上是一个典型的杀怪开门的例子,右下是各类可能的NPC事件。", - "本样板目前支持的事件列表大致有:\ntext: 显示一段文字(比如你现在正在看到的)\ntip: 左上角显示提示\nshow: 使一个事件有效(可见、可被交互)\nhide: 使一个事件失效(不可见、不可被交互)\ntrigger: 触发另一个地点的事件\nbattle: 强制和某怪物战斗\nopenDoor: 无需钥匙开门(例如机关门、暗墙)", - "openShop: 打开一个全局商店\ndisableShop: 禁用一个全局商店\nchangeFloor: 传送勇士到某层某位置\nchangePos: 传送勇士到当层某位置;转向\nsetFg: 更改画面色调\nmove: 移动事件效果\nmoveHero: 移动勇士效果\nplayBgm: 播放某个背景音乐\npauseBgm: 暂停背景音乐\nresumeBgm: 恢复背景音乐的播放\nplaySound: 播放某个音频", + "本样板目前支持的事件列表大致有:\ntext: 显示一段文字(比如你现在正在看到的)\ntip: 左上角显示提示\nshow: 使一个事件有效(可见、可被交互)\nhide: 使一个事件失效(不可见、不可被交互)\ntrigger: 触发另一个地点的事件\nanimate: 显示动画\nbattle: 强制和某怪物战斗\nopenDoor: 无需钥匙开门(例如机关门、暗墙)", + "openShop: 打开一个全局商店\ndisableShop: 禁用一个全局商店\nchangeFloor: 传送勇士到某层某位置\nchangePos: 传送勇士到当层某位置;转向\nshowImage: 显示图片\nsetFg: 更改画面色调\nsetWeather: 更改天气\nmove: 移动事件效果\nmoveHero: 移动勇士效果\nplayBgm: 播放某个背景音乐\npauseBgm: 暂停背景音乐\nresumeBgm: 恢复背景音乐的播放\nplaySound: 播放某个音频", "if: 条件判断\nchoices: 提供选项\nsetValue: 设置勇士属性道具,或某个变量/flag\nupdate: 更新状态栏和地图显伤\nwin: 获得胜利(游戏通关)\nlose: 游戏失败\nsleep: 等待多少毫秒\nexit: 立刻结束当前事件\nrevisit: 立刻结束事件并重新触发\nfunction: 自定义JS脚本\n\n更多支持的事件还在编写中,欢迎您宝贵的意见。", "有关各事件的样例,可参见本层一些NPC的写法。\n所有事件样例本层都有介绍。\n\n一个自定义事件处理完后,需要调用{\"type\": \"hide\"}该事件才不会再次出现。", {"type": "hide"} @@ -267,7 +268,7 @@ main.floors.sample1 = { value=parseInt(action.substring(6)); } else { - core.status.replay.replaying=false; + core.stopReplay(); core.drawTip("录像文件出错"); return; } @@ -320,6 +321,11 @@ main.floors.sample1 = { }, "afterOpenDoor": { // 开完门后可能触发的事件列表 - } + }, + "cannotMove": { // 每个图块不可通行的方向 + // 可以在这里定义每个点不能前往哪个方向,例如悬崖边不能跳下去 + // "x,y": ["up", "left"], // (x,y)点不能往上和左走 + + }, } diff --git a/libs/floors/sample2.js b/libs/floors/sample2.js index 5e440aa4..d57b5b2f 100644 --- a/libs/floors/sample2.js +++ b/libs/floors/sample2.js @@ -8,8 +8,9 @@ main.floors.sample2 = { "canFlyTo": false, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) "canUseQuickShop": true, // 该层是否允许使用快捷商店 "defaultGround": "snowGround", // 默认地面的图块ID(terrains中) - // "png": "bg.png", // 背景图;你可以选择一张png图片来作为背景素材。详细用法请参见文档“自定义素材”中的说明。 + "png": [], // // 该层默认显示的所有图片;详细用法请查看文档“自定义素材”中的说明。 "color": [255,0,0,0.3], // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。 + "weather": ["rain",10], // 该层的默认天气。本项可忽略表示晴天,如果写则第一项为"rain"或"snow"代表雨雪,第二项为1-10之间的数代表强度。 "bgm": "qianjin.mid", // 到达该层后默认播放的BGM。本项可忽略。 "map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成 [5, 5, 5, 5, 5, 5, 87, 5, 5, 5, 5, 5, 5], @@ -27,8 +28,7 @@ main.floors.sample2 = { [5, 5, 5, 5, 5, 5, 88, 5, 5, 5, 5, 5, 5], ], "firstArrive": [ // 第一次到该楼层触发的事件 - "\t[实战!]本楼将尝试复刻《宿命的旋律》40F剧情。", - "由于暂不支持一些动画效果,例如雷电、振动、天气渲染等等,因此做出来的效果远远比不上原版。\n\n不过作为抛砖引玉,还是能展示一下H5的能力。\n(开音效食用更加)" + "\t[实战!]本楼将尝试复刻《宿命的旋律》40F剧情。" ], "events": { // 该楼的所有可能事件列表 @@ -181,6 +181,7 @@ main.floors.sample2 = { {"type": "show", "loc": [8,3], "time": 500}, // 依次显示四个角的法师 {"type": "sleep", "time": 500}, "\t[blackMagician]感受绝望吧!冥顽不化的蠢货!", + /* {"type": "hide", "loc": [4,3], "time": 150}, // 由于没有动画效果,暂时使用“闪一下”表示 {"type": "show", "loc": [4,3], "time": 150}, {"type": "hide", "loc": [4,6], "time": 150}, // 由于没有动画效果,暂时使用“闪一下”表示 @@ -189,8 +190,14 @@ main.floors.sample2 = { {"type": "show", "loc": [8,6], "time": 150}, {"type": "hide", "loc": [8,3], "time": 150}, // 由于没有动画效果,暂时使用“闪一下”表示 {"type": "show", "loc": [8,3], "time": 150}, + */ + {"type": "animate", "name": "yongchang", "loc": [4,3]}, + {"type": "animate", "name": "yongchang", "loc": [4,6]}, + {"type": "animate", "name": "yongchang", "loc": [8,6]}, + {"type": "animate", "name": "yongchang", "loc": [8,3]}, {"type": "sleep", "time": 200}, {"type": "playSound", "name": "attack.ogg"}, // 播放攻击音效 + {"type": "animate", "name": "thunder", "loc": "hero"}, {"type": "sleep", "time": 200}, "\t[hero]唔……!!(吐血)", {"type": "playSound", "name": "item.ogg"}, @@ -266,6 +273,7 @@ main.floors.sample2 = { "\t[小妖精,fairy]别小瞧咱!咱好歹也是妖精族里实力数一数二的存在!", {"type": "playSound", "name": "item.ogg"}, "\t[blackMagician]只会耍嘴皮子的恼人苍蝇!我倒要看看一块焦炭会不会说话!\n——招雷弹!!", + /* {"type": "hide", "loc": [4,3], "time": 150}, // 由于没有动画效果,暂时使用“闪一下”表示 {"type": "show", "loc": [4,3], "time": 150}, {"type": "hide", "loc": [4,6], "time": 150}, // 由于没有动画效果,暂时使用“闪一下”表示 @@ -274,9 +282,17 @@ main.floors.sample2 = { {"type": "show", "loc": [8,6], "time": 150}, {"type": "hide", "loc": [8,3], "time": 150}, // 由于没有动画效果,暂时使用“闪一下”表示 {"type": "show", "loc": [8,3], "time": 150}, + */ + {"type": "animate", "name": "yongchang", "loc": [4,3]}, + {"type": "animate", "name": "yongchang", "loc": [4,6]}, + {"type": "animate", "name": "yongchang", "loc": [8,6]}, + {"type": "animate", "name": "yongchang", "loc": [8,3]}, {"type": "playSound", "name": "attack.ogg"}, // 播放攻击音效 + /* {"type": "hide", "loc": [6,6], "time": 150}, // 妖精也闪一下表示收到了伤害 {"type": "show", "loc": [6,6], "time": 150}, // 妖精也闪一下表示收到了伤害 + */ + {"type": "animate", "name": "thunder", "loc": [6,6]}, {"type": "sleep", "time": 500}, // 等待500毫秒 "\t[小妖精,fairy]切,这点伤痛跟他刚才经历的身心地狱相比根本就不算什么。", {"type": "playSound", "name": "item.ogg"}, @@ -385,6 +401,11 @@ main.floors.sample2 = { }, "afterOpenDoor": { // 开完门后可能触发的事件列表 - } + }, + "cannotMove": { // 每个图块不可通行的方向 + // 可以在这里定义每个点不能前往哪个方向,例如悬崖边不能跳下去 + // "x,y": ["up", "left"], // (x,y)点不能往上和左走 + + }, } diff --git a/libs/maps.js b/libs/maps.js index dce6c382..b301d9d4 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -14,27 +14,7 @@ maps.prototype.loadFloor = function (floorId, map) { for (var i = 0; i < 13; i++) { for (var j = 0; j < 13; j++) { var block = this.getBlock(j, i, map[i][j]); - if (core.isset(block.event)) { - if (block.event.cls == 'enemys' && block.event.trigger==undefined) { - block.event.trigger = 'battle'; - } - if (block.event.cls == 'items' && block.event.trigger==undefined) { - block.event.trigger = 'getItem'; - } - if (block.event.noPass == undefined) { - if (block.event.cls=='enemys' || block.event.cls=='terrains' || block.event.cls=='npcs') { - block.event.noPass = true; - } - } - if (block.event.animate == undefined) { - if (block.event.cls=='enemys' || block.event.cls=='npcs') { - block.event.animate = 2; - } - if (block.event.cls == 'animates') { - block.event.animate = 4; - } - } - } + this.addInfo(block); this.addEvent(block,j,i,floor.events[j+","+i]) this.addChangeFloor(block,j,i,floor.changeFloor[j+","+i]); if (core.isset(block.event)) blocks.push(block); @@ -257,6 +237,31 @@ maps.prototype.getBlock = function (x, y, id) { return tmp; } +////// 添加一些信息到block上 ////// +maps.prototype.addInfo = function (block) { + if (core.isset(block.event)) { + if (block.event.cls == 'enemys' && block.event.trigger==undefined) { + block.event.trigger = 'battle'; + } + if (block.event.cls == 'items' && block.event.trigger==undefined) { + block.event.trigger = 'getItem'; + } + if (block.event.noPass == undefined) { + if (block.event.cls=='enemys' || block.event.cls=='terrains' || block.event.cls=='npcs') { + block.event.noPass = true; + } + } + if (block.event.animate == undefined) { + if (block.event.cls=='enemys' || block.event.cls=='npcs') { + block.event.animate = 2; + } + if (block.event.cls == 'animates') { + block.event.animate = 4; + } + } + } +} + ////// 向该楼层添加剧本的自定义事件 ////// maps.prototype.addEvent = function (block, x, y, event) { if (!core.isset(event)) return; diff --git a/libs/thirdparty/mid.min.js b/libs/thirdparty/mid.min.js new file mode 100644 index 00000000..62466cc1 --- /dev/null +++ b/libs/thirdparty/mid.min.js @@ -0,0 +1 @@ +var sampleRate=44100;function AudioPlayer(b,f,a){sampleRate=b.sampleRate;var c=2;var g=4096*4;var d=b.createScriptProcessor(g,0,c);d.onaudioprocess=function(h){e(h)};function e(m){if(f.finished){if(a){f.reset();f.finished=false}else{d.disconnect();return}}var l=m.outputBuffer.getChannelData(0);var k=m.outputBuffer.getChannelData(1);var h=f.generate(g);for(var j=0;j>4;u.channel=t&15;u.type="channel";switch(i){case 8:u.subtype="noteOff";u.noteNumber=v;u.velocity=w.readInt8();return u;case 9:u.noteNumber=v;u.velocity=w.readInt8();if(u.velocity==0){u.subtype="noteOff"}else{u.subtype="noteOn"}return u;case 10:u.subtype="noteAftertouch";u.noteNumber=v;u.amount=w.readInt8();return u;case 11:u.subtype="controller";u.controllerType=v;u.value=w.readInt8();return u;case 12:u.subtype="programChange";u.programNumber=v;return u;case 13:u.subtype="channelAftertouch";u.amount=v;return u;case 14:u.subtype="pitchBend";u.value=v+(w.readInt8()<<7);return u;default:throw"Unrecognised MIDI event type: "+i}}}stream=Stream(g);var k=a(stream);if(k.id!="MThd"||k.length!=6){throw"Bad .mid file - header not found"}var f=Stream(k.data);var d=f.readInt16();var h=f.readInt16();var p=f.readInt16();if(p&32768){throw"Expressing time division in SMTPE frames is not supported yet"}else{ticksPerBeat=p}var j={"formatType":d,"trackCount":h,"ticksPerBeat":ticksPerBeat};var m=[];for(var e=0;e0){c.generateIntoBuffer(r,t,p);p+=r*2;s-=r;e-=r}i();g()}else{if(s>0){c.generateIntoBuffer(s,t,p);e-=s}break}}return t}function i(){var p=m.event;switch(p.type){case"meta":switch(p.subtype){case"setTempo":o=60000000/p.microsecondsPerBeat}break;case"channel":switch(p.subtype){case"noteOn":d[p.channel].noteOn(p.noteNumber,p.velocity);break;case"noteOff":d[p.channel].noteOff(p.noteNumber,p.velocity);break;case"programChange":d[p.channel].setProgram(p.programNumber);break}break}}function f(){for(var p=0;p127){i-=256}b+=1;return i}function c(){return b>=g.length}function d(){var j=0;while(true){var i=h();if(i&128){j+=(i&127);j<<=7}else{return j+i}}}return{"eof":c,"read":e,"readInt32":f,"readInt16":a,"readInt8":h,"readVarInt":d}}function SineGenerator(c){var a={"alive":true};var d=sampleRate/c;var b=0;a.generate=function(g,i,h){for(;h;h--){var f=b/d;var e=Math.sin(f*2*Math.PI);g[i++]+=e;g[i++]+=e;b++}};return a}function SquareGenerator(d,a){var b={"alive":true};var e=sampleRate/d;var c=0;b.generate=function(g,i,h){for(;h;h--){var f=((c/e)%1>a?1:-1);g[i++]+=f;g[i++]+=f;c++}};return b}function ADSRGenerator(c,i,k,h,l,j){var n={"alive":true};var f=sampleRate*h;var g=sampleRate*(h+l);var b=(i-k)/(g-f);var a=null;var e=null;var d=k/(sampleRate*j);var m=0;n.noteOff=function(){if(n.released){return}a=m;n.released=true;e=a+sampleRate*j};n.generate=function(p,t,s){if(!n.alive){return}var o=new Array(s*2);for(var r=0;r=0;g--){c[g].generate(f,j,h);if(!c[g].alive){c.splice(g,1)}}}return{"sampleRate":b,"addGenerator":e,"generate":a,"generateIntoBuffer":d}}; \ No newline at end of file diff --git a/libs/ui.js b/libs/ui.js index 1b8217af..5ac798bc 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(); @@ -30,10 +29,11 @@ ui.prototype.drawTextBox = function(content) { // 获得name, image, icon var id=null, name=null, image=null, icon=null; - if (content.indexOf("\t[")==0) { + if (content.indexOf("\t[")==0 || content.indexOf("\\t[")==0) { var index = content.indexOf("]"); if (index>=0) { var str=content.substring(2, index); + if (content.indexOf("\\t[")==0) str=content.substring(3, index); content=content.substring(index+1); var ss=str.split(","); if (ss.length==1) { @@ -64,10 +64,55 @@ ui.prototype.drawTextBox = function(content) { } } + // 获得位置信息 + + var textAttribute = core.status.textAttribute || core.initStatus.textAttribute; + + var position = textAttribute.position, px=null, py=null, ydelta=0; + if (content.indexOf("\b[")==0 || content.indexOf("\\b[")==0) { + var index = content.indexOf("]"); + if (index>=0) { + var str = content.substring(2, index); + if (content.indexOf("\\b[")==0) str = content.substring(3, index); + content = content.substring(index + 1); + + var ss=str.split(","); + + if (ss[0]=='up' || ss[0]=='center' || ss[0]=='down') { + position=ss[0]; + if (core.status.event.id=='action') { + px = core.status.event.data.x; + py = core.status.event.data.y; + } + + if (ss.length>=2) { + if (ss[1]=='hero') { + px=core.getHeroLoc('x'); + py=core.getHeroLoc('y'); + ydelta = core.material.icons.hero.height-32; + } + else if (ss.length>=3) { + px=parseInt(ss[1]); + py=parseInt(ss[2]); + } + } + } + /* + if (ss.length==3) { + px=parseInt(ss[1]); + py=parseInt(ss[2]); + } + */ + + } + } + content = core.replaceText(content); var background = core.canvas.ui.createPattern(core.material.ground, "repeat"); + core.status.boxAnimateObjs = []; core.clearMap('ui', 0, 0, 416, 416); + // var contents = content.split('\n'); // var contents = core.splitLines('ui', content, ); var left=10, right=416-2*left; @@ -77,16 +122,74 @@ ui.prototype.drawTextBox = function(content) { var validWidth = right-(content_left-left)-13; var contents = core.splitLines("ui", content, validWidth, '16px Verdana'); - var height = 416 - 10 - Math.min(416-24*(contents.length+1)-65, 250); - var top = (416-height)/2, bottom = height; + var height = 20 + 21*(contents.length+1) + (id=='hero'?core.material.icons.hero.height-10:core.isset(name)?32-10:0); + + + var xoffset = 6, yoffset = 22; + + var top; + if (position=='center') { + top = (416 - height) / 2; + } + else if (position=='up') { + if (px==null || py==null) { + top = 5; + } + else { + top = 32 * py - height - ydelta - yoffset; + } + } + else if (position=='down') { + if (px==null || py==null) { + top = 416 - height - 5; + } + else { + top = 32 * py + 32 + yoffset; + } + } // var left = 97, top = 64, right = 416 - 2 * left, bottom = 416 - 2 * top; - core.setAlpha('ui', 0.85); - 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.status.boxAnimateObjs = []; - core.setBoxAnimate(); + //core.setAlpha('ui', 0.85); + core.setAlpha('ui', textAttribute.background[3]); + core.setFillStyle('ui', core.arrayToRGB(textAttribute.background)); + core.setStrokeStyle('ui', '#FFFFFF'); + + + core.fillRect('ui', left, top, right, height); + core.strokeRect('ui', left - 1, top - 1, right + 1, height + 1, '#FFFFFF', 2); + + var xoffset = 6; + + // draw triangle + if (position=='up' && core.isset(px) && core.isset(py)) { + core.canvas.ui.clearRect(32*px+xoffset, top+height-1, 32-2*xoffset, 2); + core.canvas.ui.beginPath(); + core.canvas.ui.moveTo(32*px+xoffset-1, top+height-1); + core.canvas.ui.lineTo(32*px+16, top+height+yoffset-2); + core.canvas.ui.lineTo(32*px+32-xoffset+1, top+height-1); + core.canvas.ui.moveTo(32*px+xoffset-1, top+height-1); + core.canvas.ui.closePath(); + core.canvas.ui.fill(); + // core.canvas.ui.stroke(); + // core.drawLine('ui', 32*px+4+1, top+height+1, 32*px + 28-1, top+height+1, core.arrayToRGB(textAttribute.background), 3); + core.drawLine('ui', 32*px+xoffset, top+height, 32*px+16, top+height+yoffset-2); + core.drawLine('ui', 32*px+32-xoffset, top+height, 32*px+16, top+height+yoffset-2); + } + if (position=='down' && core.isset(px) && core.isset(py)) { + core.canvas.ui.clearRect(32*px+xoffset, top-2, 32-2*xoffset, 3); + core.canvas.ui.beginPath(); + core.canvas.ui.moveTo(32*px+xoffset-1, top+1); + core.canvas.ui.lineTo(32*px+16-1, top-yoffset+2); + core.canvas.ui.lineTo(32*px+32-xoffset-1, top+1); + core.canvas.ui.moveTo(32*px+xoffset-1, top+1); + core.canvas.ui.closePath(); + core.canvas.ui.fill(); + // core.canvas.ui.stroke(); + // core.drawLine('ui', 32*px+4+1, top+height+1, 32*px + 28-1, top+height+1, core.arrayToRGB(textAttribute.background), 3); + core.drawLine('ui', 32*px+xoffset, top, 32*px+16, top-yoffset+2); + core.drawLine('ui', 32*px+32-xoffset, top, 32*px+16, top-yoffset+2); + } + // 名称 core.canvas.ui.textAlign = "left"; @@ -95,36 +198,42 @@ ui.prototype.drawTextBox = function(content) { if (core.isset(id)) { content_top = top+57; + core.setAlpha('ui', textAttribute.title[3]); + core.setFillStyle('ui', core.arrayToRGB(textAttribute.title)); + core.setStrokeStyle('ui', core.arrayToRGB(textAttribute.title)); if (id == 'hero') { var heroHeight=core.material.icons.hero.height; - core.strokeRect('ui', left + 15 - 1, top + 40 - 1, 34, heroHeight+2, '#FFD700', 2); - core.fillText('ui', core.status.hero.name, content_left, top + 30, '#FFD700', 'bold 22px Verdana'); + core.strokeRect('ui', left + 15 - 1, top + 40 - 1, 34, heroHeight+2, null, 2); + core.fillText('ui', core.status.hero.name, content_left, top + 30, null, 'bold 22px Verdana'); core.clearMap('ui', left + 15, top + 40, 32, heroHeight); core.fillRect('ui', left + 15, top + 40, 32, heroHeight, background); var heroIcon = core.material.icons.hero['down']; core.canvas.ui.drawImage(core.material.images.hero, heroIcon.stop * 32, heroIcon.loc * heroHeight, 32, heroHeight, left+15, top+40, 32, heroHeight); } else { - core.fillText('ui', name, content_left, top + 30, '#FFD700', 'bold 22px Verdana'); + core.fillText('ui', name, content_left, top + 30, null, 'bold 22px Verdana'); if (core.isset(icon)) { - core.strokeRect('ui', left + 15 - 1, top + 40 - 1, 34, 34, '#FFD700', 2); + core.strokeRect('ui', left + 15 - 1, top + 40 - 1, 34, 34, null, 2); core.status.boxAnimateObjs = []; core.status.boxAnimateObjs.push({ 'bgx': left + 15, 'bgy': top + 40, 'bgsize': 32, 'image': image, 'x': left + 15, 'y': top + 40, 'icon': icon }); - core.setBoxAnimate(); + core.drawBoxAnimate(); } } } + core.setAlpha('ui', textAttribute.text[3]); + core.setFillStyle('ui', core.arrayToRGB(textAttribute.text)); + for (var i=0;i', 270, top+height-13, '#CCCCCC', '13px Verdana'); + // core.fillText('ui', '<点击任意位置继续>', 270, top+height-13, '#CCCCCC', '13px Verdana'); } ////// 绘制一个选项界面 ////// @@ -237,7 +346,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(); } } } @@ -369,6 +478,22 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) { 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; + var initDamage = 0; // 战前伤害 + + // 吸血 + if (core.enemys.hasSpecial(mon_special, 11)) { + var vampireDamage = hero_hp * monster.value; + + // 如果有神圣盾免疫吸血等可以在这里写 + + vampireDamage = parseInt(vampireDamage); + // 加到自身 + if (monster.add) // 如果加到自身 + mon_hp += vampireDamage; + + initDamage += vampireDamage; + } + hero_hp -= core.enemys.getExtraDamage(monster); if (core.enemys.hasSpecial(mon_special, 10)) { // 模仿 @@ -388,16 +513,9 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) { if (core.enemys.hasSpecial(mon_special, 5)) turns=4; if (core.enemys.hasSpecial(mon_special, 6)) turns=1+(monster.n||4); - // 初始伤害 - 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, 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; @@ -433,7 +551,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; @@ -464,7 +581,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; @@ -627,7 +744,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); @@ -674,11 +790,27 @@ ui.prototype.drawSyncSave = function () { core.status.event.id = 'syncSave'; this.drawChoices(null, [ - "同步存档到服务器", "从服务器加载存档", "存档至本地文件", "从本地文件读档", "清空所有存档", "返回主菜单" + "同步存档到服务器", "从服务器加载存档", "存档至本地文件", "从本地文件读档", "下载当前录像", "清空本地存档", "返回主菜单" ]); } +////// 绘制存档同步选择页面 ////// +ui.prototype.drawSyncSelect = function () { + core.status.event.id = 'syncSelect'; + this.drawChoices(null, [ + "同步本地所有存档", "只同步最新单存档", "返回上级菜单" + ]); +} + +////// 绘制单存档界面 ////// +ui.prototype.drawLocalSaveSelect = function () { + core.status.event.id = 'localSaveSelect'; + this.drawChoices(null, [ + "下载所有存档", "只下载最新单存档", "返回上级菜单" + ]); +} + ////// 绘制分页 ////// ui.prototype.drawPagination = function (page, totalPage) { @@ -701,10 +833,34 @@ ui.prototype.drawPagination = function (page, totalPage) { } +////// 绘制键盘光标 ////// +ui.prototype.drawCursor = function () { + + if (!core.isset(core.status.automaticRoute.cursorX)) + core.status.automaticRoute.cursorX=core.getHeroLoc('x'); + if (core.status.automaticRoute.cursorX<0) core.status.automaticRoute.cursorX=0; + if (core.status.automaticRoute.cursorX>12) core.status.automaticRoute.cursorX=12; + if (!core.isset(core.status.automaticRoute.cursorY)) + core.status.automaticRoute.cursorY=core.getHeroLoc('y'); + if (core.status.automaticRoute.cursorY<0) core.status.automaticRoute.cursorY=0; + if (core.status.automaticRoute.cursorY>12) core.status.automaticRoute.cursorY=12; + + core.status.event.id = 'cursor'; + core.lockControl(); + + core.clearMap('ui', 0, 0, 416, 416); + core.setAlpha('ui', 1); + + var width = 4; + core.strokeRect('ui', 32*core.status.automaticRoute.cursorX+width/2, 32*core.status.automaticRoute.cursorY+width/2, + 32-width, 32-width, '#FFD700', width); + +} + ////// 绘制怪物手册 ////// ui.prototype.drawBook = function (index) { - var enemys = core.enemys.getCurrentEnemys(); + var enemys = core.enemys.getCurrentEnemys(core.floorIds[core.status.event.selection]); var background = core.canvas.ui.createPattern(core.material.ground, "repeat"); clearInterval(core.interval.tipAnimate); @@ -814,13 +970,13 @@ ui.prototype.drawBook = function (index) { } } - core.setBoxAnimate(); + core.drawBoxAnimate(); this.drawPagination(page, totalPage); } ////// 绘制怪物属性的详细信息 ////// ui.prototype.drawBookDetail = function (index) { - var enemys = core.enemys.getCurrentEnemys(); + var enemys = core.enemys.getCurrentEnemys(core.floorIds[core.status.event.selection]); if (enemys.length==0) return; if (index<0) index=0; if (index>=enemys.length) index=enemys.length-1; @@ -1051,6 +1207,7 @@ ui.prototype.drawToolbox = function(index) { // 退出 core.canvas.ui.textAlign = 'center'; + core.fillText('ui', '删除道具', 370, 32,'#DDDDDD', 'bold 15px Verdana'); core.fillText('ui', '返回游戏', 370, 403,'#DDDDDD', 'bold 15px Verdana'); } @@ -1121,9 +1278,31 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroL if (core.isset(core.floors[floorId].png)) { var png = core.floors[floorId].png; + /* if (core.isset(core.material.images.pngs[png])) { core.canvas.ui.drawImage(core.material.images.pngs[png], x, y, size, size); } + */ + + var ratio = size/416; + + if (typeof png == 'string') { + if (core.isset(core.material.images.pngs[png])) { + core.canvas.ui.drawImage(core.material.images.pngs[png], x, y, size, size); + } + } + else if (png instanceof Array) { + png.forEach(function (t) { + if (t.length!=3) return; + var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2]; + if (core.isset(dx) && core.isset(dy) && core.isset(core.material.images.pngs[p])) { + dx*=32; dy*=32; + var image = core.material.images.pngs[p]; + core.canvas.ui.drawImage(image, x+dx*ratio, y+dy*ratio, Math.min(size-dx*ratio, ratio*image.width), Math.min(size-dy*ratio, ratio*image.height)); + } + }) + } + } var mapArray = core.maps.getMapArray(blocks); @@ -1212,9 +1391,10 @@ ui.prototype.drawAbout = function() { // 名称 core.canvas.ui.textAlign = "left"; core.fillText('ui', "HTML5 魔塔样板", text_start, top+35, "#FFD700", "bold 22px Verdana"); - core.fillText('ui', "作者: 艾之葵", text_start, top + 80, "#FFFFFF", "bold 17px Verdana"); - core.fillText('ui', 'HTML5魔塔交流群:539113091', text_start, top+112); - // TODO: 写自己的“关于”页面 + core.fillText('ui', "版本: "+core.firstData.version, text_start, top + 80, "#FFFFFF", "bold 17px Verdana"); + core.fillText('ui', "作者: 艾之葵", text_start, top + 112); + core.fillText('ui', 'HTML5魔塔交流群:539113091', text_start, top+112+32); + // TODO: 写自己的“关于”页面,每次增加32像素即可 } ////// 绘制帮助页面 ////// @@ -1229,6 +1409,7 @@ ui.prototype.drawHelp = function () { "[K] 打开/关闭快捷商店选择列表\n" + "[T] 打开/关闭工具栏\n" + "[ESC] 打开/关闭系统菜单\n" + + "[E] 显示光标\n" + "[H] 打开帮助页面\n"+ "[R] 回放\n"+ "[SPACE] 轻按(仅在轻按开关打开时有效)\n" + diff --git a/main.js b/main.js index 283318e6..bae1a274 100644 --- a/main.js +++ b/main.js @@ -2,7 +2,7 @@ function main() { //------------------------ 用户修改内容 ------------------------// - this.version = "1.3.2"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 + this.version = "1.4.1"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 this.useCompress = false; // 是否使用压缩文件 // 当你即将发布你的塔时,请使用“JS代码压缩工具”将所有js代码进行压缩,然后将这里的useCompress改为true。 @@ -12,10 +12,15 @@ function main() { this.floorIds = [ // 在这里按顺序放所有的楼层;其顺序直接影响到楼层传送器的顺序和上楼器/下楼器的顺序 "sample0", "sample1", "sample2" ]; - this.pngs = [ // 在此存放所有可能的背景图片;背景图片最好是416*416像素,其他分辨率会被强制缩放成416*416 - // 建议对于较大的图片,在网上使用在线的“图片压缩工具”来进行压缩,以节省流量 - // 有关使用自定义背景图,请参见文档的“自定义素材”说明 - "bg.png", // 依次向后添加 + this.pngs = [ // 在此存放所有可能使用的图片,只能是png格式,可以不写后缀名 + // 图片可以被作为背景图(的一部分),也可以直接用自定义事件进行显示。 + // 图片名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 + // 建议对于较大的图片,在网上使用在线的“图片压缩工具(http://compresspng.com/zh/)”来进行压缩,以节省流量 + "bg", // 依次向后添加 + ]; + this.animates = [ // 在此存放所有可能使用的动画,必须是animate格式,在这里不写后缀名 + // 动画必须放在animates目录下;文件名不能使用中文,不能带空格或特殊字符 + "hand", "sword", "zone", "yongchang", // "jianji", "thunder" // 根据需求自行添加 ]; this.bgms = [ // 在此存放所有的bgm,和文件名一致。第一项为默认播放项 // 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 @@ -23,7 +28,7 @@ function main() { ]; this.sounds = [ // 在此存放所有的SE,和文件名一致 // 音频名不能使用中文,不能带空格或特殊字符;可以直接改名拼音就好 - 'floor.mp3', 'attack.ogg', 'door.ogg', 'item.ogg', + 'floor.mp3', 'attack.ogg', 'door.ogg', 'item.ogg', 'zone.ogg' ]; //------------------------ 用户修改内容 END ------------------------// @@ -95,6 +100,19 @@ function main() { 'load': document.getElementById("img-load"), 'settings': document.getElementById("img-settings") }, + 'icons': { + 'book': null, + 'fly': null, + 'toolbox': null, + 'save': null, + 'load': null, + 'settings': null, + 'rewind': null, // 减速 + 'forward': null, // 加速 + 'play': null, // 播放 + 'pause': null, // 暂停 + 'stop': null, // 停止 + }, 'floor': document.getElementById('floor'), 'lv': document.getElementById('lv'), 'hp': document.getElementById('hp'), @@ -122,6 +140,11 @@ main.prototype.init = function () { for (var i = 0; i < main.dom.gameCanvas.length; i++) { main.canvas[main.dom.gameCanvas[i].id] = main.dom.gameCanvas[i].getContext('2d'); } + Object.keys(this.statusBar.icons).forEach(function (t) { + var image=new Image(); + image.src="images/"+t+".png"; + main.statusBar.icons[t] = image; + }) main.loaderJs(function () { var coreData = {}; for (i = 0; i < main.loadList.length; i++) { @@ -131,7 +154,11 @@ main.prototype.init = function () { coreData[name] = main[name]; } main.loaderFloors(function() { - main.core.init(main.dom, main.statusBar, main.canvas, main.images, main.pngs, main.bgms, main.sounds, main.floorIds, main.floors, coreData); + ["dom", "statusBar", "canvas", "images", "pngs", + "animates", "bgms", "sounds", "floorIds", "floors"].forEach(function (t) { + coreData[t] = main[t]; + }) + main.core.init(coreData); main.core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight); }) }); @@ -319,12 +346,23 @@ main.dom.data.ontouchend = function () { ////// 点击状态栏中的怪物手册时 ////// main.statusBar.image.book.onclick = function () { + if (core.isset(core.status.replay) && core.status.replay.replaying) { + core.triggerReplay(); + return; + } + if (main.core.isPlaying()) main.core.openBook(true); } ////// 点击状态栏中的楼层传送器时 ////// main.statusBar.image.fly.onclick = function () { + + if (core.isset(core.status.replay) && core.status.replay.replaying) { + core.stopReplay(); + return; + } + if (main.core.isPlaying()) main.core.useFly(true); } @@ -343,12 +381,24 @@ main.statusBar.image.shop.onclick = function () { ////// 点击状态栏中的存档按钮时 ////// main.statusBar.image.save.onclick = function () { + + if (core.isset(core.status.replay) && core.status.replay.replaying) { + core.rewindReplay(); + return; + } + if (main.core.isPlaying()) main.core.save(true); } ////// 点击状态栏中的读档按钮时 ////// main.statusBar.image.load.onclick = function () { + + if (core.isset(core.status.replay) && core.status.replay.replaying) { + core.forwardReplay(); + return; + } + if (main.core.isPlaying()) main.core.load(true); } @@ -384,7 +434,7 @@ main.dom.replayGame.onclick = function () { alert("存档和游戏不一致!"); return; } - if (obj.version!=core.firstData.version) { + if (core.isset(obj.version) && obj.version!=core.firstData.version) { alert("游戏版本不一致!"); return; } @@ -397,8 +447,8 @@ main.dom.replayGame.onclick = function () { core.resetStatus(core.firstData.hero, obj.hard, core.firstData.floorId, null, core.initStatus.maps); core.events.setInitData(obj.hard); core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() { - core.setHeroMoveTriggerInterval(); - core.replay(core.decodeRoute(obj.route)); + //core.setHeroMoveTriggerInterval(); + core.startReplay(core.decodeRoute(obj.route)); }); }, function () { diff --git a/sounds/zone.ogg b/sounds/zone.ogg new file mode 100644 index 00000000..aef5fcbc Binary files /dev/null and b/sounds/zone.ogg differ diff --git a/styles.css b/styles.css index 397e82ce..817020c5 100644 --- a/styles.css +++ b/styles.css @@ -21,7 +21,7 @@ position: fixed; top: 10px; left: 10px; - z-index: 13; + z-index: 15; } #startPanel { @@ -32,7 +32,7 @@ left: 0; background-color: #fff; overflow: hidden; - z-index: 9; + z-index: 11; } #startTop { @@ -42,7 +42,7 @@ top: 0; left: 0; background-color: #000; - z-index: 12; + z-index: 14; } #startTopProgressBar { @@ -52,7 +52,7 @@ position: absolute; top: 5%; background-color: #fff; - z-index: 13; + z-index: 15; } #startTopProgress { @@ -67,7 +67,7 @@ position: absolute; top: 8%; left: 5%; - z-index: 13; + z-index: 15; } #startBackground { @@ -77,12 +77,12 @@ height: 100%; width: auto; transform:translate(-50%,-50%); - z-index: 10; + z-index: 12; } #startLogo { position: absolute; - z-index: 10; + z-index: 12; left: 0; right: 0; margin-left: auto; @@ -95,7 +95,7 @@ #startTitle { position: absolute; - z-index: 11; + z-index: 13; } #startButtonGroup { @@ -106,7 +106,7 @@ background-color: #000; opacity: 0.85; display: none; - z-index: 10; + z-index: 12; bottom: 0; margin-bottom: 7%; } @@ -142,7 +142,7 @@ display: none; color: #fff; background-color: #000; - z-index: 8; + z-index: 10; } #logoLabel { @@ -170,7 +170,7 @@ -moz-box-sizing: border-box; -webkit-box-sizing: border-box; background: url(images/ground.png) repeat; - z-index: 7; + z-index: 9; display: none; } #statusBar .status{ @@ -199,7 +199,7 @@ #toolBar { position: absolute; background: url(images/ground.png) repeat; - z-index: 6; + z-index: 8; box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; @@ -234,7 +234,7 @@ span#poison, span#weak, span#curse { } #curtain { - z-index: 5; + z-index: 7; position: absolute; opacity: 0; background: #000000; @@ -256,12 +256,20 @@ span#poison, span#weak, span#curse { z-index: 4; } -#ui { +#animate { + z-index: 5; +} + +#weather { z-index: 6; } +#ui { + z-index: 8; +} + #data { - z-index: 7; + z-index: 9; } .clearfix:before, diff --git a/启动服务.exe b/启动服务.exe index e403609a..2ec60d88 100644 Binary files a/启动服务.exe and b/启动服务.exe differ diff --git a/常用工具/Newtonsoft.Json.dll b/常用工具/Newtonsoft.Json.dll new file mode 100644 index 00000000..67b9d351 Binary files /dev/null and b/常用工具/Newtonsoft.Json.dll differ diff --git a/常用工具/RM动画导出器.exe b/常用工具/RM动画导出器.exe new file mode 100644 index 00000000..0e762d67 Binary files /dev/null and b/常用工具/RM动画导出器.exe differ diff --git a/常用工具/rgss.dll b/常用工具/rgss.dll new file mode 100644 index 00000000..1b3f0854 Binary files /dev/null and b/常用工具/rgss.dll differ diff --git a/常用工具/便捷PS工具.exe b/常用工具/便捷PS工具.exe index a85e29fd..3d453d0c 100644 Binary files a/常用工具/便捷PS工具.exe and b/常用工具/便捷PS工具.exe differ diff --git a/常用工具/地图生成器.exe b/常用工具/地图生成器.exe index 286aa26b..6d56bf06 100644 Binary files a/常用工具/地图生成器.exe and b/常用工具/地图生成器.exe differ diff --git a/快捷键说明.txt b/快捷键说明.txt index 525b10d5..0e0fcf45 100644 --- a/快捷键说明.txt +++ b/快捷键说明.txt @@ -12,6 +12,7 @@ [K] 打开/关闭快捷商店选择列表 [T] 打开/关闭工具栏 [ESC] 打开/关闭系统菜单 +[E] 显示光标 [H] 打开帮助页面 [R] 回放 [SPACE] 轻按(仅在轻按开关打开时有效) diff --git a/更新说明.txt b/更新说明.txt index 36d57caf..63fe424a 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -1,4 +1,35 @@ -HTML5魔塔样板V1.3.2 +HTML5魔塔样板V1.4.1 + +改变图块(setBlock事件)。 +同一个点的多事件处理(做法详见文档)。 +地图中每个块的可通行方向控制(悬崖效果)。 +动画支持带旋转和翻转的帧。 +现在可以允许用户丢弃道具了(例如不会再使用的装备)。 +修复行走时按键会发生动画抖动问题。 +修复无法打开战斗动画的Bug。 + +----------------------------------------------------------------------- + +HTML5魔塔样板V1.4 + +动画!动画!!动画!!! +瞬间移动。 +支持天气系统,可以在剧本中设置默认天气。 +新增自定义事件-图片显示。 +同时可以在剧本中设定多个背景素材。 +剧情文本特性控制,人物的对话框效果。 +单存档同步到服务器,下载到文件和读取。 +键盘支持自动寻路操作。 +浏览地图模式下可以查看怪物数据。 +未成功打怪和开门则不自动存档。 +重新支持楼梯穿透。 +支持多结局,成绩将分开统计。 +重构全局动画、行走动画和行走检测,大幅提升性能。 +修复所有已知Bug。 + +----------------------------------------------------------------------- + +HTML5魔塔样板V1.3.2 增加录像和回放功能。 增加统计功能,现在能看到每部塔的游戏人数、通关人数和当前MAX了。