查看: 3113|回复: 1

[VIPArcher] 【八方向移动】

[复制链接]

无限の剣制

梦石
0
星屑
10445
在线时间
5019 小时
注册时间
2013-2-28
回帖
4942

开拓者贵宾

发表于 2014-11-2 00:19:39 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 VIPArcher 于 2018-12-12 05:27 编辑

[pre lang="ruby" line="1"]#===============================================================================
# ■ 八向移动待机行走图动画扩展
# by :VIPArcher [email: VIPArcher@sina.com]
#  -- https://viparcher.github.io/Hexo/2018/12/12/dir8_anime/
#  -- Project1 论坛:https://rpg.blue/ 使用或转载请保留以上信息。
#==============================================================================
# ■ 使用说明:
#   行走图素材文件名最前面添加 '@' 符号视为该角色/事件使用八方向行走图
#   需为其配置对应的其他形态的行走图文件,文件名后缀规则请看设定部分
#     例如  $@Actor1.png / @Actor1.png
#   文件名中带上 [f帧数#默认帧] 来控制行走图动画的帧数和停下时使用的帧
#     例如  $@Actor[f8#4].png / @Actor1[f8#4].png
#   事件也要使用待机动画需要在事件页(当前页)中备注上 <idle_anime>
#   事件的移动速度超过 5 则使用奔跑行走图
#==============================================================================
$VIPArcherScript ||= {};$VIPArcherScript[:dir8_anime] = 20181212
#==============================================================================
# ★ 设定部分 ★
#==============================================================================
module VIPArcher end
module VIPArcher::DIR8_ANIME
  # 配置开始
  DIR8_OFF_SW   = 0  # 控制关闭八方向行走的开关
  IDLE_ANIME_SW = 0  # 控制关闭待机动画的开关
  DASH_ANIME_SW = 0  # 控制关闭奔跑动画的开关
  IDLE_TIME   = 120  # 静止后进入待机动画的时间(帧)
  RIDLE_TIME  = 120  # 待机等待时间浮动值(上下浮动该值一半) 默认即 120 - 360 帧
  ANIME_TIME  = 240  # 待机动画播放的时长(帧)
  GAP_TIME    = 120  # 两次待机动画之间的时间间隔
  IDLE_NOTE   = '<idle_anime>' # 事件使用待机动画的备注
  DASH4_AFFIX = '_DASH'    # 奔跑普通行走图后缀
  IDLE4_AFFIX = '_IDLE'    # 待机普通行走图后缀
  DIRE8_AFFIX = '_8D'      # 普通斜向行走图后缀
  DASH8_AFFIX = '_DASH_8D' # 奔跑斜向行走图后缀(该条仅参考命名,没有实际作用)
  IDLE8_AFFIX = '_IDLE_8D' # 待机斜向行走图后缀(该条仅参考命名,没有实际作用)
  # 配置结束
  #--------------------------------------------------------------------------
  # ● 判断是否多帧
  #--------------------------------------------------------------------------
  def is_multi_frames?
    character_name =~ /\[f\d+#?\d*\]/i
  end
  #--------------------------------------------------------------------------
  # ● 获取帧数
  #--------------------------------------------------------------------------
  def get_frame(character_name)
    character_name =~ /\[f(\d+)#?\d*\]/i ? $1.to_i : 4
  end
  #--------------------------------------------------------------------------
  # ● 获取原图案(静止时矫正帧)
  #--------------------------------------------------------------------------
  def get_halt_name(character_name)
    character_name =~ /\[f\d+#(\d+)\]/i ? $1.to_i : 1
  end
end
#==============================================================================
# ■ Game_Player
#==============================================================================
class Game_Player
  include VIPArcher::DIR8_ANIME
  #--------------------------------------------------------------------------
  # ● 由方向键移动
  #--------------------------------------------------------------------------
  def move_by_input
    return if !movable? || $game_map.interpreter.running?
    if [1, 3, 7, 9].include?(Input.dir8)
      case Input.dir8
      when 1 then move_diagonal(4, 2)
      when 3 then move_diagonal(6, 2)
      when 7 then move_diagonal(4, 8)
      when 9 then move_diagonal(6, 8)
      end; return if @move_succeed
    end unless $game_switches[DIR8_OFF_SW]
    move_straight(Input.dir4) if Input.dir4 > 0
  end
  #--------------------------------------------------------------------------
  # ● 是否奔跑中
  #--------------------------------------------------------------------------
  def is_dash?
    return dash? && @stop_count.zero?
  end
  #--------------------------------------------------------------------------
  # ● 刷新
  #--------------------------------------------------------------------------
  alias set_frame_refresh refresh
  def refresh
    set_frame_refresh
    @frame = get_frame(@character_name)
    @original_pattern = get_halt_name(@character_name)
  end
end
class Game_Follower
  #--------------------------------------------------------------------------
  # ● 是否奔跑中
  #--------------------------------------------------------------------------
  def is_dash?
    $game_player.is_dash?
  end
  #--------------------------------------------------------------------------
  # ● 刷新
  #--------------------------------------------------------------------------
  alias set_frame_refresh refresh
  def refresh
    set_frame_refresh
    @frame = get_frame(@character_name)
    @original_pattern = get_halt_name(@character_name)
  end
  #--------------------------------------------------------------------------
  # ● 更新画面
  # * 使队员待机动画不同步,没用alias,如有冲突,请把该脚本放置被冲突脚本上面
  #--------------------------------------------------------------------------
  def update
    @move_speed     = $game_player.real_move_speed
    @transparent    = $game_player.transparent
    @walk_anime     = $game_player.walk_anime
    @step_anime     = @step_anime  #踏步属性不继承队伍
    @direction_fix  = $game_player.direction_fix
    @opacity        = $game_player.opacity
    @blend_type     = $game_player.blend_type
    super
  end
end
class Game_Event
  #--------------------------------------------------------------------------
  # ● 是否奔跑中
  #--------------------------------------------------------------------------
  def is_dash?
    return !@locked && @move_speed >= 5 && @stop_count.zero?
  end
  #--------------------------------------------------------------------------
  # ● 是否待机动画
  #--------------------------------------------------------------------------
  def idle_anime?
    @list.each do |command|
      if [108, 408].include?(command.code)
        return @idle_anime if command.parameters.any? do |line|
          line =~ /#{IDLE_NOTE}/i
        end
      end
    end if @list
    return false
  end
  #--------------------------------------------------------------------------
  # ● 刷新
  #--------------------------------------------------------------------------
  alias set_frame_setup_page_settings setup_page_settings
  def setup_page_settings
    set_frame_setup_page_settings
    @frame = get_frame(@character_name)
    @original_pattern = get_halt_name(@character_name)
  end
end
#==============================================================================
# ■ Game_CharacterBase
#==============================================================================
class Game_CharacterBase
  include VIPArcher::DIR8_ANIME
  attr_reader :frame
  attr_reader :static_anime
  attr_accessor :idle_anime
  #--------------------------------------------------------------------------
  # ● 更新画面
  #--------------------------------------------------------------------------
  alias dir8_update update
  def update
    dir8_update
    return if $game_switches[IDLE_ANIME_SW]
    return unless idle_anime?
    @step_anime = update_static_anime
  end
  #--------------------------------------------------------------------------
  # ● 更新待机动画
  #--------------------------------------------------------------------------
  def update_static_anime
    case @stop_count
    when static_anime_idle_time...static_anime_idle_time + ANIME_TIME
      @static_anime = true
    when static_anime_idle_time + ANIME_TIME
      @stop_count = [static_anime_idle_time - GAP_TIME,0].max
      @pattern = @original_pattern
      @static_anime = false
    else @static_anime = false end
  end
  #--------------------------------------------------------------------------
  # ● 进入待机前等待时间获取
  #--------------------------------------------------------------------------
  def static_anime_idle_time
    return @anime_idle_time if @anime_idle_time
    @anime_idle_time = (IDLE_TIME - RIDLE_TIME / 2 + rand(RIDLE_TIME)).to_i
  end
  #--------------------------------------------------------------------------
  # ● 是否待机动画
  #--------------------------------------------------------------------------
  def idle_anime?; @idle_anime end
  #--------------------------------------------------------------------------
  # ● 是否奔跑
  #--------------------------------------------------------------------------
  def is_dash?; false end
  #--------------------------------------------------------------------------
  # ● 初始化私有成员变量
  #--------------------------------------------------------------------------
  alias set_frame_init_private_members init_private_members
  def init_private_members
    set_frame_init_private_members
    @frame = 4
  end
  #--------------------------------------------------------------------------
  # ● 更新步行/踏步动画
  #--------------------------------------------------------------------------
  def update_animation
    update_anime_count
    if @anime_count > animation_wait
      update_anime_pattern
      @anime_count = 0
    end
  end
  #--------------------------------------------------------------------------
  # ● 移动时两帧之间等待时间
  #--------------------------------------------------------------------------
  def animation_wait
    [(9 - real_move_speed) * 3, 2].max
  end
  #--------------------------------------------------------------------------
  # ● 矫正姿势
  #--------------------------------------------------------------------------
  def straighten
    @pattern = @original_pattern if @walk_anime || @step_anime
    @anime_count = 0
  end
  #--------------------------------------------------------------------------
  # ● 更新动画图案
  #--------------------------------------------------------------------------
  def update_anime_pattern
    if !@step_anime && @stop_count > 0
      @pattern = @original_pattern
    else
      @pattern = (@pattern + 1) % @frame
    end
  end
  #--------------------------------------------------------------------------
  # ● 更改图像
  #--------------------------------------------------------------------------
  alias set_frame_set_graphic set_graphic
  def set_graphic(character_name, character_index)
    set_frame_set_graphic(character_name, character_index)
    @frame = get_frame(character_name)
    @original_pattern = get_halt_name(character_name)
  end
  #--------------------------------------------------------------------------
  # ● 斜向移动
  #--------------------------------------------------------------------------
  alias dir8_move_diagonal move_diagonal
  def move_diagonal(horz, vert)
    return @move_succeed = false if !passable?(@x, @y, horz) && !passable?(@x, @y, vert)
    return move_straight(horz) if passable?(@x, @y, horz) && !passable?(@x, @y, vert)
    return move_straight(vert) if passable?(@x, @y, vert) && !passable?(@x, @y, horz)
    dir8_move_diagonal(horz, vert)
    case [horz,vert]
    when [4,2] then set_direction(1)
    when [4,8] then set_direction(7)
    when [6,2] then set_direction(3)
    when [6,8] then set_direction(9)
    end
  end
end
#==============================================================================
# ■ Sprite_Character
#==============================================================================
class Sprite_Character < Sprite_Base
  include VIPArcher::DIR8_ANIME
  #--------------------------------------------------------------------------
  # ● 是否是八方向素材
  #--------------------------------------------------------------------------
  def is_dir8?
    return false if @character_name =~ /#{DIRE8_AFFIX}/
    return @character_name =~ /^(\@|\!\@|\$@|\!\$\@).+/
  end
  #--------------------------------------------------------------------------
  # ● 设置角色的位图
  #--------------------------------------------------------------------------
  alias dir8_move_set_character_bitmap set_character_bitmap
  def set_character_bitmap
    dir8_move_set_character_bitmap
    return unless is_dir8?
    @character_dir8 = {}
    set_character_dir8("", "")
    set_character_dir8(DASH4_AFFIX, DASH4_AFFIX)
    set_character_dir8(IDLE4_AFFIX, IDLE4_AFFIX)
    set_character_dir8(DIRE8_AFFIX, DIRE8_AFFIX)
    set_character_dir8(DASH8_AFFIX, DASH8_AFFIX, DIRE8_AFFIX)
    set_character_dir8(IDLE8_AFFIX, IDLE8_AFFIX, DIRE8_AFFIX)
    frame = @character.is_multi_frames? ? @character.frame : 3
    sign = @character_name[/^[\@\!\$]../]
    @cw = bitmap.width / frame
    @cw /= 4 unless sign && sign.include?('$')
    self.ox = @cw / 2
  end
  #--------------------------------------------------------------------------
  # ● 设置角色的各状态图
  #--------------------------------------------------------------------------
  def set_character_dir8(string, affix, default = "")
    begin
      @character_dir8[string.to_sym] = Cache.character(@character_name + affix)
      @character.idle_anime = true if string.include?(IDLE4_AFFIX)
    rescue
      @character_dir8[string.to_sym] = @character_dir8[default.to_sym]
    end
  end
  #--------------------------------------------------------------------------
  # ● 更新源矩形
  #--------------------------------------------------------------------------
  def update_src_rect
    return if @tile_id != 0
    index = @character.character_index
    frame = @character.is_multi_frames? ? @character.frame : 3
    first = @character.is_multi_frames? ? 0 : 1
    pattern = @character.pattern < frame ? @character.pattern : first
    if (anime_symbol = "#{
      @character.is_dash? && !$game_switches[DASH_ANIME_SW] ?
      DASH4_AFFIX : @character.static_anime ? IDLE4_AFFIX : ''
    }#{@character.direction.odd? ? DIRE8_AFFIX : ''}".to_sym) != @anime_symbol
      @anime_symbol = anime_symbol
      self.bitmap = @character_dir8[anime_symbol]
    end if is_dir8?
    sx = (index % 4 * frame + pattern) * @cw
    if (dir = @character.direction).odd?
      dir = [3, 7].include?(dir) && !is_dir8? ? 10 - dir : dir
      sy = (index / 4 * 4 + (dir + 1) / 3) * @ch
    else
      sy = (index / 4 * 4 + (dir - 2) / 2) * @ch
    end
    self.src_rect.set(sx, sy, @cw, @ch)
  end
  #--------------------------------------------------------------------------
  # ● 释放
  #--------------------------------------------------------------------------
  alias dir8_dispose dispose
  def dispose
    dir8_dispose
    @character_dir8.each_value do |v|
      v.dispose unless v.disposed?
    end if @character_dir8
  end
end[/pre]

无限の剣制

梦石
0
星屑
10445
在线时间
5019 小时
注册时间
2013-2-28
回帖
4942

开拓者贵宾

 楼主| 发表于 2018-11-8 17:26:42 | 显示全部楼层
本帖最后由 VIPArcher 于 2018-11-8 23:49 编辑

旧版丢失了Orz
回复

使用道具 举报

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

在本发帖返回顶部