查看: 988|回复: 2

[有事请教] 问个行走图4帧和8帧同时使用后切换出现空白帧的问题

[复制链接]
梦石
0
星屑
35248
在线时间
4171 小时
注册时间
2007-12-15
回帖
9489
发表于 2026-4-29 09:08:33 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 89444640 于 2026-4-29 09:15 编辑

是这样我用特殊符号+N后缀行走图表示多帧行走图的脚本以后,(张三□8代表行走图有8帧)出现了一个问题,
比如播放循环动画,正好播放到第5~6帧
131-Noble06-1□8.png
然后需要切换回4帧的行走图
131-Noble06.png
因为这时候是自动循环,事件触发以后鬼知道随机播放到第几帧完全无法保证播放到第1~4帧停止,
这时候会如果抽到5~6帧,会出现瞬间闪一下空白,因为4帧行走图没有4以后的,抽到了空,但是程序不能立即切换回4帧行走图的第一帧,问题理论上不大,就是看着不舒服。
更改素材名称,并且把所有4帧行走图,全都改成□8,虽然可以解决,但是工程量过大并且非常麻烦,所有事件都要重写,而且多帧行走我指不定有几帧循环,上面那张就是6帧……
请问有没有其他方法
应该是 Game_Character 2定义的吧

[pre lang="ruby"]#==============================================================================
# ■ Game_Character (分割定义 2)
#------------------------------------------------------------------------------
#  处理角色的类。本类作为 Game_Player 类与 Game_Event
# 类的超级类使用。
#【动画N】已被覆盖,用 □N 表示4帧以上动画
#==============================================================================

class Game_Character
  attr_accessor :anime_speed
  #--------------------------------------------------------------------------
  # ● 刷新画面
  #--------------------------------------------------------------------------
  def update
    # 跳跃中、移动中、停止中的分支
    if jumping?
      update_jump
    elsif moving?
      update_move
    else
      update_stop
    end
    # 动画计数超过最大值的情况下
    # ※最大值等于基本值减去移动速度 * 1 的值
    if @anime_count > MOVESPEEDLIST[Integer(@move_speed)]
      # 停止动画为 OFF 并且在停止中的情况下
      if not @step_anime and @stop_count > 0
        # 还原为原来的图形
        @pattern = @original_pattern
      # 停止动画为 ON 并且在移动中的情况下
      else
        # 更新图形
        @pattern = (@pattern + 1) % max_frame
      end
      # 清除动画计数
      @anime_count = 0
    end
    # 等待中的情况下
    if @wait_count > 0
      # 减少等待计数
      @wait_count -= 1
      return
    end
    # 强制移动路线的场合
    if @move_route_forcing
      # 自定义移动
      move_type_custom
      return
    end
    # 事件执行待机中并且为锁定状态的情况下
    if @starting or lock?
      # 不做规则移动
      return
    end
    # 如果停止计数超过了一定的值(由移动频度算出)
    if @stop_count > (40 - @move_frequency * 2) * (6 - @move_frequency)
      # 移动类型分支
      case @move_type
      when 1  # 随机
        move_type_random
      when 2  # 接近
        move_type_toward_player
      when 3  # 自定义
        move_type_custom
      when 4 #毛玉诱饵
        #接近事件(YOU_ER)
      when 5 #追杀
        move_type_toward_player#往事件移动(0)
      when 6 #避开
        move_away_from_player
      when 7 #回程
        往坐标移动(self.原位[0],self.原位[1])
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 更新画面 (跳跃)
  #--------------------------------------------------------------------------
  def update_jump
    # 跳跃计数减 1
    @jump_count -= 1
    # 计算新坐标
    @real_x = (@real_x * @jump_count + @x * 128) / (@jump_count + 1)
    @real_y = (@real_y * @jump_count + @y * 128) / (@jump_count + 1)
  end
  #--------------------------------------------------------------------------
  # ● 更新画面 (移动)
  #--------------------------------------------------------------------------
  def update_move
    # 移动速度转换为地图坐标系的移动距离
    distance = 2 ** @move_speed
    # 理论坐标在实际坐标下方的情况下
    if @y * 128 > @real_y
      # 向下移动
      @real_y = [@real_y + distance, @y * 128].min
    end
    # 理论坐标在实际坐标左方的情况下
    if @x * 128 < @real_x
      # 向左移动
      @real_x = [@real_x - distance, @x * 128].max
    end
    # 理论坐标在实际坐标右方的情况下
    if @x * 128 > @real_x
      # 向右移动
      @real_x = [@real_x + distance, @x * 128].min
    end
    # 理论坐标在实际坐标上方的情况下
    if @y * 128 < @real_y
      # 向上移动
      @real_y = [@real_y - distance, @y * 128].max
    end
    # 移动时动画为 ON 的情况下
    if @walk_anime
      # 动画计数增加 1.5
      @anime_count += 1.5
    # 移动时动画为 OFF、停止时动画为 ON 的情况下
    elsif @step_anime
      # 动画计数增加 1
      @anime_count += 1
    end
  end
  #--------------------------------------------------------------------------
  # ● 更新画面 (停止)
  #--------------------------------------------------------------------------
  def update_stop
    # 停止时动画为 ON 的情况下
    if @step_anime
      # 动画计数增加 1
      @anime_count += 1
    # 停止时动画为 OFF 并且、现在的图像与原来的不同的情况下
    elsif @pattern != @original_pattern
      # 动画计数增加 1.5
      @anime_count += 1.5
    end
    # 事件执行待机中并且不是锁定状态的情况下
    # ※缩定、处理成立刻停止执行中的事件
    unless @starting or lock?
      # 停止计数增加 1
      @stop_count += 1
    end
  end
  #--------------------------------------------------------------------------
  # ● 移动类型 : 随机
  #--------------------------------------------------------------------------
  def move_type_random
    if @领地 != nil
      if @x < @领地[0] or @y < @领地[1] or @x > @领地[2] or @y > @领地[3]
        往坐标移动(self.原位[0],self.原位[1])
        return
      end
    end
    # 随机 0~5 的分支
    case rand(6)
    when 0..3  # 随机
      move_random
    when 4  # 前进一步
      move_forward
    when 5  # 暂时停止
      @stop_count = 0
    end
  end
  #--------------------------------------------------------------------------
  # ● 移动类型 : 接近
  #--------------------------------------------------------------------------
  def move_type_toward_player
    # 求得与主角坐标的差
    # 当开关212重力开关打开时判定位置
    sx = @x - $game_player.x
    a = $game_switches[212] ? 1 : 0
    sy = @y - $game_player.y - a
    # 求得差的绝对值
    abs_sx = sx > 0 ? sx : -sx
    abs_sy = sy > 0 ? sy : -sy
    # 如果纵横共计离开 20 个元件
    if sx + sy >= 20
      # 随机
      move_random
      return
    end
    # 随机 0~5 的分支
    case rand(6)
    when 0..3  # 接近主角
      move_toward_player
    when 4  # 随机
      move_random
    when 5  # 前进一步
      move_forward
    end
  end
  #--------------------------------------------------------------------------
  # ● 移动类型 : 自定义
  #--------------------------------------------------------------------------
  def move_type_custom
    # 如果不是停止中就中断
    if jumping? or moving?
      return
    end
    # 如果在移动指令列表最后结束还没到达就循环执行
    while @move_route_index < @move_route.list.size
      # 获取移动指令
      command = @move_route.list[@move_route_index]
      # 指令编号 0 号 (列表最后) 的情况下
      if command.code == 0
        # 选项 [反复动作] 为 ON 的情况下
        if @move_route.repeat
          # 还原为移动路线的最初索引
          @move_route_index = 0
        end
        # 选项 [反复动作] 为 OFF 的情况下
        unless @move_route.repeat
          # 强制移动路线的场合
          if @move_route_forcing and not @move_route.repeat
            # 强制解除移动路线
            @move_route_forcing = false
            # 还原为原始的移动路线
            @move_route = @original_move_route
            @move_route_index = @original_move_route_index
            @original_move_route = nil
          end
          # 清除停止计数
          @stop_count = 0
        end
        return
      end
      # 移动系指令 (向下移动~跳跃) 的情况下
      if command.code <= 14
        # 命令编号分支
        case command.code
        when 1  # 向下移动
          move_down
        when 2  # 向左移动
          move_left
        when 3  # 向右移动
          move_right
        when 4  # 向上移动
          move_up
        when 5  # 向左下移动
          move_lower_left
        when 6  # 向右下移动
          move_lower_right
        when 7  # 向左上移动
          move_upper_left
        when 8  # 向右上
          move_upper_right
        when 9  # 随机移动
          move_random
        when 10  # 接近主角
          move_toward_player
        when 11  # 远离主角
          move_away_from_player
        when 12  # 前进一步
          move_forward
        when 13  # 后退一步
          move_backward
        when 14  # 跳跃
          jump(command.parameters[0], command.parameters[1])
        end
        # 选项 [无视无法移动的情况] 为 OFF 、移动失败的情况下
        if not @move_route.skippable and not moving? and not jumping?
          return
        end
        @move_route_index += 1
        return
      end
      # 等待的情况下
      if command.code == 15
        # 设置等待计数
        @wait_count = command.parameters[0] * 2 - 1
        @move_route_index += 1
        return
      end
      # 朝向变更系指令的情况下
      if command.code >= 16 and command.code <= 26
        # 命令编号分支
        case command.code
        when 16  # 面向下
          turn_down
        when 17  # 面向左
          turn_left
        when 18  # 面向右
          turn_right
        when 19  # 面向上
          turn_up
        when 20  # 向右转 90 度
          turn_right_90
        when 21  # 向左转 90 度
          turn_left_90
        when 22  # 旋转 180 度
          turn_180
        when 23  # 从右向左转 90 度
          turn_right_or_left_90
        when 24  # 随机变换方向
          turn_random
        when 25  # 面向主角的方向
          turn_toward_player
        when 26  # 背向主角的方向
          turn_away_from_player
        end
        @move_route_index += 1
        return
      end
      # 其它指令的场合
      if command.code >= 27
        # 命令编号分支
        case command.code
        when 27  # 开关 ON
          $game_switches[command.parameters[0]] = true
          $game_map.need_refresh = true
        when 28  # 开关 OFF
          $game_switches[command.parameters[0]] = false
          $game_map.need_refresh = true
        when 29  # 更改移动速度
          @move_speed = command.parameters[0]
        when 30  # 更改移动频度
          @move_frequency = command.parameters[0]
        when 31  # 移动时动画 ON
          @walk_anime = true
        when 32  # 移动时动画 OFF
          @walk_anime = false
        when 33  # 停止时动画 ON
          @step_anime = true
        when 34  # 停止时动画 OFF
          @step_anime = false
        when 35  # 朝向固定 ON
          @direction_fix = true
        when 36  # 朝向固定 OFF
          @direction_fix = false
        when 37  # 穿透 ON
          @through = true
        when 38  # 穿透 OFF
          @through = false
        when 39  # 在最前面显示 ON
          @always_on_top = 1
        when 40  # 在最前面显示 OFF
          @always_on_top = 0
        when 41  # 更改图形
          @tile_id = 0
          @character_name = command.parameters[0]
          @character_hue = command.parameters[1]
          if @original_direction != command.parameters[2]
            @direction = command.parameters[2]
            @original_direction = @direction
            @prelock_direction = 0
          end
          if @original_pattern != command.parameters[3]
            @pattern = command.parameters[3]
            @original_pattern = @pattern
          end
        when 42  # 不更改不透明度
          @opacity = command.parameters[0]
        when 43  # 更改合成方式
          @blend_type = command.parameters[0]
        when 44  # 演奏 SE
          $game_system.se_play(command.parameters[0])
        when 45  # 脚本
          result = eval(command.parameters[0])
        end
        @move_route_index += 1
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 增加步数
  #--------------------------------------------------------------------------
  def increase_steps
    # 清除停止步数
    @stop_count = 0
  end
  
  def 接近事件(id)
    # 求得与主角坐标的差
    sx = @x - $game_map.events[id].x
    sy = @y - $game_map.events[id].y
    # 求得差的绝对值
    abs_sx = sx > 0 ? sx : -sx
    abs_sy = sy > 0 ? sy : -sy
    # 如果纵横共计离开 20 个元件
    if sx + sy >= 20
      # 随机
      move_random
      return
    end
    # 随机 0~5 的分支
    case rand(6)
    when 0..3  # 接近主角
      往事件移动(id)
    when 4  # 随机
      move_random
    when 5  # 前进一步
      move_forward
    end
  end
  
  def 往事件移动(id)
    x,y = 事件(id).x,事件(id).y
    sx = @x - x
    sy = @y - y
    # 求得差的绝对值
    abs_sx = sx.abs
    abs_sy = sy.abs
    # 横距离与纵距离相等的情况下
    if abs_sx == abs_sy
      # 随机将边数增加 1
      rand(2) == 0 ? abs_sx += 1 : abs_sy += 1
    end
    # 横侧距离长的情况下
    if abs_sx > abs_sy
      智能前进(sx > 0 ? 4 : 6,[x,y])
    # 竖侧距离长的情况下
    else
      智能前进(sy > 0 ? 8 : 2,[x,y])
    end
  end
  #--------------------------------------------------------------------------
  # ● 可以通行的情况下前进,否则向随机方向转换
  #--------------------------------------------------------------------------
  def 智能前进(direction,xy= nil)
    d = direction == 0 ? @direction : direction
    case d
    when 8 ;turn_up
    when 6 ;turn_right
    when 4 ;turn_left
    when 2 ;turn_down
    end
    unless moving?
      if passable?(@x, @y, d)
        @ex_d = 0
        move_forward
      else
        找路(direction,xy)
      end
    end
  end
  
  def 找路(d,xy)
    if @ex_d != 0
      if passable?(@x,@y,@ex_d)
        case @ex_d
        when 2 ; move_down
        when 4 ; move_left
        when 6 ; move_right
        when 8 ; move_up
        end
      else
        @ex_d = 0
      end
    else
      case d
      when 2,8
        x,y,n = @x,@y,0
        while passable?(x,y,4)
          x -= 1
          if passable?(x,y,d)
            n -= 1000
            break
          end
          n += 1
        end
        x,y,m = @x,@y,0
        while passable?(x,y,6)
          x += 1
          if passable?(x,y,d)
            m -= 1000
            break
          end
          m += 1
        end
        if n < m
          @ex_d = 4
        else
          @ex_d = 6
        end
      when 4,6
        x,y,n = @x,@y,0
        while passable?(x,y,2)
          y += 1
          if passable?(x,y,d)
            n -= 1000
            break
          end
          n += 1
        end
        x,y,m = @x,@y,0
        while passable?(x,y,8)
          y -= 1
          if passable?(x,y,d)
            m -= 1000
            break
          end
          m += 1
        end
        if n < m
          @ex_d = 2
        else
          @ex_d = 8
        end
      end
    end
  end
  
  def 往坐标移动(x,y,启动=0)
    sx = @x - x
    sy = @y - y
    # 坐标相等情况下
    if sx == 0 and sy == 0
      if self.is_a?(Game_Event) and 启动 != 0 and @启动 != nil
        if not jumping?
          k(K到目标)
          start
        end
      end
      @启动 = nil
      return
    end
    @启动 = true
    # 求得差的绝对值
    abs_sx = sx.abs
    abs_sy = sy.abs
    # 横距离与纵距离相等的情况下
    if abs_sx == abs_sy
      # 随机将边数增加 1
      rand(2) == 0 ? abs_sx += 1 : abs_sy += 1
    end
    # 横侧距离长的情况下
    if abs_sx > abs_sy
      智能前进(sx > 0 ? 4 : 6,[x,y])
    # 竖侧距离长的情况下
    else
      智能前进(sy > 0 ? 8 : 2,[x,y])
    end
  end
  #------------------------------------------------------------
  def 路线(*ary) #[x,y,0智1直],"表达式",:循环
    return if @hp.nil?
    if ary[@hp].is_a?(Array)
      @hp += 1 if goto(ary[@hp])
    elsif ary[@hp].is_a?(String)
      eval(ary[@hp]) ; @hp += 1
    elsif ary[@hp] == :循环
      @hp = 0
    else
      if @list.any?{|i| i.code == 118 and i.parameters[0].include?("&")}
        @hp = :终点启动 ;start
      else
        @hp = nil
      end
    end
  end
  def goto(ary) #[x,y,直行]
    if ary[2] == 1
      return to坐标(ary) == 2
    else
      return 绕路前进(ary)
    end
  end
  def to坐标(ary,绕=false) #[x,y,直行] #返回 不通0 ;通1 ;终点2
    sx = (@x - ary[0]).to_i ;sy = (@y - ary[1]).to_i
    m = 0 ; m = 1 if 绕 and !ary[0].f? and 事件(0).a_xy == ary[0,2]
    a,b = sx.abs,sy.abs
    return 2 if a + b <= m
    (rand(2) == 0 ? a += 1 : b += 1) if a == b
    return (move_dir?(a > b ? (sx > 0 ? 4 : 6) : (sy > 0 ? 8 : 2)) ? 1 : 0)
  end
  
  def 此路(rx,ry,dir) # rx ry :穷举的数值曲线,返回可通行的距离
    x,y = @x,@y ; n = 0
    nd = ry == 0 ? (rx < 0 ? 4 : 6) : (ry < 0 ? 8 : 2)
    while !passable?(x,y,dir)
      return [9999,nd] if !passable?(x,y,nd) #探路方向不通
      x += rx ; y += ry ; n += 1
    end
    return [n,nd] #[距离,方向]
  end
  def 靠左探索?(ad,bd) #ad前进方向,bd目标方向,获得按左还是右探索
    case ad
    when 2 ;return bd == 6
    when 4 ;return bd == 2
    when 6 ;return bd == 8
    when 8 ;return bd == 4
    end
  end
  def 摸墙方向
    case @摸墙[3]
    when 2 ;return @摸墙[1] ? 6 : 4
    when 4 ;return @摸墙[1] ? 2 : 8
    when 6 ;return @摸墙[1] ? 8 : 2
    when 8 ;return @摸墙[1] ? 4 : 6
    end
  end
  
  def 绕路前进(ary)
    if @摸墙 != nil
      摸墙探索(ary)
      return false
    end
    sx = (@x - ary[0]).to_i ; sy = (@y - ary[1]).to_i ; a,b = sx.abs,sy.abs
    m = ary[0].f? ? 0 : 事件(0).a_xy == ary[0,2] ? 1 : 0
    return true if a + b <= m #到达目的地
    (rand(2) == 0 ? a += 1 : b += 1) if a == b
    dir = (a > b ? (sx > 0 ? 4 : 6) : (sy > 0 ? 8 : 2))
    return false if move_dir?(dir) #可前进
    #[0目的坐标线,1靠左探索?,2目的方向,3探索方向]
    @摸墙 = [[[nil,@y+1],[@x-1,nil],[@x+1,nil],[nil,@y-1]][dir / 2 - 1]]
    nd = 确定探索方向(dir,ary)
    @摸墙.push(靠左探索?(nd,dir),dir,nd)
    return false
  end
  
  def 确定探索方向(dir,ary)
    f = [[1,0],[0,1],[0,1],[1,0]][dir / 2 - 1] #寻找最近的通路
    a = 此路(f[0],f[1],dir) ; b = 此路(-f[0],-f[1],dir)
    if a[0] == b[0]
      sx = (@x - ary[0]).to_i ; sy = (@y - ary[1]).to_i
      return ([4,6].include?(dir) ? (sy < 0 ? 2 : 8) : (sx < 0 ? 6 : 4))
    end
    return (a[0] < b[0] ? a[1] : b[1])
  end
  
  def 摸墙探索(ary) #[0目的坐标线,1靠左探索?,2目的方向,3探索方向]
    (@摸墙 = nil ; return) if @x==@摸墙[0][0] or @y==@摸墙[0][1] #到达目标线
    if @摸墙[1] != nil and move_dir?(a = 摸墙方向,false) #摸墙方向可通行
      @摸墙[1] = nil if a == @摸墙[2] #是目的方向
      @摸墙[3] = a #改变探索方向
      return
    end
    return if move_dir?(@摸墙[3]) #探索方向可前进
    if @摸墙[1].nil?
      @摸墙[3] = 确定探索方向(@摸墙[3],ary)
      @摸墙[1] = 靠左探索?(@摸墙[2],@摸墙[3])
      return
    end
    return if move_dir?(10 - a) #换个方向可通行
  end
end
[/pre]
梦石
0
星屑
8026
在线时间
1051 小时
注册时间
2012-4-3
回帖
1270

开拓者

发表于 2026-5-21 22:34:56 来自手机 | 显示全部楼层
可以在当前事件行走图改变的时候,加一句:@pattern = 0。(这个pattern数值是行走图对应帧,值为0时是第1帧。)

评分

参与人数 1赞 +1 收起 理由
89444640 + 1 塞糖

查看全部评分

回复

使用道具 举报

梦石
0
星屑
1928
在线时间
150 小时
注册时间
2009-8-17
回帖
47
发表于 2026-8-29 14:31:18 | 显示全部楼层
有阵子没见了 游戏进展怎么样
战局对我们的战士太不利了!我的战士们坚持不住了!我的圣堂武士遭受了巨大的损失!我得重新集结部队——
回复 1 0

使用道具 举报

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

本版积分规则

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

在本版发帖返回顶部