From 45586df3383d5c416b1c3ab5da874f11d31b287d Mon Sep 17 00:00:00 2001 From: lizhuoyuan <2820814112@qq.com> Date: Sat, 4 Jan 2025 15:23:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=BC=B9=E5=B9=95=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libs/utils.js | 3 +- project/functions.js | 202 +++++++++++++++++++------------------- project/plugins.js | 226 ++++++++++++++++++++++--------------------- runtime.d.ts | 4 +- 4 files changed, 223 insertions(+), 212 deletions(-) diff --git a/libs/utils.js b/libs/utils.js index 5f50de4d..a2bc9d06 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -1316,9 +1316,10 @@ utils.prototype._unzip_readEntries = function (entries, success, convertToText) }); } -utils.prototype.http = function (type, url, formData, success, error, mimeType, responseType, onprogress) { +utils.prototype.http = function (type, url, formData, success, error, mimeType, responseType, onprogress, timeout) { var xhr = new XMLHttpRequest(); xhr.open(type, url, true); + xhr.timeout = timeout; if (mimeType) xhr.overrideMimeType(mimeType); if (responseType) xhr.responseType = responseType; xhr.onload = function (e) { diff --git a/project/functions.js b/project/functions.js index fd7c9f44..8e285169 100644 --- a/project/functions.js +++ b/project/functions.js @@ -1,8 +1,8 @@ /// -var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = +var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = { - "events": { - "resetGame": function (hero, hard, floorId, maps, values) { + "events": { + "resetGame": function (hero, hard, floorId, maps, values) { // 重置整个游戏;此函数将在游戏开始时,或者每次读档时最先被调用 // hero:勇士信息;hard:难度;floorId:当前楼层ID;maps:地图信息;values:全局数值信息 @@ -52,7 +52,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 隐藏右下角的音乐按钮 core.dom.musicBtn.style.display = 'none'; }, - "win": function (reason, norank, noexit) { + "win": function (reason, norank, noexit) { // 游戏获胜事件 // 请注意,成绩统计时是按照hp进行上传并排名 // 可以先在这里对最终分数进行计算,比如将2倍攻击和5倍黄钥匙数量加到分数上 @@ -81,7 +81,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = }) }); }, - "lose": function (reason) { + "lose": function (reason) { // 游戏失败事件 core.ui.closePanel(); var replaying = core.isReplaying(); @@ -94,75 +94,77 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = }); }) }, - "changingFloor": function (floorId, heroLoc) { - // 正在切换楼层过程中执行的操作;此函数的执行时间是“屏幕完全变黑“的那一刻 - // floorId为要切换到的楼层ID;heroLoc表示勇士切换到的位置 + "changingFloor": function (floorId, heroLoc) { + // 正在切换楼层过程中执行的操作;此函数的执行时间是“屏幕完全变黑“的那一刻 + // floorId为要切换到的楼层ID;heroLoc表示勇士切换到的位置 - // ---------- 此时还没有进行切换,当前floorId还是原来的 ---------- // - var currentId = core.status.floorId || null; // 获得当前的floorId,可能为null - var fromLoad = core.hasFlag('__fromLoad__'); // 是否是读档造成的切换 - var isFlying = core.hasFlag('__isFlying__'); // 是否是楼传造成的切换 - if (!fromLoad && !(isFlying && currentId == floorId)) { - if (!core.hasFlag("__leaveLoc__")) core.setFlag("__leaveLoc__", {}); - if (currentId != null) core.getFlag("__leaveLoc__")[currentId] = core.clone(core.status.hero.loc); + // ---------- 此时还没有进行切换,当前floorId还是原来的 ---------- // + var currentId = core.status.floorId || null; // 获得当前的floorId,可能为null + var fromLoad = core.hasFlag('__fromLoad__'); // 是否是读档造成的切换 + var isFlying = core.hasFlag('__isFlying__'); // 是否是楼传造成的切换 + if (!fromLoad && !(isFlying && currentId == floorId)) { + if (!core.hasFlag("__leaveLoc__")) core.setFlag("__leaveLoc__", {}); + if (currentId != null) core.getFlag("__leaveLoc__")[currentId] = core.clone(core.status.hero.loc); + } + + // 可以对currentId进行判定,比如删除某些自定义图层等 + // if (currentId == 'MT0') { + // core.deleteAllCanvas(); + // } + + // 根据分区信息自动砍层与恢复 + if (core.autoRemoveMaps) core.autoRemoveMaps(floorId); + + // 重置画布尺寸 + core.maps.resizeMap(floorId); + // 设置勇士的位置 + heroLoc.direction = core.turnDirection(heroLoc.direction); + core.status.hero.loc = heroLoc; + // 检查重生怪并重置 + if (!fromLoad) { + core.extractBlocks(floorId); + core.status.maps[floorId].blocks.forEach(function (block) { + if (block.disable && core.enemys.hasSpecial(block.event.id, 23)) { + block.disable = false; + core.setMapBlockDisabled(floorId, block.x, block.y, false); + core.maps._updateMapArray(floorId, block.x, block.y); } + }); + core.control.gatherFollowers(); + } - // 可以对currentId进行判定,比如删除某些自定义图层等 - // if (currentId == 'MT0') { - // core.deleteAllCanvas(); - // } + // ---------- 重绘新地图;这一步将会设置core.status.floorId ---------- // + core.drawMap(floorId); - // 根据分区信息自动砍层与恢复 - if (core.autoRemoveMaps) core.autoRemoveMaps(floorId); + // 切换楼层BGM + if (core.status.maps[floorId].bgm) { + var bgm = core.status.maps[floorId].bgm; + if (bgm instanceof Array) bgm = bgm[Math.floor(Math.random() * bgm.length)]; // 多个bgm则随机播放一个 + if (!core.hasFlag("__bgm__")) core.playBgm(bgm); + } else if (fromLoad && !core.hasFlag("__bgm__")) { + core.pauseBgm(); + } + // 更改画面色调 + var color = core.getFlag('__color__', null); + if (!color && core.status.maps[floorId].color) + color = core.status.maps[floorId].color; + core.clearMap('curtain'); + core.status.curtainColor = color; + if (color) core.fillRect('curtain', 0, 0, core.__PIXELS__, core.__PIXELS__, core.arrayToRGBA(color)); + // 更改天气 + var weather = core.getFlag('__weather__', null); + if (!weather && core.status.maps[floorId].weather) + weather = core.status.maps[floorId].weather; + if (weather) + core.setWeather(weather[0], weather[1]); + else core.setWeather(); - // 重置画布尺寸 - core.maps.resizeMap(floorId); - // 设置勇士的位置 - heroLoc.direction = core.turnDirection(heroLoc.direction); - core.status.hero.loc = heroLoc; - // 检查重生怪并重置 - if (!fromLoad) { - core.extractBlocks(floorId); - core.status.maps[floorId].blocks.forEach(function (block) { - if (block.disable && core.enemys.hasSpecial(block.event.id, 23)) { - block.disable = false; - core.setMapBlockDisabled(floorId, block.x, block.y, false); - core.maps._updateMapArray(floorId, block.x, block.y); - } - }); - core.control.gatherFollowers(); - } + core.deleteAllTickers(); // 摧毁所有现存的高级动画 - // ---------- 重绘新地图;这一步将会设置core.status.floorId ---------- // - core.drawMap(floorId); + // ...可以新增一些其他内容,比如创建个画布在右上角显示什么内容等等 - // 切换楼层BGM - if (core.status.maps[floorId].bgm) { - var bgm = core.status.maps[floorId].bgm; - if (bgm instanceof Array) bgm = bgm[Math.floor(Math.random() * bgm.length)]; // 多个bgm则随机播放一个 - if (!core.hasFlag("__bgm__")) core.playBgm(bgm); - } else if (fromLoad && !core.hasFlag("__bgm__")) { - core.pauseBgm(); - } - // 更改画面色调 - var color = core.getFlag('__color__', null); - if (!color && core.status.maps[floorId].color) - color = core.status.maps[floorId].color; - core.clearMap('curtain'); - core.status.curtainColor = color; - if (color) core.fillRect('curtain', 0, 0, core.__PIXELS__, core.__PIXELS__, core.arrayToRGBA(color)); - // 更改天气 - var weather = core.getFlag('__weather__', null); - if (!weather && core.status.maps[floorId].weather) - weather = core.status.maps[floorId].weather; - if (weather) - core.setWeather(weather[0], weather[1]); - else core.setWeather(); - - // ...可以新增一些其他内容,比如创建个画布在右上角显示什么内容等等 - - }, - "afterChangeFloor": function (floorId) { +}, + "afterChangeFloor": function (floorId) { // 转换楼层结束的事件;此函数会在整个楼层切换完全结束后再执行 // floorId是切换到的楼层 @@ -181,7 +183,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = } } }, - "flyTo": function (toId, callback) { + "flyTo": function (toId, callback) { // 楼层传送器的使用,从当前楼层飞往toId // 如果不能飞行请返回false @@ -224,7 +226,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = return true; }, - "beforeBattle": function (enemyId, x, y) { + "beforeBattle": function (enemyId, x, y) { // 战斗前触发的事件,可以加上一些战前特效(详见下面支援的例子) // 此函数在“检测能否战斗和自动存档”【之后】执行。如果需要更早的战前事件,请在插件中覆重写 core.events.doSystemEvent 函数。 // 返回true则将继续战斗,返回false将不再战斗。 @@ -255,7 +257,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = return true; }, - "afterBattle": function (enemyId, x, y) { + "afterBattle": function (enemyId, x, y) { // 战斗结束后触发的事件 var enemy = core.material.enemys[enemyId]; @@ -426,7 +428,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.clearContinueAutomaticRoute(); }, - "afterOpenDoor": function (doorId, x, y) { + "afterOpenDoor": function (doorId, x, y) { // 开一个门后触发的事件 var todo = []; @@ -447,7 +449,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = else core.clearContinueAutomaticRoute(); }, - "afterGetItem": function (itemId, x, y, isGentleClick) { + "afterGetItem": function (itemId, x, y, isGentleClick) { // 获得一个道具后触发的事件 // itemId:获得的道具ID;x和y是该道具所在的坐标 // isGentleClick:是否是轻按触发的 @@ -468,7 +470,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = if (todo.length > 0) core.insertAction(todo, x, y); }, - "afterPushBox": function () { + "afterPushBox": function () { // 推箱子后的事件 if (core.searchBlock('box').length == 0) { // 可以通过if语句来进行开门操作 @@ -481,9 +483,9 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = */ } } - }, - "enemys": { - "getSpecials": function () { + }, + "enemys": { + "getSpecials": function () { // 获得怪物的特殊属性,每一行定义一个特殊属性。 // 分为五项,第一项为该特殊属性的数字,第二项为特殊属性的名字,第三项为特殊属性的描述 // 第四项为该特殊属性的颜色,可以写十六进制 #RRGGBB 或者 [r,g,b,a] 四元数组 @@ -519,7 +521,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = [27, "捕捉", function (enemy) { return "当走到怪物周围" + (enemy.zoneSquare ? "九宫格" : "十字") + "时会强制进行战斗。"; }, "#c0ddbb"] ]; }, - "getEnemyInfo": function (enemy, hero, x, y, floorId) { + "getEnemyInfo": function (enemy, hero, x, y, floorId) { // 获得某个怪物变化后的数据;该函数将被伤害计算和怪物手册使用 // 例如:坚固、模仿、仿攻等等 // @@ -642,7 +644,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = "guards": guards, // 返回支援情况 }; }, - "getDamageInfo": function (enemy, hero, x, y, floorId) { + "getDamageInfo": function (enemy, hero, x, y, floorId) { // 获得战斗伤害信息(实际伤害计算函数) // // 参数说明: @@ -800,9 +802,9 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = "damage": Math.floor(damage) }; } - }, - "actions": { - "onKeyUp": function (keyCode, altKey) { + }, + "actions": { + "onKeyUp": function (keyCode, altKey) { // 键盘按键处理,可以在这里自定义快捷键列表 // keyCode:当前按键的keyCode(每个键的keyCode自行百度) // altKey:Alt键是否被按下,为true代表同时按下了Alt键 @@ -950,7 +952,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = } }, - "onStatusBarClick": function (px, py, vertical) { + "onStatusBarClick": function (px, py, vertical) { // 点击状态栏时触发的事件,仅在自绘状态栏开启时生效 // px和py为点击的像素坐标 // vertical为录像播放过程中的横竖屏信息 @@ -1018,9 +1020,9 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = */ } - }, - "control": { - "saveData": function () { + }, + "control": { + "saveData": function () { // 存档操作,此函数应该返回“具体要存档的内容” // 差异化存储values @@ -1045,7 +1047,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = return data; }, - "loadData": function (data, callback) { + "loadData": function (data, callback) { // 读档操作;从存储中读取了内容后的行为 // 重置游戏和路线 @@ -1084,7 +1086,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = if (callback) callback(); }); }, - "getStatusLabel": function (name) { + "getStatusLabel": function (name) { // 返回某个状态英文名的对应中文标签,如atk -> 攻击,def -> 防御等。 // 请注意此项仅影响 libs/ 下的内容(如绘制怪物手册、数据统计等) // 自行定义的(比如获得道具效果)中用到的“攻击+3”等需要自己去对应地方修改 @@ -1105,7 +1107,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = steps: "步数", }[name] || name; }, - "triggerDebuff": function (action, type) { + "triggerDebuff": function (action, type) { // 毒衰咒效果的获得与解除 // action:获得还是解除;'get'表示获得,'remove'表示解除 // type:一个数组表示获得了哪些毒衰咒效果;poison, weak,curse @@ -1162,7 +1164,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = if (success) core.playSound('回血'); } }, - "updateStatusBar": function () { + "updateStatusBar": function () { // 更新状态栏 // 检查等级 @@ -1244,7 +1246,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // updateDamage只能在此处执行!!更新全地图显伤 core.updateDamage(); }, - "updateCheckBlock": function (floorId) { + "updateCheckBlock": function (floorId) { // 领域、夹击、阻击等的伤害值计算 floorId = floorId || core.status.floorId; if (!floorId || !core.status.maps) return; @@ -1455,7 +1457,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = cache: {} // clear cache }; }, - "moveOneStep": function (callback) { + "moveOneStep": function (callback) { // 勇士每走一步后执行的操作。callback为行走完毕后的回调 // 这个函数执行在“刚走完”的时候,即还没有检查该点的事件和领域伤害等。 // 请注意:瞬间移动不会执行该函数。如果要控制能否瞬间移动有三种方法: @@ -1518,7 +1520,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 如需强行终止行走可以在这里条件判定: // core.stopAutomaticRoute(); }, - "moveDirectly": function (x, y, ignoreSteps) { + "moveDirectly": function (x, y, ignoreSteps) { // 瞬间移动;x,y为要瞬间移动的点;ignoreSteps为减少的步数,可能之前已经被计算过 // 返回true代表成功瞬移,false代表没有成功瞬移 @@ -1556,7 +1558,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = } return false; }, - "parallelDo": function (timestamp) { + "parallelDo": function (timestamp) { // 并行事件处理,可以在这里写任何需要并行处理的脚本或事件 // 该函数将被系统反复执行,每次执行间隔视浏览器或设备性能而定,一般约为16.6ms一次 // 参数timestamp为“从游戏资源加载完毕到当前函数执行时”的时间差,以毫秒为单位 @@ -1573,9 +1575,9 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = } } } - }, - "ui": { - "getToolboxItems": function (cls) { + }, + "ui": { + "getToolboxItems": function (cls) { // 获得道具栏中当前某类型道具的显示项和显示顺序 // cls为道具类型,只可能是 tools, constants 和 equips // 返回一个数组,代表当前某类型道具的显示内容和顺序 @@ -1585,7 +1587,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = .filter(function (id) { return !core.material.items[id].hideInToolbox; }) .sort( /*function (id1, id2) { return core.material.items[id1].name <= core.material.items[id2].name ? -1 : 1 }*/); }, - "drawStatusBar": function () { + "drawStatusBar": function () { // 自定义绘制状态栏,需要开启状态栏canvas化 // 如果是非状态栏canvas化,直接返回 @@ -1688,7 +1690,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = _fillBoldTextWithFontCheck(core.setTwoDigits(core.itemCount('redKey')), 212, 90, '#FF8888'); } }, - "drawStatistics": function () { + "drawStatistics": function () { // 浏览地图时参与的统计项目 return [ @@ -1704,7 +1706,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 在这里可以增加新的ID来进行统计个数,只能增加道具ID ]; }, - "drawAbout": function () { + "drawAbout": function () { // 绘制“关于”界面 core.ui.closePanel(); core.lockControl(); @@ -1732,5 +1734,5 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // TODO: 写自己的“关于”页面,每次增加32像素即可 core.playSound('打开界面'); } - } + } } \ No newline at end of file diff --git a/project/plugins.js b/project/plugins.js index 33256872..e5bf2bc4 100644 --- a/project/plugins.js +++ b/project/plugins.js @@ -3193,6 +3193,38 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.registerReplayAction("equip", core.control._replayAction_equip); core.registerReplayAction("unEquip", core.control._replayAction_unEquip); }, + "FloatingText": function () { + // 本插件定义了一些字符绘制相关效果 + + const { Animation, linear } = core.plugin.animate; + const ctx = 'scrollingText'; + + new Animation().ticker.add(() => { + core.createCanvas(ctx, 0, 0, core.__PIXELS__, core.__PIXELS__, 200); //每帧重绘该画布 + }); + + /** + * 绘制弹幕 + * @example + * core.plugin.drawCommentStr('OK', 450, 200, 0.1); + * @param {string} content 弹幕的内容 + * @param {number} x 弹幕的初始x坐标 + * @param {number} y 弹幕的初始y坐标 + * @param {number} vx 弹幕的横向滚动速度 + */ + this.drawCommentStr = function (content, x, y, vx) { + if (core.isReplaying()) return; + const ani = new Animation(); + ani.ticker.add(() => { + core.fillText(ctx, content, x + ani.x, y, 'white', '16px Verdana'); + }) + ani.mode(linear()) + .time(600 / vx) + .absolute() + .move(-600, 0) + ani.all().then(() => { ani.ticker.destroy(); }); + } + }, "MenuBase": function () { // 本插件定义了一些用于绘制的基类 class ButtonBase { @@ -3289,57 +3321,13 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = /** 塔的英文名 */ const towerName = core.firstData.name; - let W, H, WIDTH, HEIGHT; - if (core._WIDTH_ && core._HEIGHT_) { - [W, H] = [core._WIDTH_, core._HEIGHT_]; - } else if (core.__SIZE__) { - [W, H] = [core.__SIZE__, core.__SIZE__]; - } else { - [W, H] = [13, 13]; - } - if (core._PX_ && core._PY_) { - [WIDTH, HEIGHT] = [core._PX_, core._PY_]; - } else if (core.__SIZE__) { - [WIDTH, HEIGHT] = [core.__PIXELS__, core.__PIXELS__]; - } else { - [WIDTH, HEIGHT] = [416, 416]; - } + let [W, H] = [core.__SIZE__, core.__SIZE__]; + let [WIDTH, HEIGHT] = [core.__PIXELS__, core.__PIXELS__]; - utils.prototype.http = function (type, url, formData, success, error, mimeType, responseType, onprogress, timeout) { - let xhr = new XMLHttpRequest(); - xhr.open(type, url, true); - - xhr.timeout = timeout; - if (mimeType) xhr.overrideMimeType(mimeType); - if (responseType) xhr.responseType = responseType; - xhr.onload = function (e) { - if (xhr.status == 200) { - if (success) success(xhr.response); - } else { - if (error) error("HTTP " + xhr.status); - } - }; - xhr.onprogress = function (e) { - if (e.lengthComputable) { - if (onprogress) onprogress(e.loaded, e.total); - } - } - xhr.onabort = function () { - if (error) error("Abort"); - } - xhr.ontimeout = function () { - if (error) error("Timeout"); - } - xhr.onerror = function () { - if (error) error("Error on Connection"); - } - if (formData) - xhr.send(formData); - else xhr.send(); - } - + //#region 弹幕的收发 this.getComment = function () { + if (core.isReplaying()) return; let form = new FormData(); form.append('type', 1); form.append('towername', towerName); @@ -3348,56 +3336,28 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = 'https://h5mota.com/backend/tower/barrage.php', form, function (res) { - res = JSON.parse(res); - console.log(res); - core.drawTip('接收成功!') - core.playSound('item.mp3'); - let commentCollection = {}; - const commentList = res?.list; - for (let i = 0, l = commentList.length; i <= l - 1; i++) { - if (commentList[i]?.comment?.length === 0 || commentList[i]?.comment.match(/^[ ]*$/)) continue; - const commentTags = commentList[i].tags; - const cFloorId = commentTags.split(',')[0], - cX = parseInt(commentTags.split(',')[1]), - cY = parseInt(commentTags.split(',')[2]); - if (0 <= cX && cX <= W - 1 && 0 <= cY && - cY <= H - 1 && core.floorIds.includes(cFloorId)) { - if (!commentCollection.hasOwnProperty(cFloorId)) { commentCollection[cFloorId] = {}; } - const str = cX + ',' + cY; - if (!commentCollection[cFloorId].hasOwnProperty(str)) { commentCollection[cFloorId][str] = []; } - commentCollection[cFloorId][str].push(commentList[i]?.comment); - } - } - core.setFlag('commentCollection', commentCollection); - }, - function (err) { - err = JSON.parse(err); - console.error(err); - core.drawTip('接收失败' + err?.message); - core.playSound('error.mp3'); - }, - null, null, null, 1000 - ); - } - - this.postComment = function (comment, tags) { - let form = new FormData(); - form.append('type', 2); - form.append('towername', towerName); - form.append('comment', comment); - form.append('tags', tags); - utils.prototype.http( - 'POST', - 'https://h5mota.com/backend/tower/barrage.php', - form, - function (res) { - res = JSON.parse(res); - console.log(res); - if (res?.code === 0) { - core.drawTip('提交成功!') + try { + res = JSON.parse(res); + console.log(res); + core.drawTip('接收成功!') core.playSound('item.mp3'); - } else { - core.drawTip('提交失败!' + res?.message); + let commentCollection = {}; + const commentList = res?.list; + const isEmpty = /^\s*$/; + for (let i = 0, l = commentList.length; i <= l - 1; i++) { + if (isEmpty.test(commentList[i]?.comment)) continue; + const commentTagsList = commentList[i].tags.split(','); + const [cFloorId, cX, cY] = commentTagsList; + if (0 <= cX && cX <= W - 1 && 0 <= cY && cY <= H - 1 && core.floorIds.includes(cFloorId)) { + if (!commentCollection.hasOwnProperty(cFloorId)) { commentCollection[cFloorId] = {}; } + const str = cX + ',' + cY; + if (!commentCollection[cFloorId].hasOwnProperty(str)) { commentCollection[cFloorId][str] = []; } + commentCollection[cFloorId][str].push(commentList[i]?.comment); + } + } + core.setFlag('commentCollection', commentCollection); + } catch (err) { + core.drawTip('接收消息失败!' + err.message); core.playSound('error.mp3'); } }, @@ -3411,6 +3371,51 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = ); } + this.postComment = function (comment, tags) { + if (core.isReplaying()) return; + const isEmpty = /^\s*$/; + if (isEmpty.test(comment)){ + core.drawTip('您输入的消息为空,请重发!'); + core.playSound('error.mp3'); + return; + } + let form = new FormData(); + form.append('type', 2); + form.append('towername', towerName); + form.append('comment', comment); + form.append('tags', tags); + utils.prototype.http( + 'POST', + 'https://h5mota.com/backend/tower/barrage.php', + form, + function (res) { + try { + res = JSON.parse(res); + console.log(res); + if (res?.code === 0) { + core.drawTip('提交成功!') + core.playSound('item.mp3'); + } else { + core.drawTip('提交失败!' + res?.message); + core.playSound('error.mp3'); + } + } + catch (err) { + core.drawTip('接收消息失败!' + err.message); + core.playSound('error.mp3'); + } + }, + function (err) { + err = JSON.parse(err); + console.error(err); + core.drawTip('接收失败' + err?.message); + core.playSound('error.mp3'); + }, + null, null, null, 1000 + ); + } + //#endregion + this.drawCommentSign = function () { if (!core.getFlag('comment') || core.isReplaying()) return; let commentCollection = core.getFlag('commentCollection', {}), @@ -3419,15 +3424,11 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.setOpacity('sign', 0.6); if (commentCollection.hasOwnProperty(floorId)) { for (let pos in commentCollection[floorId]) { - if (commentCollection[floorId][pos].length > 0) { - for (let i = 0, l = commentCollection[floorId][pos].length; i <= l - 1; i++) { - if (!(commentCollection[floorId][pos][i].match(/^[ ]*$/))) { - const x = pos.split(',')[0], - y = pos.split(',')[1]; - core.drawImage('sign', 'sign.png', 32 * x, 32 * y); - break; - } - } + const l = commentCollection[floorId][pos].length; + for (let i = 0; i <= l - 1; i++) { + const [x, y] = pos.split(','); + core.drawImage('sign', 'sign.png', 32 * x, 32 * y); + break; } } } @@ -3437,11 +3438,12 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = core.deleteCanvas('sign'); } - const showNum = 5; - - function pickComment(commentArr, showNum = 5) { + /** 返回从commentArr中挑选showNum个comment组成的数组*/ + function pickComment(commentArr, showNum) { let showList = []; - if (commentArr.length <= showNum) { showList = commentArr; } else { + if (commentArr.length <= showNum) { + showList = commentArr; + } else { for (let i = 0; i <= showNum - 1; i++) { const l = commentArr.length, n = core.plugin.dice(l - 1); @@ -3452,6 +3454,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = return showList; } + /** 生成count个随机数,范围从min到max,作为弹幕的y坐标*/ function generateCommentYList(min, max, count) { let yList = Array(count).fill(0); const distance = (max - min) / (count + 1); @@ -3474,6 +3477,9 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = return result.slice(len - count); } + /** 默认一次显示的弹幕数 */ + const showNum = 5; + function drawComment(commentArr) { const l = commentArr.length; let yList = generateCommentYList(20, HEIGHT - 20, showNum); diff --git a/runtime.d.ts b/runtime.d.ts index 0f57c07e..5fa5d49d 100644 --- a/runtime.d.ts +++ b/runtime.d.ts @@ -2714,8 +2714,10 @@ interface utils { * @param formData 如果是POST请求则为表单数据 * @param success 成功后的回调 * @param error 失败后的回调 + * @param timeout 超时时间 */ - http(type: 'GET' | 'POST', url: string, formData: FormData, success: () => void, error: () => void): void + http(type: 'GET' | 'POST', url: string, formData: FormData, success: () => void, error: () => void, + mimeType: string, responseType: XMLHttpRequestResponseType, onprogress: boolean, timeout: number): void /** 获得浏览器唯一的guid */ getGuid(): string