设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 3245|回复: 17
打印 上一主题 下一主题

[有事请教] 实用插件,RPG Maker MZ根据敌人个数,敌人坐标自动排列或...

[复制链接]

Lv2.观梦者

梦石
0
星屑
677
在线时间
115 小时
注册时间
2012-9-30
帖子
102
跳转到指定楼层
1
发表于 2022-11-25 09:57:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
100星屑
求一个实用插件,RPG Maker MZ根据敌人个数,敌人坐标自动排列或者布阵的插件

Lv3.寻梦者

梦石
0
星屑
1340
在线时间
165 小时
注册时间
2022-9-17
帖子
102
2
发表于 2022-11-25 18:07:50 | 只看该作者
这是CSVN的随机敌人插件。根据你作品的分辨率设置好后,他会随机放置敌人的位置。
至于随机敌人,这个功能如果你觉得有趣的话,也可以使用。

  1. /*=============================================================================
  2. CSVN_randomEnemies.js
  3. ----------------------------------------------------------------------------
  4. (C)2020 munokura
  5. (C)2021 cursed_steven
  6. This software is released under the MIT License.
  7. http://opensource.org/licenses/mit-license.php
  8. ----------------------------------------------------------------------------
  9. Version
  10. 1.0.0 2021/08/05 初版
  11. 1.0.1 2021/08/05 戦闘テスト以外で動作しない不具合を修正
  12. 1.1.0 2021/10/12 バトラー画像名と敵キャラ名が同じ前提であったのを修正
  13. 2.0.0 2021/11/01 リファクタ、サイドビューに対応、battlerImageタグを不要に。
  14. 2.0.1 2021/11/06 サイドビューの場合完全ランダムではなくほどほどに重ならないように
  15.                   座標を調整する仕様を追加。
  16. 2.0.2 2021/11/12 固有名をつける処理のバグを修正、NUUN_BattleBGM対応追加。
  17. 2.0.3 2022/02/11 横幅が大きい敵画像をSVで使うと位置が右に寄りすぎる問題の修正
  18. ----------------------------------------------------------------------------
  19. [Twitter]: https://twitter.com/cursed_steven
  20. =============================================================================*/

  21. /*:
  22. * @target MZ
  23. * @author ムノクラ(+ノロワレ)
  24. * @url https://note.com/cursed_steven/n/n097b817e4856
  25. * @plugindesc 敵グループの敵キャラをランダムに入れ替えます。
  26. * @base PluginCommonBase
  27. * @orderAfter PluginCommonBase
  28. * @help 敵グループの敵キャラをランダムに入れ替えます。
  29. *
  30. * 敵キャラのメモ欄に下記のようにタグを入れてください。
  31. * <RandomEnemy:敵キャラID>
  32. * <RandomEnemy:敵キャラID,敵キャラID,敵キャラID>
  33. * 0は非表示になります。
  34. *
  35. * 例
  36. * <RandomEnemy:0,0,1,1,2,3>
  37. *
  38. * フロントビューの場合、戦闘開始時エネミー画像は、0で非表示になった分を
  39. * 考慮して均等に並べ直されます。
  40. * また、そのためのエネミー画像をプリロードするので、画像が
  41. * あまり多いとか重いとかだとアレかもしれません。
  42. * また、MVはウチに環境がないので target からは除外しました。
  43. * 確認可能な方はしてみてください。
  44. *
  45. * プラグインコマンドはありません。
  46. *
  47. * このプラグインは munokura =サン作の MNKR_RandomEnemies.js (v.1.0.4)を
  48. * ベースにしつつリライトしてかいはつされています。
  49. *
  50. * 利用規約:
  51. *   MITライセンスです。
  52. *   https://licenses.opensource.jp/MIT/MIT.html
  53. *   作者に無断で改変、再配布が可能で、
  54. *   利用形態(商用、18禁利用等)についても制限はありません。
  55. *
  56. * @param boxWidth
  57. * @text 画面横幅
  58. * @desc システム2の「画面の幅」
  59. * @default 816
  60. * @type number
  61. *
  62. * @param boxHeight
  63. * @text 画面高さ
  64. * @desc システム2の「画面の高さ」
  65. * @default 624
  66. * @type number
  67. *
  68. * @param enemyIdFrom
  69. * @text 敵キャラIDFrom
  70. * @desc 画像をプリロードする敵キャラIDの範囲(From)
  71. * @type number
  72. *
  73. * @param enemyIdTo
  74. * @text 敵キャラIDTo
  75. * @desc 画像をプリロードする敵キャラIDの範囲(To)
  76. * @type number
  77. */

  78. (() => {

  79.     'use strict';
  80.     const params = PluginManagerEx.createParameter(document.currentScript);
  81.     const boxWidth = params.boxWidth ? params.boxWidth : 816;
  82.     const boxHeight = params.boxHeight ? params.boxHeight : 624;
  83.     const enemyIdFrom = params.enemyIdFrom ? params.enemyIdFrom : 1;
  84.     const enemyIdTo = params.enemyIdTo ? params.enemyIdTo : 2000;

  85.     const _Scene_Boot_onDatabaseLoaded = Scene_Boot.prototype.onDatabaseLoaded;
  86.     Scene_Boot.prototype.onDatabaseLoaded = function() {
  87.         _Scene_Boot_onDatabaseLoaded.call(this);

  88.         ImageManager.preloadEnemyImages(enemyIdFrom, enemyIdTo);
  89.     };

  90.     const _Scene_Map_create = Scene_Map.prototype.create;
  91.     Scene_Map.prototype.create = function() {
  92.         _Scene_Map_create.call(this);

  93.         ImageManager.preloadEnemyImages(enemyIdFrom, enemyIdTo);
  94.     };

  95.     ImageManager.preloadEnemyImages = function(from, to) {
  96.         for (let enemyId = from; enemyId <= to; enemyId++) {
  97.             const dataEnemy = $dataEnemies[enemyId];
  98.             if (dataEnemy && dataEnemy.battlerName) {
  99.                 this.loadEnemy(dataEnemy.battlerName);
  100.             }
  101.         }
  102.     };

  103.     Game_Troop.prototype.setup = function(troopId) {

  104.         this.clear();
  105.         this._troopId = troopId;

  106.         let members = this.lotteryEnemyIds();

  107.         while (members.length == 0) {

  108.             // 全部いなくなってしまった場合は再抽選
  109.             members = this.lotteryEnemyIds();

  110.         }

  111.         // フロントビューかサイドビューかを判別して敵配置
  112.         if ($gameSystem.isSideView()) {

  113.             // サイドビューの場合
  114.             this.rearrangeEnemiesSV(members);

  115.         } else {

  116.             // フロントビューの場合
  117.             this.rearrangeEnemiesFV(members);

  118.         }

  119.         // 固有名(ABC...)をつける
  120.         this.makeUniqueNames();

  121.         // NUUN_BattleBGMが入っている場合はさらにBGM設定
  122.         if (typeof Game_Troop.prototype.battleBGMsetup == 'function') {

  123.             const bgm = this.battleBGMsetup();
  124.             $gameSystem.setBattleBgm(bgm);

  125.         }

  126.     };

  127.     Game_Troop.prototype.lotteryEnemyIds = function() {

  128.         // RandomEnemiesタグを見て敵IDを抽選し、
  129.         // dataEnemyオブジェクトの配列にして返す
  130.         const troopObjs = this.troop().members;
  131.         //console.log(troopObjs);
  132.         // -> {enemyId, x, y, hidden}の配列

  133.         let randomEnemyIds;
  134.         let enemyId;
  135.         let dEnemy;
  136.         let dEnemies = [];
  137.         for (let i = 0; i < troopObjs.length; i++) {

  138.             dEnemy = $dataEnemies[troopObjs[i].enemyId];
  139.             if (dEnemy.meta.RandomEnemy) {

  140.                 // タグ記載がある
  141.                 randomEnemyIds = dEnemy.meta.RandomEnemy.split(',');
  142.                 enemyId = randomEnemyIds[Math.randomInt(randomEnemyIds.length)];

  143.             } else {

  144.                 // タグ記載がない
  145.                 enemyId = troopObjs[i].enemyId;

  146.             }
  147.             //console.log(enemyId);

  148.             if (enemyId != 0) {

  149.                 dEnemy = $dataEnemies[enemyId];
  150.                 dEnemy.hidden = troopObjs[i].hidden;
  151.                 dEnemies.push(dEnemy);

  152.             }

  153.         }

  154.         return dEnemies;

  155.     };

  156.     Game_Troop.prototype.rearrangeEnemiesSV = function(dEnemies) {

  157.         // dataEnemyオブジェクトの配列を受け取って、
  158.         // それぞれの内容からランダムに配置を決めてXY座標を決めて
  159.         // this._enemies に追加する。

  160.         // 一旦内容をクリア
  161.         this._enemies = [];

  162.         // それぞれについて Game_Enemy を定義してメンバーに追加
  163.         let gEnemy;
  164.         let xy = {};
  165.         for (let i = 0; i < dEnemies.length; i++) {

  166.             // 画面内の適切な範囲でかつ、
  167.             // すでに座標が決まっている敵画像と重ならないようなXY座標を求める
  168.             xy = this.getCheckedRandomXY(dEnemies[i]);

  169.             gEnemy = new Game_Enemy(dEnemies[i].id, xy.x, xy.y);
  170.             if (dEnemies[i].hidden) {

  171.                 gEnemy.hide();

  172.             }

  173.             this._enemies.push(gEnemy);

  174.         }

  175.     };

  176.     Game_Troop.prototype.getCheckedRandomXY = function(dEnemy) {

  177.         let xy = {
  178.             x: getRandomX(dEnemy),
  179.             y: getRandomY(dEnemy),
  180.         };
  181.         //console.log(`${xy.x}, ${xy.y}`);

  182.         if (this.checkRandomXY(xy)) {

  183.             // OKならそのまま返す
  184.             //console.log('OK');
  185.             return xy;

  186.         } else {

  187.             // NGでも敵画像サイズが大きい場合はそのまま返す
  188.             if (boxWidth / 2 - enemyWidth(dEnemy) < 0) {
  189.                 return xy;
  190.             }

  191.             // それでもNGなら再抽選して返す
  192.             //console.log('NG');
  193.             return this.getCheckedRandomXY(dEnemy);

  194.         }

  195.     }

  196.     Game_Troop.prototype.checkRandomXY = function(xy) {

  197.         let gEnemy;
  198.         for (let i = 0; i < this._enemies.length; i++) {

  199.             gEnemy = this._enemies[i];
  200.             const x = Number(gEnemy._screenX);
  201.             const y = Number(gEnemy._screenY);
  202.             const id = gEnemy._enemyId;

  203.             const minX = x - enemyWidth($dataEnemies[id]) / 3;
  204.             const minY = y - enemyHeight($dataEnemies[id]) / 3;
  205.             const maxX = x + enemyWidth($dataEnemies[id]) / 3;
  206.             const maxY = y + enemyHeight($dataEnemies[id]) / 3;

  207.             //console.log(`minX: ${minX} <= x: ${xy.x} <= maxX: ${maxX}`);
  208.             //console.log(`minY: ${minY} <= y: ${xy.y} <= maxY: ${maxY}`);

  209.             if (minX <= xy.x && xy.x <= maxX
  210.              && minY <= xy.y && xy.y <= maxY) {

  211.                 return false;

  212.             }

  213.         }

  214.         return true;
  215.     }

  216.     function getRandomX(dEnemy) {

  217.         let randX = 0;

  218.         if (boxWidth / 2 - enemyWidth(dEnemy) < 0) {
  219.             // 画像の横幅が画面幅の半分を超える
  220.             randX = Math.randomInt((boxWidth - enemyWidth(dEnemy)) / 2) + enemyWidth(dEnemy) / 2;
  221.         } else {
  222.             // 戦闘画面左半分で画像がはみ出さない範囲でランダム
  223.             randX = Math.max(100, Math.randomInt(boxWidth / 2 - enemyWidth(dEnemy))) + enemyWidth(dEnemy); //randX = Math.max(0, Math.randomInt(boxWidth / 2 - enemyWidth(dEnemy))) + enemyWidth(dEnemy);
  224.         }


  225.         return randX;

  226.     }

  227.     function getRandomY(dEnemy) {

  228.         // ステータスウィンドウより上で、
  229.         // かつ戦闘背景2と重ならない範囲でランダム
  230.         const bswh = Window_Selectable.prototype.fittingHeight(4);
  231.         const battlebacks2Height = 200;
  232.         let randY = Math.randomInt(boxHeight - bswh - battlebacks2Height - enemyHeight(dEnemy) / 2);
  233.         randY += battlebacks2Height + enemyHeight(dEnemy) / 2;

  234.         //const randY = Math.max(0, Math.randomInt(boxHeight - bswh - enemyHeight(dEnemy))) + enemyHeight(dEnemy);

  235.         return randY;
  236.     }

  237.     Game_Troop.prototype.rearrangeEnemiesFV = function(dEnemies) {

  238.         // dataEnemyオブジェクトの配列を受け取って、
  239.         // それぞれの内容から均等になるようにX座標を決めて
  240.         // this._enemies に追加する。

  241.         // 一旦内容をクリア
  242.         this._enemies = [];

  243.         // 登場する敵の画像の横幅を把握する
  244.         let widths = [];
  245.         let totalWidth = 0;
  246.         for (let i = 0; i < dEnemies.length; i++) {

  247.             widths.push(enemyWidth(dEnemies[i]));
  248.             totalWidth += enemyWidth(dEnemies[i]);

  249.         }

  250.         // 左端空白[敵]minGap[敵]minGap...minGap[敵]minGap[敵]右端空白
  251.         // となるようにX座標を決める
  252.         const minGap = 24;
  253.         const sideGap = (boxWidth - totalWidth - minGap * (widths.length - 1)) / 2;
  254.         const bswh = Window_Selectable.prototype.fittingHeight(4);
  255.         let gEnemy;
  256.         let prevX;
  257.         let x;
  258.         const y = boxHeight - bswh;
  259.         for (let i = 0; i < dEnemies.length; i++) {

  260.             if (prevX) {

  261.                 // 左から2体め以降
  262.                 x = prevX + widths[i - 1] / 2 + minGap + widths[i] / 2;

  263.             } else {

  264.                 // 左端
  265.                 x = sideGap + widths[0] / 2;

  266.             }
  267.             prevX = x;

  268.             gEnemy = new Game_Enemy(dEnemies[i].id, x, y);
  269.             if (dEnemies[i].hidden) {

  270.                 gEnemy.hide();

  271.             }

  272.             this._enemies.push(gEnemy);
  273.         }
  274.     };

  275.     function enemyWidth(dEnemy) {

  276.         if (!dEnemy) return 0;

  277.         return Number(ImageManager.loadEnemy(dEnemy.battlerName).width);

  278.     }

  279.     function enemyHeight(dEnemy) {

  280.         if (!dEnemy) return 0;

  281.         return Number(ImageManager.loadEnemy(dEnemy.battlerName).height);

  282.     }

  283. })();
复制代码
回复

使用道具 举报

Lv2.观梦者

梦石
0
星屑
677
在线时间
115 小时
注册时间
2012-9-30
帖子
102
3
 楼主| 发表于 2022-11-27 09:01:50 | 只看该作者
古树旋律 发表于 2022-11-25 18:07
这是CSVN的随机敌人插件。根据你作品的分辨率设置好后,他会随机放置敌人的位置。
至于随机敌人,这个功能 ...

感谢大神,今晚我回去试试!
回复

使用道具 举报

Lv2.观梦者

梦石
0
星屑
382
在线时间
28 小时
注册时间
2022-5-23
帖子
18
4
发表于 2022-11-27 21:33:54 | 只看该作者
古树旋律 发表于 2022-11-25 18:07
这是CSVN的随机敌人插件。根据你作品的分辨率设置好后,他会随机放置敌人的位置。
至于随机敌人,这个功能 ...

报错了,无法运行,我只需要敌人按数量排序自动坐标,不需要随机敌人,能不能再改一下,因为跟我的角色做敌人的插件冲突了。
回复

使用道具 举报

Lv2.观梦者

梦石
0
星屑
382
在线时间
28 小时
注册时间
2022-5-23
帖子
18
5
发表于 2022-11-27 21:35:39 | 只看该作者
古树旋律 发表于 2022-11-25 18:07
这是CSVN的随机敌人插件。根据你作品的分辨率设置好后,他会随机放置敌人的位置。
至于随机敌人,这个功能 ...

报错ReferenceError PluginManagerEx is not defined
回复

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
7299
在线时间
475 小时
注册时间
2021-12-4
帖子
514
6
发表于 2022-11-28 17:26:44 | 只看该作者
wgr273wgr273 发表于 2022-11-27 21:35
报错ReferenceError PluginManagerEx is not defined

凡是这种报错都表示,本插件需要放在官方插件PluginCommonBase.js之后加载。
回复

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1746
在线时间
253 小时
注册时间
2020-9-15
帖子
115
7
发表于 2022-11-28 19:23:08 | 只看该作者
你要的是这个插件,你是作者网站,有介绍功能,使用方法。
https://newrpg.seesaa.net/article/475049887.html
回复

使用道具 举报

Lv2.观梦者

梦石
0
星屑
677
在线时间
115 小时
注册时间
2012-9-30
帖子
102
8
 楼主| 发表于 2022-11-29 08:32:01 | 只看该作者
wxh811211 发表于 2022-11-28 19:23
你要的是这个插件,你是作者网站,有介绍功能,使用方法。
https://newrpg.seesaa.net/article/475049887.h ...

这个网站下载不了插件呀,点插件时显示“无法访问此网站”,怎么下载?
回复

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1746
在线时间
253 小时
注册时间
2020-9-15
帖子
115
9
发表于 2022-11-29 10:14:01 | 只看该作者
这论坛不知道为什么也上传不了附件,你来MZ萌新交流群拿吧,QQ群312473198,是大佬们的群,我已经汉化了这个随机敌人放置插件.
是你要的插件的话,记得给奖赏啊.
回复

使用道具 举报

Lv2.观梦者

梦石
0
星屑
382
在线时间
28 小时
注册时间
2022-5-23
帖子
18
10
发表于 2022-11-29 22:47:30 | 只看该作者
wxh811211 发表于 2022-11-29 10:14
这论坛不知道为什么也上传不了附件,你来MZ萌新交流群拿吧,QQ群312473198,是大佬们的群,我已经汉化了这个随 ...

我早就加了这个群了,能不能告诉我具体是哪个插件,而且我想要的是敌人位置随机插件,不需要随机敌人,只需要排列敌人的位置坐标,分开排列好!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-26 22:02

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表