查看: 2291|回复: 2

[已经解决] 关于如何让"允许穿透"事件不能穿透指定事件

[复制链接]
梦石
0
星屑
841
在线时间
194 小时
注册时间
2014-1-11
回帖
19
发表于 2019-1-30 20:49:20 | 显示全部楼层 |阅读模式

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

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

×
楼主正在做一个ARPG,
在网上借了一个事件仓库的脚本,
但不知是不是这个脚本本身的原因还是脚本冲突,
每次设置事件位置或使一个复制的事件跳跃就有几率在原地留下一个隐形的事件(什么用都没有,角色自己也可以通过,但是事件无法通过它)
为了解决这个BUG,又去找了另一个区域通行的脚本
即事件只会在指定区域内通行,再给事件加上允许穿透
本来以为就这么解决了
然后发现原来我设置了一个技能是在原地放置一个不可通行的事件,,,,,
因为很有趣不想放弃这个技能,,,,,,,,,,,
但是因为怪都可以穿透了所以他们就可以无视这个事件穿过去,,,,,,,,,
所以现在我想寻求解决的办法,希望能给一些建议,以及以下是我自己找了半天也找不到的希望能解决这一问题的有关脚本,希望能提供一些帮助
1.设置指定坐标的区域设置
如果能够做到的话配合区域通行限制的脚本可以达到我想要的效果
2.设置指定事件无法被一般“允许穿透”的事件穿透
能想到最简单暴力的脚本,,

虽然很努力想学脚本但是光看帮助看了很多次都看不懂(到函数那里就彻底懵了),但是想做自己真正想要的游戏,,只用事件实在没有办法完成(也有可能是我智商不足),,想了一天实在不知道该怎么解决,脑子乱成一团,,拜托了!
[pre lang="ruby" line="1"]
=begin               

  事件管理器+事件复制功能
  
    2014/2/4   v1.2 添加复制事件保存功能
    2013/12/13 v1.1 bug 修正
  
  
  功能
  
  1. 优化默认脚本事件运行效率
  2. 可以从其它地图复制事件;删除事件等
  
  使用说明
  
  
  
  
  v1.2 新增      
  
  save_copy_events
  
    保存从其它地图复制过来的事件
  
  remove_all_copy_events
   
    移除该地图全部从其它地图复制过来的事件,保存的事件也删除
  
   
   
  v1.1
  
  
  copy_map_event(map_id, event_id, x, y)
  
    复制特定地图的特定事件 到坐标 x y
    如果 x y 坐标不填,事件就复制到原本的坐标
   
    例 copy_map_event(2, 1) # 复制地图2的事件1到它原本地图的坐标
       copy_map_event(3, 2, 0, 0) # 复制地图3的事件2到坐标(0,0)
  
  
  关于独立开关
  
    现在每个“复制事件”有各自的独立开关
    “复制事件”的独立开关优先级高于“源事件”的独立开关
    也就是说一旦通过“复制事件”操作独立开关,“源事件”的独立开关就不再
    对“复制事件”有效了
   
    要开/关“源事件”的某个独立开关可以用脚本
      $game_self_switch[[map_id, event_id, "A"]] = true / false
  
   
  remove_copy_event(map_id, event_id)
  
    移除从特定地图复制过来的事件,如果复制了多个则全部移除
    需要一个一个移除使用下面的方法
   
   
  remove_map_event(事件id)
  
    移除指定id的事件
    复制过来的事件id为 当前地图事件id最大值 + 1
  
=end

class Game_Event
attr_reader\
:copy_id,
:map_id

attr_accessor\
:copy_self_switch
  
  # 开始 >-------
  
  # 默认脚本距离屏幕比较远的事件是不会自主移动的
  
  # 这段脚本让全屏的事件都可以按照设置好的自身移动路线前进,如果静止的事件比较多会
  # 比较省资源。如果不需要这个功能,就删除 开始 ~ 结束 之间的脚本
  
  def update_self_movement
    if @stop_count > stop_count_threshold
      case @move_type
      when 1;  move_type_random
      when 2;  move_type_toward_player
      when 3;  move_type_custom
      end
    end
  end
  
  # 结束 -------<
  
  
  def event_copy_setup(id, x, y)
    @copy_id = @id
    @id = id
    moveto(x, y) if x && y
  end
  def update #覆盖
    super
    check_event_trigger_auto
    return unless @interpreter
    @interpreter.setup(@list, @id) unless @interpreter.running? #@event.id-@id
    @interpreter.update
  end
  def conditions_met?(page) #覆盖
    c = page.condition
    if c.switch1_valid
      return false unless $game_switches[c.switch1_id]
    end
    if c.switch2_valid
      return false unless $game_switches[c.switch2_id]
    end
    if c.variable_valid
      return false if $game_variables[c.variable_id] < c.variable_value
    end
    if c.self_switch_valid #改了这里
      return false unless @copy_self_switch ?
        @copy_self_switch[c.self_switch_ch] :
        $game_self_switches[[@map_id, @event.id, c.self_switch_ch]]
    end
    if c.item_valid
      item = $data_items[c.item_id]
      return false unless $game_party.has_item?(item)
    end
    if c.actor_valid
      actor = $game_actors[c.actor_id]
      return false unless $game_party.members.include?(actor)
    end
    return true
  end
  alias_method :sEventManager_init_public_members, :init_public_members
  def init_public_members #覆盖
    @gridding = $game_map.gridding
    sEventManager_init_public_members
  end
  def moveto(x, y) #修改父类方法
    gridding_remove
    super
    gridding_insert
  end
  def move_straight(d, turn_ok = true) #修改父类方法
    gridding_remove
    super
    gridding_insert
  end
  def move_diagonal(horz, vert) #修改父类方法
    gridding_remove
    super
    gridding_insert
  end
  def gridding_remove
    @gridding[@x][@y].delete(self)
  end
  def gridding_insert
    @gridding[@x][@y].push(self)
  end
  #
  def saved_copy_load
    @gridding = $game_map.gridding
    gridding_insert
  end
end

class Game_Map
attr_reader\
:copy_map_events,
:gridding

  def prepare_copy_event(event)
    @copy_map_events ||= {}
    @copy_map_events[event] = true
  end
  def prepare_remove_event(event)
    @copy_map_events ||= {}
    event.gridding_remove
    @copy_map_events[event] = false
  end
  alias_method :sEventManager_update_events, :update_events
  def update_events
    sEventManager_update_events
    if @copy_map_events
      delete_ids = []
      in_map = SceneManager.scene_is?(Scene_Map)
      @copy_map_events.each {|event, copy|
        if copy
          @events[event.id] = event
          SceneManager.scene.spriteset.add_event_sprite(event) if in_map
        else
          delete_ids.push(event.id)
          SceneManager.scene.spriteset.remove_event_sprite(event) if in_map
        end
      }
      delete_ids.each {|id| @events.delete(id)}
      @copy_map_events = nil
    end
  end
  alias_method :sEventManager_setup_events, :setup_events
  def setup_events
    @saved_copy_events ||= {}
    @gridding = Array.new(width + 1) { Array.new(height + 1) {[]} }
    sEventManager_setup_events
    load_saved_copy_events
  end
  #
  def refresh_tile_events #覆盖
  end
  def events_xy(x, y) #覆盖
    @gridding[x][y]
  end
  def events_xy_nt(x, y) #覆盖
    @gridding[x][y].select {|event| !event.through}
  end
  def tile_events_xy(x, y) #覆盖
    @gridding[x][y].select {|event| event.tile? && !event.through}
  end
  def event_id_xy(x, y) #覆盖
    list = events_xy(x, y)
    list.empty? ? 0 : list[0].id
  end
  # 保存复制的事件
  def save_copy_events
    copy_events = []
    @events.each_value {|event| copy_events.push(event) if event.copy_id}
    @saved_copy_events[@map_id] = copy_events
  end
  # 读取保存的复制事件
  def load_saved_copy_events
    saved_copy_events = @saved_copy_events[@map_id]
    saved_copy_events.each {|event|
      event.saved_copy_load
      @events[event.id] = event
    } if saved_copy_events
  end
  
   
  # 移除所有复制事件
  def remove_all_copy_events
    @events.each_value {|event|
      $game_map.prepare_remove_event(event) if event.copy_id
    }
    @saved_copy_events.delete @map_id
  end
end
# 事件页脚本添加复制事件功能
class Game_Interpreter
  def copy_map_event(map_id, event_id, x = nil, y = nil)
    map_filename = sprintf("Data/Map%03d.rvdata2", map_id)
    if File.exist?(map_filename)
      event = load_data(map_filename).events[event_id]
      if event
        event = Game_Event.new(map_id, event)
        event_id = $game_map.events.keys.max + 1
        event_id += $game_map.copy_map_events.size if $game_map.copy_map_events
        event.event_copy_setup(event_id, x, y)
        $game_map.prepare_copy_event(event)
      elsif $TEST
        msgbox("复制<地图#{map_id}>的<事件#{event_id}>失败,该事件不存在。")
        exit
      end
    elsif $TEST
      msgbox("从<地图#{map_id}>复制事件失败,该地图不存在。")
      exit
    end
  end
  #
  def save_copy_events
    $game_map.save_copy_events
  end
  def remove_all_copy_events
    $game_map.remove_all_copy_events
  end
  def remove_copy_event(map_id, event_id)
    $game_map.events.each_value {|event|
      if event.copy_id == event_id && event.map_id == map_id
        $game_map.prepare_remove_event(event)
      end
    }
  end
  def remove_map_event(event_id)
    event = $game_map.events[event_id]
    $game_map.prepare_remove_event(event) if event
  end
  #
  alias_method :sEventManager_command_123, :command_123
  def command_123
    if @event_id > 0
      event = get_character(@event_id)
      event.copy_id ?
        process_copy_self_switch(event) :
        sEventManager_command_123
    end
  end
  def process_copy_self_switch(event)
    event.copy_self_switch ||= {}
    event.copy_self_switch[@params[0]] = (@params[1] == 0)
    all_off = true
    event.copy_self_switch.each_value {|key| break all_off = false if key}
    event.copy_self_switch = nil if all_off
    $game_map.need_refresh = true
  end
end
#
# 精灵管理
class Spriteset_Map
  EventRadius = 1
  def add_event_sprite(event)
    @events_sprites[event] = nil
  end
  def remove_event_sprite(event)
    sprite = @events_sprites.delete(event)
    sprite.dispose if sprite
  end
  alias_method :sEventManager_create_characters, :create_characters
  def create_characters
    sEventManager_create_characters
    setup_event_sprites
  end
  def setup_event_sprites
    @events_sprites = {}
    @character_sprites.each {|sp|
      @events_sprites[sp.character] = sp if sp.character.class == Game_Event
    }
    @events_sprites.each_value {|sp| @character_sprites.delete(sp)}
  end
  alias_method :sEventManager_dispose_characters, :dispose_characters
  def dispose_characters
    @events_sprites.each_value {|sprite| sprite.dispose if sprite}
    sEventManager_dispose_characters
  end
  alias_method :sEventManager_update_characters, :update_characters
  def update_characters
    sEventManager_update_characters
    update_event_sprites
  end
  def update_event_sprites
    ox = $game_map.display_x - EventRadius
    ex = $game_map.display_x + Graphics.width / 32.0 + EventRadius - 1
    oy = $game_map.display_y - EventRadius
    ey = $game_map.display_y + Graphics.height / 32.0 + EventRadius - 0.875
    mw = $game_map.width
    mh = $game_map.height
    lv = $game_map.loop_vertical?
    lh = $game_map.loop_horizontal?
    @events_sprites.each {|event, sprite|
      x = event.real_x
      y = event.real_y
      if (x > ox && x < ex || lv && x + mw > ox && x + mw < ex) &&
         (y > oy && y < ey || lh && y + mh > oy && y + mh < ey)
        sprite ? sprite.update :
          @events_sprites[event] = Sprite_Character.new(@viewport1, event)
      elsif sprite
        sprite.dispose
        @events_sprites[event] = nil
      end
    }
  end
end
class Scene_Map
attr_reader :spriteset
end[/pre]
梦石
10
星屑
39550
在线时间
1919 小时
注册时间
2010-11-14
回帖
3214

R考场第七期纪念奖

发表于 2019-1-30 21:31:04 | 显示全部楼层
本帖最后由 KB.Driver 于 2019-1-30 21:41 编辑

[pre lang="ruby"]class Game_CharacterBase
  #--------------------------------------------------------------------------
  # ● [别名修改]判定是否可以通行(检查 地图的通行度 和 前方是否有路障)
  #--------------------------------------------------------------------------
  alias :passable_for_unpassable :passable?
  def passable?(x, y, d)
    x2 = $game_map.round_x_with_direction(x, d)
    y2 = $game_map.round_y_with_direction(y, d)
    return false if collide_with_unpassable_events?(x2, y2)
    passable_for_unpassable(x, y, d)
  end
  #--------------------------------------------------------------------------
  # ● [追加]判定是否与"<不可穿透>"事件碰撞
  #--------------------------------------------------------------------------
  def collide_with_unpassable_events?(x, y)
    $game_map.events_xy_nt(x, y).any?{|event| event.unpassable_event?}
  end
end

class Game_Event
  #--------------------------------------------------------------------------
  # ● [追加]是否<不可穿透>
  #--------------------------------------------------------------------------
  def unpassable_event?
    @list.any?{|cmd| cmd.code == 108 && cmd.parameters[0].index("<不可穿透>")}
  end
end[/pre]

新建工程测试通过,有问题请报告。
使用方法:在不想被穿透的事件中增加注释,注释里写<不可穿透>

点评

十分感谢!成功了  发表于 2019-1-30 22:45

评分

参与人数 2星屑 +50 赞 +1 收起 理由
VIPArcher + 50 认可答案
苏达罗 + 1

查看全部评分

用头画头像,用脚写脚本
回复

使用道具 举报

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

本版积分规则

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

在本版发帖返回顶部