查看: 13516|回复: 26

[原创发布] 全方向 像素移动

[复制链接]
梦石
0
星屑
2270
在线时间
125 小时
注册时间
2015-8-14
回帖
17
发表于 2015-8-14 11:02:18 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 Hello``Bubble 于 2015-8-18 08:55 编辑

[fold=说明]事件指令“禁止斜触发”,用来制作传送,门,宝箱等事件。
使用时,在当前执行的事件页中的“任意”位置加入注释“禁止斜触发”即可。
PS  将移动处理、事件刷新、player刷新等方法,使用alias以提高兼容性。

其实就是让角色一次走半格,支持八方向。
rgss1默认走(默认关闭)
  1. $game_temp.rgss_move = true# 默认走
  2. $game_temp.dir_4 = true# 四方向走
复制代码
半格走(默认开启)
  1. $game_temp.rgss_move = false# 半格走
  2. $game_temp.dir_4 = false# 八方向走
复制代码
[/fold][fold=半格移动截图(4图)] 半格走01.jpg
半格走02.jpg
半格走03.jpg
半格走04.jpg [/fold]
[fold=触发截图(11图)]柜台
柜台01.jpg
柜台02.jpg
柜台03.jpg
柜台04.jpg
一般
触发01.jpg
触发02.jpg
触发03.jpg
触发04.jpg
触发05.jpg
触发06.jpg
触发07.jpg [/fold]
[fold=脚本][pre lang="ruby"]class Game_Temp
  attr_accessor :rgss_move, :dir_4
  #alias rgss_initialize_xxxxxxxxx initialize  默认值???
  #def initialize
  #  rgss_initialize_xxxxxxxxx
  #  @rgss_move = false
  #  @dir_4 = false
  #end
end
class Game_Event < Game_Character
  attr_reader :touch_4
  alias rgss_refresh refresh
  def refresh
    rgss_refresh
    @touch_4 = nil
    for list in @page.list
      if list.code == 108 or list.code == 408
        if list.parameters[0] =~ /禁止斜触发/
          @touch_4 = true
          break
        end
      end
    end
  end
end
class Game_Player < Game_Character
  def x(f=nil)
    return !f ? @x.to_i : @x
  end
  def y(f=nil)
    return !f ? @y.to_i : @y
  end
  def to_i
    @x = @x.to_i if @x.is_a?(Float)
    @y = @y.to_i if @y.is_a?(Float)
  end
  def player_passable?(dir = @direction, px = @x, py = @y)
    case dir
    when 8
      (py - 0.5).to_i == py.to_i or (passable?(px.to_i, py.to_i, 8) and
      passable?((px + 0.5).to_i, py.to_i, 8))
    when 2
      passable?(px.to_i, py.to_i, 2) and
      passable?((px + 0.5).to_i, py.to_i, 2)
    when 4
      (px - 0.5).to_i == px.to_i or (passable?(px.to_i, py.to_i, 4) and
      passable?(px.to_i, (py + 0.5).to_i, 4))
    when 6
      passable?(px.to_i, py.to_i, 6) and
      passable?(px.to_i, (py + 0.5).to_i, 6)
    when 1
      (player_passable?(4) and player_passable?(2, @x - 0.5)) or
      (player_passable?(2) and player_passable?(4, @x, @y + 0.5))
    when 3
      (player_passable?(6) and player_passable?(2, @x + 0.5)) or
      (player_passable?(2) and player_passable?(6, @x, @y + 0.5))
    when 7
      (player_passable?(4) and player_passable?(8, @x - 0.5)) or
      (player_passable?(8) and player_passable?(4, @x, @y - 0.5))
    when 9
      (player_passable?(6) and player_passable?(8, @x + 0.5)) or
      (player_passable?(8) and player_passable?(6, @x, @y - 0.5))
    end
  end
  #--------------------------------------------------------------------------
  # ● 接触事件启动判定
  #--------------------------------------------------------------------------
  def check_event_trigger_touch(x, y)
    result = false
    # 事件执行中的情况下
    if $game_system.map_interpreter.running?
      return result
    end
    # 全事件的循环
    for event in $game_map.events.values
      if event.touch_4
        if (x - 0.5).to_i == x.to_i or
          (y - 0.5).to_i == y.to_i
          next
        end
      end
      # 事件坐标与目标一致的情况下
      if event.x == x.to_i and event.y == y.to_i and [1,2].include?(event.trigger)
        # 跳跃中以外的情况下、启动判定是正面的事件
        if not event.jumping? and not event.over_trigger?
          event.start
          result = true
        end
      end
    end
    return result
  end
  def player_check_event_trigger_touch(dir)
    case dir
    when 8
      check_event_trigger_touch(@x, @y - 1)
      if (@x + 0.5).to_i != @x.to_i
        check_event_trigger_touch(@x + 1, @y - 1)
      end
    when 2
      check_event_trigger_touch(@x, @y + 1)
      if (@x + 0.5).to_i != @x.to_i
        check_event_trigger_touch(@x + 1, @y + 1)
      end
    when 4
      check_event_trigger_touch(@x - 1, @y)
      if (@y + 0.5).to_i != @y.to_i
        check_event_trigger_touch(@x - 1, @y + 1)
      end
    when 6
      check_event_trigger_touch(@x + 1, @y)
      if (@y + 0.5).to_i != @y.to_i
        check_event_trigger_touch(@x + 1, @y + 1)
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 同位置的事件启动判定
  #--------------------------------------------------------------------------
  def check_event_trigger_here(triggers)
    result = false
    # 事件执行中的情况下
    if $game_system.map_interpreter.running?
      return result
    end
    # 全部事件的循环
    for event in $game_map.events.values
      # 事件坐标与目标一致的情况下
      if triggers.include?(event.trigger) and
        ((event.x == @x.to_i and event.y == @y.to_i) or
        (!event.touch_4 and event.x == (@x + 0.5).to_i and event.y == @y.to_i) or
        (!event.touch_4 and event.x == @x.to_i and event.y == (@y + 0.5).to_i))
        # 跳跃中以外的情况下、启动判定是同位置的事件
        if not event.jumping? and event.over_trigger?
          event.start
          result = true
        end
      end
    end
    return result
  end
  #--------------------------------------------------------------------------
  # ● 正面事件的启动判定
  #--------------------------------------------------------------------------
  def check_event_trigger_there(triggers)
    result = false
    # 事件执行中的情况下
    if $game_system.map_interpreter.running?
      return result
    end
    # 计算正面坐标
    new_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
    new_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
    # 全部事件的循环
    for event in $game_map.events.values
      if event.touch_4
        if (new_x - 0.5).to_i == new_x.to_i or
          (new_y - 0.5).to_i == new_y.to_i
          next
        end
      end
      # 事件坐标与目标一致的情况下
      if !player_passable? and triggers.include?(event.trigger) and
         ((event.x == new_x.to_i and event.y == new_y.to_i) or
          (!event.touch_4 and event.x == (new_x + 0.5).to_i and event.y == new_y.to_i) or
          (!event.touch_4 and event.x == new_x.to_i and event.y == (new_y + 0.5).to_i))
        # 跳跃中以外的情况下、启动判定是正面的事件
        if not event.jumping? and not event.over_trigger?
          event.start
          result = true
        end
      end
    end
    # 找不到符合条件的事件的情况下
    if result == false
      # 正面的元件是柜台的情况下
      if $game_map.counter?(new_x, new_y)
        # 计算 1 元件里侧的坐标
        new_x += (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
        new_y += (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
        # 全事件的循环
        for event in $game_map.events.values
          if event.touch_4
            if (new_x - 0.5).to_i == new_x.to_i or
              (new_y - 0.5).to_i == new_y.to_i
              next
            end
          end
          # 事件坐标与目标一致的情况下
          if triggers.include?(event.trigger) and
            ((event.x == new_x.to_i and event.y == new_y.to_i) or
            (!event.touch_4 and event.x == (new_x + 0.5).to_i and event.y == new_y.to_i) or
            (!event.touch_4 and event.x == new_x.to_i and event.y == (new_y + 0.5).to_i))
            # 跳跃中以外的情况下、启动判定是正面的事件
            if not event.jumping? and not event.over_trigger?
              event.start
              result = true
            end
          end
        end
      end
    end
    return result
  end
  #--------------------------------------------------------------------------
  # ● 向上移动
  #     turn_enabled : 本场地位置更改许可标志
  #--------------------------------------------------------------------------
  def move_up(turn_enabled = true)
    if $game_temp.rgss_move then
      to_i ; super ; return
    end
    # 面向上
    if turn_enabled
      turn_up
    end
    # 可以通行的情况下
    if player_passable?(8)
      # 面向上
      turn_up
      # 更新坐标
      @y -= 0.5
      # 歩数増加
      increase_steps
    # 不能通行的情况下
    else
      # 接触事件的启动判定
      player_check_event_trigger_touch(8)
    end
  end
  #--------------------------------------------------------------------------
  # ● 向下移动
  #     turn_enabled : 本场地位置更改许可标志
  #--------------------------------------------------------------------------
  def move_down(turn_enabled = true)
    if $game_temp.rgss_move then
      to_i ; super ; return
    end
    # 面向下
    if turn_enabled
      turn_down
    end
    # 可以通行的场合
    if player_passable?(2)
      # 面向下
      turn_down
      # 更新坐标
      @y += 0.5
      # 增加步数
      increase_steps
    # 不能通行的情况下
    else
      # 接触事件的启动判定
      player_check_event_trigger_touch(2)
    end
  end
  #--------------------------------------------------------------------------
  # ● 向左移动
  #     turn_enabled : 本场地位置更改许可标志
  #--------------------------------------------------------------------------
  def move_left(turn_enabled = true)
    if $game_temp.rgss_move then
      to_i ; super ; return
    end
    # 面向左
    if turn_enabled
      turn_left
    end
    # 可以通行的情况下
    if player_passable?(4)
      # 面向左
      turn_left
      # 更新坐标
      @x -= 0.5
      # 增加步数
      increase_steps
    # 不能通行的情况下
    else
      # 接触事件的启动判定
      player_check_event_trigger_touch(4)
    end
  end
  #--------------------------------------------------------------------------
  # ● 向右移动
  #     turn_enabled : 本场地位置更改许可标志
  #--------------------------------------------------------------------------
  def move_right(turn_enabled = true)
    if $game_temp.rgss_move then
      to_i ; super ; return
    end
    # 面向右
    if turn_enabled
      turn_right
    end
    # 可以通行的场合
    if player_passable?(6)
      # 面向右
      turn_right
      # 更新坐标
      @x += 0.5
      # 增加步数
      increase_steps
    # 不能通行的情况下
    else
      # 接触事件的启动判定
      player_check_event_trigger_touch(6)
    end
  end
  #--------------------------------------------------------------------------
  # ● 向左下移动
  #--------------------------------------------------------------------------
  def move_lower_left
    if $game_temp.rgss_move then
      to_i ; super ; return
    end
    # 没有固定面向的场合
    unless @direction_fix
      # 朝向是右的情况下适合的面是左面、朝向是上的情况下适合的面是下面
      @direction = (@direction == 6 ? 4 : @direction == 8 ? 2 : @direction)
    end
    # 下→左、左→下 的通道可以通行的情况下
    if player_passable?(1)
      # 更新坐标
      @x -= 0.5
      @y += 0.5
      # 增加步数
      increase_steps
    end
  end
  #--------------------------------------------------------------------------
  # ● 向右下移动
  #--------------------------------------------------------------------------
  def move_lower_right
    if $game_temp.rgss_move then
      to_i ; super ; return
    end
    # 没有固定面向的场合
    unless @direction_fix
      # 朝向是右的情况下适合的面是左面、朝向是上的情况下适合的面是下面
      @direction = (@direction == 4 ? 6 : @direction == 8 ? 2 : @direction)
    end
    # 下→右、右→下 的通道可以通行的情况下
    if player_passable?(3)
      # 更新坐标
      @x += 0.5
      @y += 0.5
      # 增加步数
      increase_steps
    end
  end
  #--------------------------------------------------------------------------
  # ● 向左上移动
  #--------------------------------------------------------------------------
  def move_upper_left
    if $game_temp.rgss_move then
      to_i ; super ; return
    end
    # 没有固定面向的场合
    unless @direction_fix
      # 朝向是右的情况下适合的面是左面、朝向是上的情况下适合的面是下面
      @direction = (@direction == 6 ? 4 : @direction == 2 ? 8 : @direction)
    end
    # 上→左、左→上 的通道可以通行的情况下
    if player_passable?(7)
      # 更新坐标
      @x -= 0.5
      @y -= 0.5
      # 增加步数
      increase_steps
    end
  end
  #--------------------------------------------------------------------------
  # ● 向右上移动
  #--------------------------------------------------------------------------
  def move_upper_right
    if $game_temp.rgss_move then
      to_i ; super ; return
    end
    # 没有固定面向的场合
    unless @direction_fix
      # 朝向是右的情况下适合的面是左面、朝向是上的情况下适合的面是下面
      @direction = (@direction == 4 ? 6 : @direction == 2 ? 8 : @direction)
    end
    # 上→右、右→上 的通道可以通行的情况下
    if player_passable?(9)
      # 更新坐标
      @x += 0.5
      @y -= 0.5
      # 增加步数
      increase_steps
    end
  end
  #--------------------------------------------------------------------------
  # ● 画面更新
  #--------------------------------------------------------------------------
  alias rgss_update update
  def update
    if $game_temp.dir_4
      rgss_update
      return
    end
    # 本地变量记录移动信息
    last_moving = moving?
    # 移动中、事件执行中、强制移动路线中、
    # 信息窗口一个也不显示的时候
    unless moving? or $game_system.map_interpreter.running? or
           @move_route_forcing or $game_temp.message_window_showing
      # 如果方向键被按下、主角就朝那个方向移动
      case Input.dir8
      when 1
        move_lower_left
      when 2
        move_down
      when 3
        move_lower_right
      when 4
        move_left
      when 6
        move_right
      when 7
        move_upper_left
      when 8
        move_up
      when 9
        move_upper_right
      end
    end
    # 本地变量记忆坐标
    last_real_x = @real_x
    last_real_y = @real_y
    super
    # 角色向下移动、画面上的位置在中央下方的情况下
    if @real_y > last_real_y and @real_y - $game_map.display_y > CENTER_Y
      # 画面向下卷动
      $game_map.scroll_down(@real_y - last_real_y)
    end
    # 角色向左移动、画面上的位置在中央左方的情况下
    if @real_x < last_real_x and @real_x - $game_map.display_x < CENTER_X
      # 画面向左卷动
      $game_map.scroll_left(last_real_x - @real_x)
    end
    # 角色向右移动、画面上的位置在中央右方的情况下
    if @real_x > last_real_x and @real_x - $game_map.display_x > CENTER_X
      # 画面向右卷动
      $game_map.scroll_right(@real_x - last_real_x)
    end
    # 角色向上移动、画面上的位置在中央上方的情况下
    if @real_y < last_real_y and @real_y - $game_map.display_y < CENTER_Y
      # 画面向上卷动
      $game_map.scroll_up(last_real_y - @real_y)
    end
    # 不在移动中的情况下
    unless moving?
      # 上次主角移动中的情况
      if last_moving
        # 与同位置的事件接触就判定为事件启动
        result = check_event_trigger_here([1,2])
        # 没有可以启动的事件的情况下
        if result == false
          # 调试模式为 ON 并且按下 CTRL 键的情况下除外
          unless $DEBUG and Input.press?(Input::CTRL)
            # 遇敌计数下降
            if @encounter_count > 0
              @encounter_count -= 1
            end
          end
        end
      end
      # 按下 C 键的情况下
      if Input.trigger?(Input::C)
        # 判定为同位置以及正面的事件启动
        check_event_trigger_here([0])
        check_event_trigger_there([0,1,2])
      end
    end
  end
end[/pre][/fold]
[fold=附件]完整基础版
像素移动 基础版.zip (231.03 KB, 下载次数: 185)
更完整的斜向触发判断
像素移动 更完整斜触发.zip (231.21 KB, 下载次数: 273) [/fold]

评分

参与人数 4星屑 +200 赞 +1 收起 理由
龙夫三拳tan + 1 塞糖
RyanBern + 100 精品文章+图书馆收录
·雾逝者· + 70 GJ
imsy + 30 塞糖

查看全部评分

梦石
0
星屑
290
在线时间
3599 小时
注册时间
2012-2-29
回帖
3320

黄金编剧

发表于 2015-8-15 11:16:35 | 显示全部楼层
{:2_270:}使用状况反馈——
左上、左下、右下这三组键每当有一组被同时按下,C键(包括其他可触发事件的按键)将失效
{:2_249:}不知LZ可有解决的方法?如能提供,感激不尽

点评

简单修改了下,兼容四方向图(如果是八方向图还要再修改下<其实就是把4方向图判断条件分开而已>)  发表于 2015-8-15 23:02
简化 高效 简约 便捷,为用户体验而思考。
回复

使用道具 举报

梦石
7
星屑
655
在线时间
131 小时
注册时间
2011-5-12
回帖
120
发表于 2018-5-28 19:57:16 | 显示全部楼层
不知道这算不算挖坟qwq
我尝试使用了这个脚本,但无论在我的哪个游戏中,都会打开游戏瞬间报错

脚本''的16行发生了NoMehtodError。
undefined method 'list' for nil:NilClass

我尝试把主角的出生点丢到别的地图去,又可以运行了,但把原本那个地图的事件搬过来以后还是会报错。

而且似乎有任何 自动处理 的事件在运行时,它就会报错,目前因为不知道这里的 list 是指什么,所以不知如何处理qwq

点评

请选择性放弃,我试过,冲突太多作者又不在了……好吧是未持续提供技术支持。这种脚本请慎重使用。  发表于 2018-6-1 10:22
回复 1 0

使用道具 举报

梦石
0
星屑
9716
在线时间
2775 小时
注册时间
2008-9-5
回帖
3458

开拓者短篇八RM组冠军短篇九导演组亚军白银编剧

发表于 2018-6-1 13:38:17 | 显示全部楼层
龙夫三拳tan 发表于 2018-5-28 19:57
不知道这算不算挖坟qwq
我尝试使用了这个脚本,但无论在我的哪个游戏中,都会打开游戏瞬间报错

在15行和16行之间插入一句
  1. return if @page.nil?
复制代码

评分

参与人数 1赞 +1 收起 理由
89444640 + 1 我很赞同

查看全部评分

回复

使用道具 举报

梦石
0
星屑
35248
在线时间
4171 小时
注册时间
2007-12-15
回帖
9489
发表于 2018-6-1 13:59:42 | 显示全部楼层
cinderelmini 发表于 2018-6-1 13:38
在15行和16行之间插入一句


试了一下,成功了,
原来我也因为这个跳出直接把此脚本定义为不能用。
但是脚本有个严重缺陷,没有开关控制,脚本一直在生效,造成影响ACT那段模拟的基础操作,请问有办法增加个开关,在不需要的时候关闭吗?
回复

使用道具 举报

梦石
0
星屑
42235
在线时间
6017 小时
注册时间
2006-11-10
回帖
6966
发表于 2018-6-1 15:08:19 | 显示全部楼层
本帖最后由 灯笼菜刀王 于 2018-6-1 15:10 编辑
89444640 发表于 2018-6-1 13:59
试了一下,成功了,
原来我也因为这个跳出直接把此脚本定义为不能用。
但是脚本有个严重缺陷,没有开关控 ...


其实作者已经提供开关了,而且人家第一行就说了~~

看不懂的话

插入下面的插件, 然后事件脚本里写  走半格  走默认  走四方  走八方  这样就会用了吧=。=

  1. class Interpreter
  2.    def 走半格
  3.       $game_temp.rgss_move = false
  4.   end
  5.   def 走默认
  6.       $game_temp.rgss_move = true
  7.   end
  8.   def 走四方
  9.      $game_temp.dir_4 = true
  10. end
  11. def 走八方
  12.     $game_temp.dir_4 = false
  13. end
  14. end
复制代码


点评

各种跳出- -b准是我复制哪里错了,还是算了,至少不乱加现在能正常运行,加了反而异常了  发表于 2018-6-1 16:51
然后找到game player 的 def update 这句,塞到下面去  发表于 2018-6-1 16:45
空格键加速那个,复制到哪里?  发表于 2018-6-1 16:44
所以官方这回出了个横版卷轴ACT游戏制作大师~,默认素材大小的对话必须给对准了位置,所以默认方式还是挺靠谱的,超过默认的全得执行设置事件位  发表于 2018-6-1 16:43
按键加速你还是把它整合到默认里吧,省得动不动就给你罢工,把那个脚本 unless 到 # 呼び戻す 之前那段复制下来,  发表于 2018-6-1 16:43
回复

使用道具 举报

梦石
0
星屑
9716
在线时间
2775 小时
注册时间
2008-9-5
回帖
3458

开拓者短篇八RM组冠军短篇九导演组亚军白银编剧

发表于 2018-6-1 15:15:19 | 显示全部楼层
89444640 发表于 2018-6-1 13:59
试了一下,成功了,
原来我也因为这个跳出直接把此脚本定义为不能用。
但是脚本有个严重缺陷,没有开关控 ...

脚本自带开关来着,我下的是那个完整斜移动的附件包,
那个工程的脚本前边把Game_Temp里新定义变量初始化的代码注释掉了,
需要初始化的话就把那些#删掉,就跟1楼的说明那样,不需要8方向的话就把dir4改成true,
默认关闭这个走半格的话,就把rgss_move改成true。
然后,在游戏里要用默认移动的时候就用【脚本】输入:
  1. $game_temp.rgss_move = true
复制代码

要用走半格的时候就用【脚本】输入:
  1. $game_temp.rgss_move = nil # 至于为什么不是false而是nil呢~~你猜~~
复制代码

四方向和8方向的更替也是一样的操作,上边两个脚本的rgss_move改成dir4就行了。

PS:由于作者把操控变量写在Game_Temp里了,所以这个开关状态不会保存在存档里。

点评

非常感谢耐心详细的解释,一会慢慢测试。刚才试了一下默认地图的,走起来手感顺溜多了。还需要慢慢试明雷、NPC对话、重力脚本兼容性  发表于 2018-6-1 15:49
回复

使用道具 举报

梦石
7
星屑
655
在线时间
131 小时
注册时间
2011-5-12
回帖
120
发表于 2018-6-13 15:49:18 | 显示全部楼层
cinderelmini 发表于 2018-6-1 13:38
在15行和16行之间插入一句

谢谢~不过我这边已经解决了
我尝试性在报错那个地方前面加上 if list != nil 问题就解决了,似乎只在个别场景里,会找不到list的值。

点评

准确的说是某(些)个事件当前没有满足出现条件的事件页,于是变量@page的值就是个nil,于是就导致无法调用.list方法啦~  发表于 2018-6-14 14:09
回复

使用道具 举报

梦石
0
星屑
301
在线时间
149 小时
注册时间
2012-8-26
回帖
37
发表于 2020-8-30 14:22:13 | 显示全部楼层
想请问大家,如果我要事件(不是主角)移动的时候走半格时应该怎么设置。
试了事件页插入脚本、注释啥的,好像没用。
挖坟贴
回复

使用道具 举报

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

本版积分规则

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

在本版发帖返回顶部