Показано с 1 по 10 из 23

Тема: Multi Layer [ACE]

Древовидный режим

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #2
    Бывалый Аватар для caveman
    Информация о пользователе
    Регистрация
    15.02.2013
    Сообщений
    766
    Записей в дневнике
    47
    Репутация: 85 Добавить или отнять репутацию

    По умолчанию

    Вот так выглядит конечная версия (мапа не претендует на конкурсы, просто за 5 минут набросал из найденных тайлсетов три слоя)
    1_6.png


    Измененный скрипт multilayer
    Спойлер код:
    Код:
    #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
    # Drago - Multi Layer
    # Version: 2.02, Caveman fix: 1.02
    # Author : LiTTleDRAgo
    #:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
    
    ($imported ||= {})[:drg_multi_layer] = 2.02
    
    core = "This script needs Drago - Core Engine ver 1.43 or above"
    rmvx = "This script not for RMVX"
    
    $imported[:drg_core_engine]         || raise(core)
    LiTTleDRAgo::XP || LiTTleDRAgo::VXA || raise(rmvx)
        
    #==============================================================================
    # ** Spriteset_Map
    #------------------------------------------------------------------------------
    #  This class brings together map screen sprites, tilemaps, etc. It's used
    # within the Scene_Map class.
    #==============================================================================
    class Spriteset_Map
      #--------------------------------------------------------------------------
      # * Public Instance Variables
      #--------------------------------------------------------------------------
      attr_sec_reader :tilemap_layer, 'Array.new'
      #--------------------------------------------------------------------------
      # * Alias Listing
      #--------------------------------------------------------------------------
      alias_method     :initialize_multi_layer_cr, :initialize
      alias_sec_method :update_multi_layer_cr,     :update
      alias_sec_method :dispose_multi_layer_cr,    :dispose
      #--------------------------------------------------------------------------
      # * New Method : create_multi_layer
      #--------------------------------------------------------------------------
      def create_multi_layer
        return if @tilemap.not.is_a?(Tilemap)
        tilemap_layer.dispose
        tilemap_layer.clear
        @layer_data = $game_map.layer_data
        $game_map.layer_data.each_with_index do |data,index|
          temp_map = Game_Map.new
          temp_map.setup($game_map.layer_subs.at(index))
          tileset = LiTTleDRAgo.cache.tileset(temp_map.tileset_name)
          tilemap_layer[index] = Tilemap.new(@viewport1)
          tilemap_layer[index].map_data = temp_map.data
          if $game_map.map_type == 'XP'
            tilemap_layer[index].tileset = tileset
            for i in 0..6
              autotile_name = LiTTleDRAgo.cache.autotile(temp_map.autotile_names[i])
              tilemap_layer[index].autotiles[i] = autotile_name
            end
            tilemap_layer[index].priorities = temp_map.priorities
          else
            load = "This script needs Drago - XP Map Loader ver 1.10 or above"
            $imported[:drg_xp_map_loader] || raise(load)
            temp_map.tileset.tileset_names.each_with_index do |name, i|
              @tilemap_layer[index].bitmaps[i] = LiTTleDRAgo.cache.tileset(name)
            end
            @tilemap_layer[index].flags = temp_map.tileset.flags
          end
        end
      end
      #--------------------------------------------------------------------------
      # * Aliased Method : update
      #--------------------------------------------------------------------------
      def update
        update_multi_layer_cr
        create_multi_layer if @layer_data != $game_map.layer_data
        tilemap_layer.ox = @tilemap.ox 
        tilemap_layer.oy = @tilemap.oy 
        tilemap_layer.update
      end
      #--------------------------------------------------------------------------
      # * Aliased Method : dispose
      #--------------------------------------------------------------------------
      def dispose
        tilemap_layer.dispose
        dispose_multi_layer_cr
      end
      #-------------------------------------------------------------------------
      # * Drago - Custom Resolution
      #-------------------------------------------------------------------------
      if $imported[:drg_custom_resolution] && LiTTleDRAgo::XP
        #-------------------------------------------------------------------------
        # * Alias Listing
        #-------------------------------------------------------------------------
        alias_sec_method :create_tilemap_ex_multi_layer,  :create_tilemap_ex
        alias_sec_method :update_new_tilemap_multi_layer, :update_tilemap_ex
        alias_sec_method :dispose_tilemap_ex_multi_layer, :dispose_tilemap_ex
        #-------------------------------------------------------------------------
        # * Aliased method: create_tilemap_ex
        #-------------------------------------------------------------------------
        def create_tilemap_ex
          create_tilemap_ex_multi_layer
          create_multi_layer_ex
        end
        #-------------------------------------------------------------------------
        # * New method: create_multi_layer_ex
        #-------------------------------------------------------------------------
        def create_multi_layer_ex
          @tilemap_layer_ex && @tilemap_layer_ex.flatten.dispose
          @tilemap_layer_ex = []
          @extra_res.each_index do |a| 
            @tilemap_layer_ex[a] ||= []
            $game_map.layer_data.each_with_index do |d,b|
              temp_map = Game_Map.new
              temp_map.setup($game_map.layer_subs.at(b))
              tileset = LiTTleDRAgo.cache.tileset(temp_map.tileset_name)
              @tilemap_layer_ex[a][b] = Tilemap.new(@viewport_ex[a])
              @tilemap_layer_ex[a][b].tileset = tileset
              for i in 0..6
                autotile = LiTTleDRAgo.cache.autotile(temp_map.autotile_names[i])
                @tilemap_layer_ex[a][b].autotiles[i] = autotile
              end
              @tilemap_layer_ex[a][b].map_data   = temp_map.data
              @tilemap_layer_ex[a][b].priorities = temp_map.priorities
            end
          end
        end
        #-------------------------------------------------------------------------
        # * Aliased method: update_new_tilemap
        #-------------------------------------------------------------------------
        def update_tilemap_ex
          update_new_tilemap_multi_layer
          @tilemap_ex && @extra_res.each_index do |a| 
            $game_map.layer_data.each_index do |b|
              if @tilemap_layer_ex && @tilemap_layer_ex[a] && 
                @tilemap_layer_ex[a][b] && @tilemap_layer_ex[a][b].not.disposed?
                @tilemap_ex[a].not.disposed?
                @tilemap_layer_ex[a][b].ox = @tilemap_ex[a].ox
                @tilemap_layer_ex[a][b].oy = @tilemap_ex[a].oy
                @tilemap_layer_ex[a][b].update
              end
            end
          end
        end
        #-------------------------------------------------------------------------
        # * Aliased method: dispose_tilemap_ex
        #-------------------------------------------------------------------------
        def dispose_tilemap_ex
          @tilemap_layer_ex && @tilemap_layer_ex.flatten.dispose
          dispose_tilemap_ex_multi_layer
        end
      end
    end
    
    #==============================================================================
    # ** Game_Map
    #------------------------------------------------------------------------------
    #  This class handles maps. It includes scrolling and passage determination
    # functions. The instance of this class is referenced by $game_map.
    #==============================================================================
    class Game_Map
      #--------------------------------------------------------------------------
      # * Public Instance Variables
      #--------------------------------------------------------------------------  
      attr_sec_accessor :layer_data, :layer_subs, 'Array.new'
      attr_reader :layer_tilesets
      attr_reader       :map_type
      #--------------------------------------------------------------------------
      # * Alias Method
      #--------------------------------------------------------------------------
      alias_sec_method :setup_multilayer, :setup
      #--------------------------------------------------------------------------
      # * Aliased Method : setup
      #--------------------------------------------------------------------------
      def setup(*args)
        setup_multilayer(*args)   
        @map_type ||= 'XP'
        @is_load = true # hot fix
        decide_map_layer(*args)          
      end
      #--------------------------------------------------------------------------
      # * Overwriten Method : decide_map_layer
      #--------------------------------------------------------------------------
      def decide_map_layer(*args)
        return if layer_subs.include?(@map_id)
        return if @is_load == nil
        @layer_data, @layer_subs = [], [] 
        @layer_tilesets = []
        
        child_ids.each do |submap_id|
          map_info = mapInfo[submap_id]
          unless map_info.nil?
            if map_info.parent_id == map_id &&
              map_info.name.include?("[" + 'join' + "]")
            then
              submap = load_map_data(submap_id, @map_type=='XP' ? :rxdata : :rvdata2)
              unless submap
                print "Map #{submap_id} doesn't exist" 
                next 
              end
              if [submap.width,submap.height] != [width,height]
                raise "Dimension of child maps must be same with parent's dimension"
              end
             # p sprintf("tileset=%d, cur_size=%d", submap.tileset_id, data.zsize)
              @layer_tilesets << submap.tileset_id
              @layer_data << data
              @layer_subs << submap_id
              old_zsize = data.zsize
              data.resize(data.xsize, data.ysize, old_zsize + 3)
              for x in 0...data.xsize
                for y in 0...data.ysize
                  if @map_type == 'XP' 
                    data[x, y, old_zsize]     = submap.data[x, y, 0]
                    data[x, y, old_zsize + 1] = submap.data[x, y, 1]
                    data[x, y, old_zsize + 2] = submap.data[x, y, 2]
                  else
                    data[x, y, old_zsize]     = submap.data[x, y, 1]
                    data[x, y, old_zsize + 1] = submap.data[x, y, 2]
                  end
                end
              end
            end
            @need_redraw = true
          end
        end
      end
    
      # for separate passability
      def check_passage(x, y, bit)
        pass = true
        # проверяем первую карту
        all_tiles1(x, y).each do |tile_id|
          flag = tileset.flags[tile_id]
          if flag & 0x10 != 0                       # [?]: No effect on passage
            if flag & bit == 0 # [0] : Passable but star
              next   
            end
            if flag & bit == bit   # [?] : Impassable
              pass = false 
              break
            end
          else
            if flag & bit == 0  # [0] : Passable
              pass = true  
              break
            end
            if flag & bit == bit   # [?] : Impassable
              pass = false 
              break
            end
          end
        end
        if pass == false                           # Impassable
          return false 
        end
        
        idx = 0
       
        @layer_tilesets.each do |tileset_n|     
          all_tiles_n(x, y, idx).each do |tile_id|
            flag = $data_tilesets[tileset_n].flags[tile_id]
            if flag & 0x10 != 0    # [?]: No effect on passage
              if flag & bit == 0 # [0] : Passable but star
                next   
              end
              if flag & bit == bit   # [?] : Impassable
                pass = false 
                break
              end
            else
              if flag & bit == 0  # [0] : Passable
                pass = true  
                break
              end
              if flag & bit == bit   # [?] : Impassable
                pass = false 
                break
              end
            end
          end
          
          if pass == false                           # Impassable
            return false 
          end
          idx = idx +1
        end
        
        return pass                                
      end
      
      def all_tiles1(x, y)
        tile_events_xy(x, y).collect {|ev| ev.tile_id } + layered_tiles1(x, y)
      end
      
      def layered_tiles1(x, y)
        _z_data = z_data.reject {|s| s >= 3 }
        _z_data.collect {|z| tile_id(x, y, z) }
      end
      
      def all_tiles_n(x, y, idx)
        tile_events_xy(x, y).collect {|ev| ev.tile_id } + layered_tiles_n(x, y, idx)
      end
      
      def layered_tiles_n(x, y, idx)
        idx1 = 3 + idx*3
        idx2 = 5 + idx*3
       # p sprintf("idx1=%d,idx2=%d",idx1,idx2)
        _z_data = z_data.reject {|s| s <= idx1 || s > idx2 }
        _z_data.collect {|z| tile_id(x, y, z) }
      end
      
      #--------------------------------------------------------------------------
      # * If RMXP
      #--------------------------------------------------------------------------
      if LiTTleDRAgo::XP
        #--------------------------------------------------------------------------
        # * Overwriten Method : passable?
        #--------------------------------------------------------------------------
        def passable?(x, y, d, s = nil)
          return false unless valid?(x, y)
          bit = (1 << (d / 2 - 1)) & 0x0f
          (event_tiles(x, y, s) + layered_tiles(x, y)).each do |tile_id|
            return false if tile_id.nil?
            if @passages[tile_id] & bit != 0
              return false
            elsif @passages[tile_id] & 0x0f == 0x0f
              return false
            elsif @priorities[tile_id] == 0
              return true
            end
          end
          return true
        end
        #--------------------------------------------------------------------------
        # * Overwriten Method : bush?
        #--------------------------------------------------------------------------
        def bush?(x, y)
          return false if @map_id == 0
            layered_tiles(x, y).each do |tile_id|
            return false if tile_id.nil?
            passage = @passages[tile_id] 
            return true if passage & 0x40 == 0x40
          end
          return false
        end
        #--------------------------------------------------------------------------
        # * Overwriten Method : counter?
        #--------------------------------------------------------------------------
        def counter?(x, y)
          return false if @map_id == 0
          layered_tiles(x, y).each do |tile_id|
            return false if tile_id.nil?
            passage = @passages[tile_id] 
            return true if passage & 0x80 == 0x80
          end
          return false
        end
        #--------------------------------------------------------------------------
        # * Overwriten Method : terrain_tag
        #--------------------------------------------------------------------------
        def terrain_tag(x, y)
          return 0 if @map_id == 0
          layered_tiles(x, y).each do |tile_id|
            return 0 if tile_id.nil?
            tag = @terrain_tags[tile_id] 
            return tag if tag > 0
          end
          return 0
        end
        #--------------------------------------------------------------------------
        # * New Method : layered_tiles
        #--------------------------------------------------------------------------
        def layered_tiles(x, y)
          z_data.collect {|z| tile_id(x, y, z) }
        end
        #--------------------------------------------------------------------------
        # * New Method : z_data
        #--------------------------------------------------------------------------
        unless method_defined?(:z_data)
          def z_data
            (0...data.zsize).to_a.reverse
          end
        end
        #--------------------------------------------------------------------------
        # * New Method : event_tiles
        #--------------------------------------------------------------------------
        def event_tiles(x, y, s=nil)
          return [] unless self.respond_to?(:events_xy_nt)
          e = events_xy_nt(x,y).select {|e| e.tile_id >= 0 && e != s }
          e.collect {|event| event.tile_id }
        end
        #--------------------------------------------------------------------------
        # * New Method : tile_id
        #--------------------------------------------------------------------------
        unless method_defined?(:tile_id)
          def tile_id(x, y, z)
            data[x, y, z]
          end
        end
      end
    end


    И, наконец, демка, где собраны все скрипты и есть пример карты.
    http://yadi.sk/d/nIIVTTqrK2V2U


    Резюмируя все вышесказанное,
    - теперь XP уходит на задний план, он со своими тремя слоями и километровыми тайлсетами уже не так крут.
    - обычный маппинг и событийный маппинг в асе туда же
    - за параллакс, конечно, будут люди... которым не лень маппить все в фотошопах и проставлять каждый раз ручками проходимости - но это не я

    Спасибо LittleDrago и Kian Ni за помощь в создании этого способа и статьи.
    Последний раз редактировалось caveman; 07.07.2014 в 22:08. Причина: фикс
    back to the primitive

    http://cavemangame.blogspot.ru/ - разные идеи и новости
    http://cavescripts.blogspot.ru/ - мои скрипты
    http://cavecrusader.blogspot.ru/ - текущий проект

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 2 (пользователей: 0 , гостей: 2)

Социальные закладки

Социальные закладки

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •  
Multi Layer [ACE]