查看: 985|回复: 2

[有事请教] 怎么做那种敌人在特定视野内看到主角就追逐的效果啊

[复制链接]
梦石
0
星屑
324
在线时间
55 小时
注册时间
2021-2-27
回帖
14
发表于 2025-7-12 19:36:22 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
想做个类似以前那种只要看到主角就会冒感叹号然后追逐主人公的效果,踩地雷的模式还是太难绷了

花匠

梦石
64
星屑
16710
在线时间
4205 小时
注册时间
2016-6-17
回帖
1004

极短26获奖极短24参与开拓者

发表于 2025-7-12 20:18:18 | 显示全部楼层
可以看这个发布页https://reflector88.itch.io/proximity-sensor

这个插件可以让事件设定按面对方向的照格子、十字方向之类的检测玩家是否进入判定区域
作者是reflector88

[pre lang="js"]/*:
@target MZ
@plugindesc 计算距离和视线。
@author reflector88
@url https://reflector88.itch.io/
@help

"Proximity Sensor 1.3"
当有事件发生时,该插件会激活一个开关/自开关,以便
玩家。这对漫游敌人、隐身序列和陷阱非常有用。
还可选择方向和视线。

更新
-V1.1 添加了 "面对一条线 "功能
-V1.2 开关现在可以切换;兼容性得到改善
-V1.3 修正了与某些像素移动脚本一起使用时的崩溃问题
____________________________________________________________________________
配置
1. 打开事件命令窗口,选择 "插件命令

2. 选择要使用的接近类型:
"所有方向"- 检查所有方向。
"面向"- 仅检查事件面向的方向。
"Orthogonal Directions(正交方向)"- 仅在十字形中进行检查。
面向一条直线"--"面向 "和 "正交 "的组合。

3. 设置操作员和距离,以确定事件的视距
(例如,如果玩家距离小于 3 个方砖,则检查 "小于 3") 4.

4. 4. 设置开关和/或自开关,以便在事件接近时切换。

5. 在地图编辑器中设置区域 ID 和/或地形标签来表示障碍物。
____________________________________________________________________________

TERMS OF USE
This plugin is free to use in both commercial and non-commercial projects,
though please credit me.


@param Obstacle Region ID
@type number
@desc Regions with this ID will block line of sight.
@default 1

@param Obstacle Terrain Tag
@type number
@desc Terrain with this tag will block line of sight.
@default 1

@command Basic
@text All Directions
@desc Checks if this event is in proximity of the player.

    @arg Operator
    @type select
    @option less than @option less than or equal to @option equals @option greater than or equal to @option greater than
    @default less than or equal to
    @desc The comparison operator.

    @arg Distance
    @type number
    @default 3
    @desc The distance to be compared with the player's proximity to this event.

    @arg Self-Switch
    @type select
    @option 0 @option A @option B @option C @option D
    @default A
    @desc Switch is toggled if the proximity condition is fulfilled.

    @arg Switch
    @type switch
    @default 0
    @desc Switch is toggled if the proximity condition is fulfilled.

@command Facing
@text Facing
@desc Checks if this event is facing and in proximity of the player.

    @arg Operator
    @type select
    @option less than @option less than or equal to @option equals @option greater than or equal to @option greater than
    @default less than or equal to
    @desc The comparison operator.

    @arg Distance
    @type number
    @default 3
    @desc The distance to be compared with the player's proximity to this event.

    @arg Self-Switch
    @type select
    @option 0 @option A @option B @option C @option D
    @default A
    @desc Switch is toggled if the proximity condition is fulfilled.

    @arg Switch
    @type switch
    @default 0
    @desc Switch is toggled if the proximity condition is fulfilled.

@command Orthogonal
@text Orthogonal Directions
@desc Checks if this event is in proximity of and in line with the player.

    @arg Operator
    @type select
    @option less than @option less than or equal to @option equals @option greater than or equal to @option greater than
    @default less than or equal to
    @desc The comparison operator.

    @arg Distance
    @type number
    @default 3
    @desc The distance to be compared with the player's proximity to this event.

    @arg Self-Switch
    @type select
    @option 0 @option A @option B @option C @option D
    @default A
    @desc Switch is toggled if the proximity condition is fulfilled.

    @arg Switch
    @type switch
    @default 0
    @desc Switch is toggled if the proximity condition is fulfilled.

@command FacingLine
@text Facing in a Line
@desc Checks if this event is in proximity, in line, and facing the player.

    @arg Operator
    @type select
    @option less than @option less than or equal to @option equals @option greater than or equal to @option greater than
    @default less than or equal to
    @desc The comparison operator.

    @arg Distance
    @type number
    @default 3
    @desc The distance to be compared with the player's proximity to this event.

    @arg Self-Switch
    @type select
    @option 0 @option A @option B @option C @option D
    @default A
    @desc Switch is toggled if the proximity condition is fulfilled.

    @arg Switch
    @type switch
    @default 0
    @desc Switch is toggled if the proximity condition is fulfilled.
*/

(() => {
    'use strict';
    var r88 = r88 || {};
    r88.PS = r88.PS || {};
    r88.PS.parameters = PluginManager.parameters('r88_ProximitySensor');
    r88.PS.regionId = r88.PS.parameters["Obstacle Region ID"];
    r88.PS.terrainTag = r88.PS.parameters["Obstacle Terrain Tag"];

    function r88_isProx(args) {
        const playerX = $gamePlayer.x;
        const playerY = $gamePlayer.y;
        const eventX = $gameMap.event(this._eventId).x;
        const eventY = $gameMap.event(this._eventId).y;
        const operator = args['Operator'];
        const distance = args['Distance'];
        const proximity = (Math.sqrt(Math.pow(eventX - playerX, 2) +
            Math.pow(eventY - playerY, 2)));

        switch (operator) {
            case 'less than': return proximity < distance;
            case 'less than or equal to': return proximity <= distance;
            case 'equals': return proximity === distance;
            case 'greater than or equal to': return proximity >= distance;
            case 'greater than': return proximity > distance;
            default: return false;
        }
    }

    function r88_isFacing() {
        const dir = $gameMap.event(this._eventId).direction();
        const playerX = $gamePlayer.x;
        const playerY = $gamePlayer.y;
        const eventX = $gameMap.event(this._eventId).x;
        const eventY = $gameMap.event(this._eventId).y;

        if (dir == 2 && eventY < playerY || dir == 8 && eventY > playerY
            || dir == 4 && eventX > playerX || dir == 6 && eventX < playerX) {
            return true;
        } else {
            return false;
        }
    }

    function r88_isOrthogonal() {
        const playerX = $gamePlayer.x;
        const playerY = $gamePlayer.y;
        const eventX = $gameMap.event(this._eventId).x;
        const eventY = $gameMap.event(this._eventId).y;

        return playerX === eventX || playerY === eventY;
    }

    // Bresenham Algorithm for line of sight calculation
    function r88_inLineOfSight() {
        const tileCoords = [];
        const playerX = $gamePlayer.x;
        const playerY = $gamePlayer.y;
        const eventX = $gameMap.event(this._eventId).x;
        const eventY = $gameMap.event(this._eventId).y;
        const distanceX = Math.abs(playerX - eventX);
        const distanceY = Math.abs(playerY - eventY);
        const incrementX = (eventX < playerX) ? 1 : -1;
        const incrementY = (eventY < playerY) ? 1 : -1;
        let tileX = eventX;
        let tileY = eventY;
        let error = distanceX - distanceY;


        const hypotenuse = Math.sqrt(Math.pow(distanceX, 2) + Math.pow(distanceY, 2));
        let tileHypotenuse = Math.sqrt(Math.pow(tileX - eventX, 2) + Math.pow(tileY - eventY, 2));


        while (tileHypotenuse < hypotenuse) {
            tileCoords.push([tileX, tileY]);

            const error2 = 2 * error;
            if (error2 > -distanceY) {
                error -= distanceY;
                tileX += incrementX;
            }
            if (error2 < distanceX) {
                error += distanceX;
                tileY += incrementY;
            }

            tileHypotenuse = Math.sqrt(Math.pow(tileX - eventX, 2) + Math.pow(tileY - eventY, 2));
        }

        for (let i = 0; i < tileCoords.length; i++) {
            if ($gameMap.regionId(tileCoords[0], tileCoords[1]) == r88.PS.regionId ||
                $gameMap.terrainTag(tileCoords[0], tileCoords[1]) == r88.PS.terrainTag)
                return false;
        }
        return true;

    }

    function r88_FlipSwitch(args) {
        if (r88_inLineOfSight.call(this)) {

            if (args['Self-Switch'] !== '0') {
                $gameSelfSwitches.setValue([this._mapId, this._eventId,
                args['Self-Switch']], !$gameSelfSwitches.value([this._mapId, this._eventId,
                args['Self-Switch']]));
            }
            $gameSwitches.setValue(args['Switch'], !$gameSwitches.value(args['Switch']));
        }
    }

    // User-defined plugin commands
    function r88_basicProx(args) {
        if (r88_isProx.call(this, args)) {
            r88_FlipSwitch.call(this, args);
        }
    }

    function r88_facingProx(args) {
        if (r88_isProx.call(this, args) && r88_isFacing.call(this)) {
            r88_FlipSwitch.call(this, args);
        }
    }

    function r88_orthogonalProx(args) {
        if (r88_isProx.call(this, args) && r88_isOrthogonal.call(this)) {
            r88_FlipSwitch.call(this, args);
        }
    }

    function r88_facingLineProx(args) {
        if (r88_isProx.call(this, args) && r88_isFacing.call(this) && r88_isOrthogonal.call(this)) {
            r88_FlipSwitch.call(this, args);
        }
    }


    PluginManager.registerCommand("r88_ProximitySensor", "Basic", r88_basicProx);
    PluginManager.registerCommand("r88_ProximitySensor", "Facing", r88_facingProx);
    PluginManager.registerCommand("r88_ProximitySensor", "Orthogonal", r88_orthogonalProx);
    PluginManager.registerCommand("r88_ProximitySensor", "FacingLine", r88_facingLineProx);

})();[/pre]
回复 1 0

使用道具 举报

梦石
0
星屑
324
在线时间
55 小时
注册时间
2021-2-27
回帖
14
 楼主| 发表于 2025-7-12 22:30:14 | 显示全部楼层
Arfies 发表于 2025-7-12 20:18
可以看这个发布页https://reflector88.itch.io/proximity-sensor

这个插件可以让事件设定按面对方向的照格 ...

太好了,谢谢大佬QAQ
回复

使用道具 举报

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

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部