设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
12
返回列表 发新帖
楼主: 88510051as
打印 上一主题 下一主题

[已经解决] 如何让行走图有影子

 关闭 [复制链接]

Lv1.梦旅人

梦石
0
星屑
79
在线时间
394 小时
注册时间
2011-4-24
帖子
291
11
发表于 2011-4-25 22:19:44 | 只看该作者
本帖最后由 ZAndiH 于 2011-5-7 22:50 编辑

利用事件的说法来阐述一下“伪代码”。纯事件可达到部分效果,但强烈建议使用脚本。
(不过脚本的话估计就要重新做一个了、、目前没有看到这样的、、、工程量加调试大约需要连续的2~6小时《-指我自己- -)
另外,感谢lZ提供了一个新的功能的方向哦~:victory:
  1. #调用 当前角色  当前 行走图
  2. 显示 当前图片|此时效果为:显示当前人物当前行走图,即4方向行走图(16个图片)中的某一个
  3. 对 当前图片 进行效果处理
  4.   效果处理包括:调节透明度为 100 (阴影透明度,0~255,越大越不透明导致影子越深;反之影子越浅),调解对比度为 最大 (我记不住最大多少了、、、)
  5. 将 当前图片 以图片中心为旋转轴 旋转180°
  6. 将 当前图片 跟随左上角移动 (当前图片左上角《-这是注释,程序思路中没有该括号内容)移动到 坐标((当前角色 横坐标X-1) *32(图块像素数),当前角色 横坐标X *32(图块像素数)-16(约一半处))
复制代码
以上“伪代码”的问题:(有处理办法- -,还算可以、、、、)
1.对影子形状的处理:若人物行走图在转化后,内部有非黑完全黑者(如本身就是白色的地方,用此种处理方法无论如何都还是白、、),则影子的“黑”深度不一;
2.影子与原行走图连接处可能并非完美衔接;
3.影子图有可能盖住人物行走图;
4.若人物影子所在位置与人物所在位置较特殊(如:高度差太大之类),导致影子应变形但却未变形(典型的例子如:人物在陡坡边,影子在陡坡上应有相应的拉长,人物在墙边影子在墙上应有相应变形等);
5.当前光源永远被限定在角色正上方(意即影子永远在角色行走图正下方);


另外,由于背景图的风格,阴影样式同样需进行更换(而且是大动)。
例如LZ给出的图多数情况下也许需要3D建模后渲染(2d的话至少要一个专业过得去的美工了、、)。在此种情况下,还不如导出的时候直接加上阴影。
如果只是RM默认风格,以RMXP为例,其光源永远在左上角,而且几乎直射地面,所以阴影只需要一个相对脚偏右的相对应的黑(椭)圆或其他东西即可。这种情况下貌似那个太阳精灵的脚本可直接使用。(再次声明、、我没用过= =)(况且、、也不需要考虑图块与图块之间的关系、、、透明度也不需要考虑了- -唯一的问题在于在光源附近是否会导致原光源阴影不适合。但看在RM默认阴影风格是不会改变的情形下,也不用变了吧、、、)

评分

参与人数 1星屑 +1600 梦石 +2 收起 理由
「旅」 + 1600 + 2 0 0回答得好仔细啊……

查看全部评分

《RM——梦想与现实之间》【论坛活动】《RM到底能做什么》
↑想知道如何快速获得60VIP?请点↑
回复

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
88
在线时间
331 小时
注册时间
2010-10-24
帖子
778
12
发表于 2011-4-26 13:43:02 | 只看该作者
#==================================================================================
# ■ 太阳精灵(活动块)
#------------------------------------------------------------------------------
#    由阴影精灵(活动块)为基础
#    由 Rataime 原创。
#    由 DerVVulfman 重新编辑。
#   
#    由 Painhurt 进行修正。
#    由 精灵使者 进行汉化并修正。
#    2008年10月14日
#------------------------------------------------------------------------------
#
#  介绍:
#
#  这个系统允许角色和所有“已经准备好的”事件在大地图上产生阴影。当角色四处移动的
#  时候,将会出现由算法算出的像阳光照射一样的影子。当然,经过在事件页里特殊注释的
#  事件也会同样产生影子。
#  
#------------------------------------------------------------------------------
#
# 使用方法:
#
#  -- 太阳
#     想创建阳光效果的话,你必须要在地图上创建一个“太阳”的事件。在很多的场合之下
#     ,这个事件的行走图肯定是空白的。你肯定不想“看”到太阳,是么?(精灵:太阳事
#     件无论在任何位置,只要在地图内就可以了喵~当然,此事件不能加任何启动条件。)
#
#     想把这些事件的其中的一个当做太阳,那么你就必须在这个事件页里面添加一些东西。
#     这些东西没有什么太多的,仅仅是一些注释而已。
#
#     你首先要添加的注释就是“begin Sun”请不要加引号。这个告诉了系统,这张地图要使
#     使用太阳效果。剩下的两个值是可选项,而且在脚本里面有默认值(当然只加进了脚本里
#     面)。当然,这些也可以加入作为注释。注意大小写,一定要符合要求。注:切记不能写
#     在一起,每个注释一行。
#
#     begin Sun --- 启动太阳系统
#     self_angle 数字 --- 每个影子的角度是多少。(0-360)
#     self_opacity 数字 --- 影子的不透明度是多少。(0-255)
#     书写格式举例:self_angle 90
#
#     然后,你的角色移动的时候就会自动产生影子了。
#
#  -- 其他事件
#     事件不会知道他们如何才可以产生阴影。如果想让他们产生阴影的话,你只需要在此事件
#     的的事件页里添加一段特殊的注释。这个注释仅仅是一个特殊短语“begin shadow”(再
#     次注意,不要加引号)。请注意,产生阴影的优先级一定为“与角色相同”或者“上方”
#     才可以产生阴影。注意有些事件如果处于在画面以上的优先级的情况之下,其影子会被遮
#     掩,所以不要启用那些事件的阴影,切记。
#
#
#------------------------------------------------------------------------------
#
# 更新日志:
#
#  1) 在脚本中增添了更人性化的标签和标题头。
#  2) 在XPML模块里压缩了关键字分隔符和参数。
#  3) 为了降低资源,将太阳产生的影子数组设成了实例变量。
#  4) 与Near Fantastica 的人物跟随脚本兼容。
#  5) 与Ccoa的人物跟随脚本兼容。
#  6) 与Trickster的人物跟随脚本兼容。
#  7) 在设定区段增加了默认的影子设定。
#
#==================================================================================



   #========================================================================
   #  ■      设       定       系        统          部       分       ■  #
   #========================================================================
    # 跟随系统部分设定(如果选用了相应的系统请选true,否则选false)
    CATERPILLAR_COMPATIBLE      = true    # 原版跟随系统兼容开关  
    SQUAD_MOVE_COMPATIBLE       = false   # Near Fantastica的跟随系统兼容开关
    CCOA_CATER_COMPATIBLE       = false   # Ccoa的跟随系统兼容开关
    TRICKSTER_CATER_COMPATIBLE  = false   # Trickster的跟随系统兼容开关
   
    # 太阳系统的特别设定
    SUN_WARN                    = true    # 检查是否兼容老版本的太阳系统
    SUN_ANGLE                   = 45      # 默认太阳系统产生的影子角度
    SUN_OPACITY                 = 128     # 默认太阳系统产生的影子深度

   
   #========================================================================
   #  ■■   设         定       部          分          结      束   ■■  #
   #========================================================================
  
  

#==================================================================================
# ■ Game_Temp
#------------------------------------------------------------------------------
#  在没有存档的情况下,处理临时数据的类。这个类的实例请参考 $game_temp 。
#=================================================================================
class Game_Temp
  #--------------------------------------------------------------------------
  # ● 定义实例变量
  #--------------------------------------------------------------------------
  attr_accessor :sun_spriteset            # 维持太阳阴影的活动块
end

#==================================================================================
# ■ Game_Party
#------------------------------------------------------------------------------
#  处理同伴的类。包含金钱以及物品的信息。本类的实例请参考 $game_party。
#==================================================================================

class Game_Party
  #--------------------------------------------------------------------------
  # ● 定义实例变量
  #--------------------------------------------------------------------------
  attr_reader :characters
end



#==================================================================================
# ■ Sprite_Sun
#------------------------------------------------------------------------------
#  根据角色的地图位置来处理角色阴影角度的精灵(活动块)类。Game_Character 类的实例
#  监视、活动块状态的自动变化。
#==================================================================================

class Sprite_Sun < RPG::Sprite
  #--------------------------------------------------------------------------
  # ● 定义实例变量
  #--------------------------------------------------------------------------
  attr_accessor :character         
  #--------------------------------------------------------------------------
  # ● 初始化对象
  #     viewport  : 显示端口
  #     character : 角色 (Game_Character)
  #     id        : 角色ID
  #--------------------------------------------------------------------------
  def initialize(viewport, character = nil, id=0)
    super(viewport)
    @character = character
    params=$game_temp.sun_spriteset.sun[id]
    # 默认设置
    self_angle    = SUN_ANGLE
    self_opacity  = SUN_OPACITY
    # 根据参数的设置
    self_angle    = params[0]   if params.size > 0
    self_opacity  = params[1]   if params.size > 1
    @self_angle   = self_angle
    @self_opacity = self_opacity
    update
  end
  #--------------------------------------------------------------------------
  # ● 更新画面
  #--------------------------------------------------------------------------  
  def update
    super
    # 在图块ID,文件名或者色相不同于当前的情况下
    if @tile_id != @character.tile_id or
       @character_name != @character.character_name or
       @character_hue != @character.character_hue
      @tile_id = @character.tile_id
      @character_name = @character.character_name
      @character_hue = @character.character_hue
      if @tile_id > 0
         sx = (@tile_id / 128 % 2 * 8 + @tile_id % 8) * 32;
         sy = @tile_id % 256 / 8 % 16 * 32;
          set_number = @tile_id / 256
        self.bitmap = RPG::Cache.system("TileB") if set_number == 0
        self.bitmap = RPG::Cache.system("TileC") if set_number == 1
        self.bitmap = RPG::Cache.system("TileD") if set_number == 2
        self.bitmap = RPG::Cache.system("TileE") if set_number == 3
        self.src_rect.set(0, 0, 32, 32)
        self.ox = 16
        self.oy = 32
      else
       #self.bitmap =RPG::Cache.character(@character_name)#影子参数的对应修改
       self.bitmap = RPG::Cache.character(@character.character_name,
         @character.character_hue)
        sign = @character_name[/^[\!\$]./]
        if sign != nil and sign.include?('$')
          @cw = bitmap.width / 4#影子的完整度设定
          @ch = bitmap.height / 4#影子的完整度设定
        else
          @cw = bitmap.width / 4#影子的完整度设定
          @ch = bitmap.height / 4#影子的完整度设定
        end
        self.ox = @cw / 2
        self.oy = @ch
      end
    end
    # 设置可见状况
    self.visible = (not @character.transparent)
    # 如果画面是角色的情况下
    if @tile_id == 0
      hue = @character.character_hue
      pattern = @character.pattern < 3 ? @character.pattern : 1
      # 矩形本体设定
      sx = (hue % 4 * 3 + pattern) * @cw
      @direct = @character.direction
      if self.angle > 90 or angle < -90
        sy = ( 4 - 2) / 2 * @ch                   if @direct == 6
        sy = ( 6 - 2) / 2 * @ch                   if @direct == 4
        sy = (@character.direction - 2) / 2 * @ch if @direct != 4 and @direct != 6
      else
        sy = (hue / 4 * 4 + (@character.direction - 2) / 2) * @ch
       #sy = @character.direction
      end
      self.src_rect.set(sx, sy, @cw, @ch)
    end
    # 设置精灵(活动块)的坐标
    self.x = @character.screen_x#  
    self.y = @character.screen_y-5 #  
     #self.z = 10#@character.screen_z-1
     
     self.z = @character.screen_z(@ch)-1#  
    # 设置不透明度,合成方式和草木深度
   self.opacity = @self_opacity
   # self.opacity = @character.opacity#  
    self.blend_type = @character.blend_type
    self.bush_depth = @character.bush_depth
    # 显示动画
    if @character.animation_id != 0#  
      animation = $data_animations[@character.animation_id]#  
      animation(animation, true)#  
      @character.animation_id = 0#  
    end
    self.angle = @self_angle.to_i - 90
    self.color = Color.new(0, 0, 0)
  #==========近大远小
   
   id = $game_map.map_id
   name = $data_mapinfos[id].name
   if name.include?("★")
     rate =  @character.y.to_f / $game_map.height.to_f + 0.5 # ← 这个值是到达屏幕最上方时的人物比例 1.0为默认大小 最下方比例则为 1+这个值
     self.zoom_x = self.zoom_y = rate
   end
  #===========
    end
end



#==================================================================================
# ■ Sprite_Character
#------------------------------------------------------------------------------
#  角色显示用脚本。监视 Game_Character 类的实例、自动变化脚本状态。
#==================================================================================

class Sprite_Character < RPG::Sprite
  #--------------------------------------------------------------------------
  # ● 重命名函数列表
  #--------------------------------------------------------------------------  
  alias sun_initialize initialize
  alias sun_update update
  #--------------------------------------------------------------------------
  # ● 初始化对像
  #     viewport  : 显示端口
  #     character : 角色 (Game_Character)
  #--------------------------------------------------------------------------
  def initialize(viewport, character = nil)
   #@viewport0 = Viewport.new(0, 0, 544, 416)
    @viewport = Viewport.new(0, 0, 800, 600)#修改影子的行动范围,不做剪切
     viewport.z = 0#战斗清除影子,地图切换清楚影子,改为1则有延迟
    @character = character
    super(viewport)
    @sunlist=[]
    if character.is_a?(Game_Event) and $game_temp.sun_spriteset.sun != []
      params = XPML.XPML_read("Shadow", @character.id, 2)
      if params != nil
        for i in 0...$game_temp.sun_spriteset.sun.size
          @sunlist.push(Sprite_Sun.new(viewport, @character, i))
        end
      end
    end
    if character.is_a?(Game_Player) and $game_temp.sun_spriteset.sun != []
      for i in 0...$game_temp.sun_spriteset.sun.size
        @sunlist.push(Sprite_Sun.new(viewport, $game_player, i))
      end
      #===================================================
      # ● 与人物跟随功能兼容脚本
      #===================================================
      if CATERPILLAR_COMPATIBLE and $game_party.characters != nil
        for member in $game_party.characters
          for i in 0...$game_temp.sun_spriteset.sun.size
            @sunlist.push(Sprite_Sun.new(viewport, member, i))
          end
        end
      end
      if SQUAD_MOVE_COMPATIBLE and $game_allies.values != nil
        for member in $game_allies.values
          for i in 0...$game_temp.sun_spriteset.sun.size
            @sunlist.push(Sprite_Sun.new(viewport, member, i))
          end
        end
      end
      if CCOA_CATER_COMPATIBLE and $game_train.actors != nil
        for member in $game_train.actors
          for i in 0...$game_temp.sun_spriteset.sun.size
            @sunlist.push(Sprite_Sun.new(viewport, member, i))
          end
        end
      end
      if TRICKSTER_CATER_COMPATIBLE and $game_party.followers != nil
        for member in $game_party.followers
          for i in 0...$game_temp.sun_spriteset.sun.size
            @sunlist.push(Sprite_Sun.new(viewport, member, i))
          end
        end
      end
      #===================================================
      # ● 兼容脚本结束
      #===================================================      
    end
    # 执行原始函数调用
    sun_initialize(viewport, @character)
  end
  #--------------------------------------------------------------------------
  # ● 更新画面
  #--------------------------------------------------------------------------
  def update
     
    sun_update
    if @sunlist != []
      for i in [email protected]
        @sunlist.update
      end
    end
  end  
end



#==================================================================================
# ■ Game_Event
#------------------------------------------------------------------------------
#  处理事件的类。条件判断、事件页的切换、并行处理、执行事件功能
# 在 Game_Map 类的内部使用。
#==================================================================================

class Game_Event < Game_Character
  #--------------------------------------------------------------------------
  # ● 定义实例变量
  #--------------------------------------------------------------------------
  attr_accessor :id
end




#==================================================================================
# ■ Spriteset_Map
#------------------------------------------------------------------------------
#  处理地图画面活动块和元件的类。本类在 Scene_Map 类的内部使用。
#================================================================================

class Spriteset_Map
  #--------------------------------------------------------------------------
  # ● 定义实例变量
  #--------------------------------------------------------------------------  
  attr_accessor :sun
  #--------------------------------------------------------------------------
  # ● 重命名函数列表
  #--------------------------------------------------------------------------  
  alias sun_initialize initialize
  #--------------------------------------------------------------------------
  # ● 初始化对象
  #--------------------------------------------------------------------------   
  def initialize
    @sun = []
    $game_temp.sun_spriteset = self
    warn = false
    for k in $game_map.events.keys.sort
      if ($game_map.events[k].list != nil and
          $game_map.events[k].list[0].code == 108 and
          ($game_map.events[k].list[0].parameters == ["Sun"] or
          $game_map.events[k].list[0].parameters == ["o"]))
        warn = true
      end
      params = XPML.XPML_read("Sun", k, 2)
      $game_temp.sun_spriteset.sun.push(params) if params != nil
    end
    if warn == true and SUN_WARN
      p "警告:在地图上至少有一个事件使用了过去的方法来添加太阳效果"
    end
    # 执行原始函数调用
    sun_initialize
  end  
end


#==============================================================================
# ■ module XPML
#------------------------------------------------------------------------------
#  本模块用来读取并传递注释中的参数。
#
#  使用此模块的主要用途就是检查和读出事件的注释。
#  * 标记的关键字的注明方法:
#    begin 关键字
#  * 注意参数之间必须用关键字隔开。
#  * 调用此函数的方法:
#    XPML_read("关键字",事件ID,读取参数的最大值)
#  * 最后一项可以忽略,默认为整个事件。
#  * 赋值方法:
#    变量名 参数
#  * 每个变量名和参数各占一行。
#  * 如果指明的关键字在事件里面不存在的话,则返回nil。
#  * 如果两个标记之间没有参数的话,则返回空数组。
#  * 如果参数中有数字参数的话,会自动返回为数字变量。
#  举例:在一个事件中的注释写入(每个注释写一行,#号后面的不写)
#       begin first # 第一关键字
#       begin second #第二关键字
#       变量1 1
#       变量2 two
#       begin third #第三关键字
#       任何东西 3
#  然后得出转换结果:
#   p XPML_read("first", event_id) -> [] #第一关键字和第二关键字没有参数
#   p XPML_read("second", event_id) -> [1,"two"] #第二关键字和第三关键字之间有2个参数
#   p XPML_read("third", event_id) -> [3] #第三关键字之间有一个参数
#   p XPML_read("forth", event_id) -> nil #找不到第四关键字则返回nil
#===================================================

module XPML
  module_function
  #--------------------------------------------------------------------------
  # ● XPML_read
  #     markup           : 需要在文件注释里检查的关键字。
  #     event_id         : 事件ID
  #     max_param_number : 读取参数/注释的最大值,0为事件内的所有注释
  #--------------------------------------------------------------------------  
  def XPML_read(markup, event_id, max_param_number = 0)
    parameter_list = nil
    event = $game_map.events[event_id]
    return if event.list == nil
      for i in 0...event.list.size
        if event.list.code == 108 and
          event.list.parameters[0].downcase == "begin " + markup.downcase
          parameter_list = [] if parameter_list == nil
          for j in i + 1...event.list.size
            if event.list[j].code == 108
              parts = event.list[j].parameters[0].split
              if parts.size != 1 and parts[0].downcase != "begin"
                if parts[1].to_i != 0 or parts[1] == "0"
                  parameter_list.push(parts[1].to_i)
                else
                  parameter_list.push(parts[1])
                end
              else
                return parameter_list
              end
            else
              return parameter_list
            end
            if max_param_number != 0 and j == i + max_param_number
              return parameter_list
            end
          end
        end
      end
    return parameter_list
  end
end


注意了....这个不是VX用的....
回复

使用道具 举报

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

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2025-7-20 22:17

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表